From 7f47ae425954a1ae1ef50a10751293e8a4d36e89 Mon Sep 17 00:00:00 2001 From: bmy <2583236812@qq.com> Date: Mon, 10 Jun 2024 18:04:45 +0800 Subject: [PATCH] initial commit --- .clang-format | 38 + .eide/bc2d.arm.options.gcc.json | 29 + .eide/bc2d.arm.options.v5.json | 24 + .eide/bc2d.files.options.yml | 31 + .eide/bc5d-pos.arm.options.gcc.json | 29 + .eide/bc5d-pos.files.options.yml | 31 + .eide/bc5d.arm.options.gcc.json | 25 + .eide/bc5d.files.options.yml | 31 + .eide/eide.json | 86 + .gitignore | 15 + .vscode/settings.json | 8 + .vscode/tasks.json | 40 + 3rd-part/PID-Library/LICENSE | 21 + 3rd-part/PID-Library/README.md | 164 + 3rd-part/PID-Library/pid.c | 293 + 3rd-part/PID-Library/pid.h | 170 + 3rd-part/lwprintf/.gitignore | 400 + 3rd-part/lwprintf/AUTHORS | 6 + 3rd-part/lwprintf/CHANGELOG.md | 41 + 3rd-part/lwprintf/LICENSE | 21 + 3rd-part/lwprintf/README.md | 29 + 3rd-part/lwprintf/lwprintf.c | 1274 +++ 3rd-part/lwprintf/lwprintf.h | 313 + 3rd-part/lwprintf/lwprintf_opt.h | 191 + 3rd-part/lwprintf/lwprintf_opts.h | 44 + BC5D-POS.ATWP | 151 + BC5D-POS.code-workspace | 38 + app/by_can.c | 39 + app/by_can.h | 9 + app/by_motion.c | 261 + app/by_motion.h | 36 + app/by_utils.c | 7 + app/by_utils.h | 23 + .../cm4/core_support/arm_common_tables.h | 517 + .../cm4/core_support/arm_const_structs.h | 76 + .../cmsis/cm4/core_support/arm_helium_utils.h | 348 + libraries/cmsis/cm4/core_support/arm_math.h | 8970 +++++++++++++++++ .../cmsis/cm4/core_support/arm_mve_tables.h | 235 + .../cmsis/cm4/core_support/arm_vec_math.h | 372 + .../cmsis/cm4/core_support/cmsis_armcc.h | 885 ++ .../cmsis/cm4/core_support/cmsis_armclang.h | 1467 +++ .../cm4/core_support/cmsis_armclang_ltm.h | 1893 ++++ .../cmsis/cm4/core_support/cmsis_compiler.h | 283 + libraries/cmsis/cm4/core_support/cmsis_gcc.h | 2177 ++++ .../cmsis/cm4/core_support/cmsis_iccarm.h | 968 ++ .../cmsis/cm4/core_support/cmsis_version.h | 39 + libraries/cmsis/cm4/core_support/core_cm4.h | 2129 ++++ libraries/cmsis/cm4/core_support/mpu_armv7.h | 275 + libraries/cmsis/cm4/core_support/mpu_armv8.h | 352 + libraries/cmsis/cm4/core_support/pmu_armv8.h | 337 + libraries/cmsis/cm4/device_support/at32f425.h | 393 + .../device_support/at32f425_conf_template.h | 147 + .../startup/gcc/linker/AT32F425x4_FLASH.ld | 153 + .../startup/gcc/linker/AT32F425x6_FLASH.ld | 153 + .../startup/gcc/linker/AT32F425x8_FLASH.ld | 153 + .../startup/gcc/startup_at32f425.s | 309 + .../startup/iar/linker/AT32F425x4.icf | 30 + .../startup/iar/linker/AT32F425x6.icf | 30 + .../startup/iar/linker/AT32F425x8.icf | 30 + .../startup/iar/startup_at32f425.s | 320 + .../startup/mdk/startup_at32f425.s | 261 + .../cm4/device_support/system_at32f425.c | 215 + .../cm4/device_support/system_at32f425.h | 85 + libraries/drivers/inc/at32f425_acc.h | 201 + libraries/drivers/inc/at32f425_adc.h | 658 ++ libraries/drivers/inc/at32f425_can.h | 984 ++ libraries/drivers/inc/at32f425_crc.h | 198 + libraries/drivers/inc/at32f425_crm.h | 912 ++ libraries/drivers/inc/at32f425_debug.h | 182 + libraries/drivers/inc/at32f425_def.h | 69 + libraries/drivers/inc/at32f425_dma.h | 481 + libraries/drivers/inc/at32f425_ertc.h | 943 ++ libraries/drivers/inc/at32f425_exint.h | 232 + libraries/drivers/inc/at32f425_flash.h | 577 ++ libraries/drivers/inc/at32f425_gpio.h | 553 + libraries/drivers/inc/at32f425_i2c.h | 477 + libraries/drivers/inc/at32f425_misc.h | 123 + libraries/drivers/inc/at32f425_pwc.h | 218 + libraries/drivers/inc/at32f425_scfg.h | 292 + libraries/drivers/inc/at32f425_spi.h | 504 + libraries/drivers/inc/at32f425_tmr.h | 962 ++ libraries/drivers/inc/at32f425_usart.h | 408 + libraries/drivers/inc/at32f425_usb.h | 1421 +++ libraries/drivers/inc/at32f425_wdt.h | 195 + libraries/drivers/inc/at32f425_wwdt.h | 157 + libraries/drivers/src/at32f425_acc.c | 232 + libraries/drivers/src/at32f425_adc.c | 909 ++ libraries/drivers/src/at32f425_can.c | 1234 +++ libraries/drivers/src/at32f425_crc.c | 208 + libraries/drivers/src/at32f425_crm.c | 987 ++ libraries/drivers/src/at32f425_debug.c | 102 + libraries/drivers/src/at32f425_dma.c | 375 + libraries/drivers/src/at32f425_ertc.c | 1418 +++ libraries/drivers/src/at32f425_exint.c | 254 + libraries/drivers/src/at32f425_flash.c | 830 ++ libraries/drivers/src/at32f425_gpio.c | 498 + libraries/drivers/src/at32f425_i2c.c | 812 ++ libraries/drivers/src/at32f425_misc.c | 171 + libraries/drivers/src/at32f425_pwc.c | 269 + libraries/drivers/src/at32f425_scfg.c | 228 + libraries/drivers/src/at32f425_spi.c | 715 ++ libraries/drivers/src/at32f425_tmr.c | 1758 ++++ libraries/drivers/src/at32f425_usart.c | 780 ++ libraries/drivers/src/at32f425_usb.c | 1087 ++ libraries/drivers/src/at32f425_wdt.c | 154 + libraries/drivers/src/at32f425_wwdt.c | 149 + project/MDK_V5/BC5D.uvoptx | 493 + project/MDK_V5/BC5D.uvprojx | 481 + project/MDK_V5/startup_at32f425.s | 261 + project/inc/at32f425_conf.h | 147 + project/inc/at32f425_int.h | 79 + project/inc/at32f425_wk_config.h | 100 + project/inc/by_debug.h | 35 + project/src/at32f425_int.c | 264 + project/src/at32f425_wk_config.c | 746 ++ project/src/by_debug.c | 98 + project/src/main.c | 124 + 117 files changed, 54265 insertions(+) create mode 100644 .clang-format create mode 100644 .eide/bc2d.arm.options.gcc.json create mode 100644 .eide/bc2d.arm.options.v5.json create mode 100644 .eide/bc2d.files.options.yml create mode 100644 .eide/bc5d-pos.arm.options.gcc.json create mode 100644 .eide/bc5d-pos.files.options.yml create mode 100644 .eide/bc5d.arm.options.gcc.json create mode 100644 .eide/bc5d.files.options.yml create mode 100644 .eide/eide.json create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 3rd-part/PID-Library/LICENSE create mode 100644 3rd-part/PID-Library/README.md create mode 100644 3rd-part/PID-Library/pid.c create mode 100644 3rd-part/PID-Library/pid.h create mode 100644 3rd-part/lwprintf/.gitignore create mode 100644 3rd-part/lwprintf/AUTHORS create mode 100644 3rd-part/lwprintf/CHANGELOG.md create mode 100644 3rd-part/lwprintf/LICENSE create mode 100644 3rd-part/lwprintf/README.md create mode 100644 3rd-part/lwprintf/lwprintf.c create mode 100644 3rd-part/lwprintf/lwprintf.h create mode 100644 3rd-part/lwprintf/lwprintf_opt.h create mode 100644 3rd-part/lwprintf/lwprintf_opts.h create mode 100644 BC5D-POS.ATWP create mode 100644 BC5D-POS.code-workspace create mode 100644 app/by_can.c create mode 100644 app/by_can.h create mode 100644 app/by_motion.c create mode 100644 app/by_motion.h create mode 100644 app/by_utils.c create mode 100644 app/by_utils.h create mode 100644 libraries/cmsis/cm4/core_support/arm_common_tables.h create mode 100644 libraries/cmsis/cm4/core_support/arm_const_structs.h create mode 100644 libraries/cmsis/cm4/core_support/arm_helium_utils.h create mode 100644 libraries/cmsis/cm4/core_support/arm_math.h create mode 100644 libraries/cmsis/cm4/core_support/arm_mve_tables.h create mode 100644 libraries/cmsis/cm4/core_support/arm_vec_math.h create mode 100644 libraries/cmsis/cm4/core_support/cmsis_armcc.h create mode 100644 libraries/cmsis/cm4/core_support/cmsis_armclang.h create mode 100644 libraries/cmsis/cm4/core_support/cmsis_armclang_ltm.h create mode 100644 libraries/cmsis/cm4/core_support/cmsis_compiler.h create mode 100644 libraries/cmsis/cm4/core_support/cmsis_gcc.h create mode 100644 libraries/cmsis/cm4/core_support/cmsis_iccarm.h create mode 100644 libraries/cmsis/cm4/core_support/cmsis_version.h create mode 100644 libraries/cmsis/cm4/core_support/core_cm4.h create mode 100644 libraries/cmsis/cm4/core_support/mpu_armv7.h create mode 100644 libraries/cmsis/cm4/core_support/mpu_armv8.h create mode 100644 libraries/cmsis/cm4/core_support/pmu_armv8.h create mode 100644 libraries/cmsis/cm4/device_support/at32f425.h create mode 100644 libraries/cmsis/cm4/device_support/at32f425_conf_template.h create mode 100644 libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x4_FLASH.ld create mode 100644 libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x6_FLASH.ld create mode 100644 libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld create mode 100644 libraries/cmsis/cm4/device_support/startup/gcc/startup_at32f425.s create mode 100644 libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x4.icf create mode 100644 libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x6.icf create mode 100644 libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x8.icf create mode 100644 libraries/cmsis/cm4/device_support/startup/iar/startup_at32f425.s create mode 100644 libraries/cmsis/cm4/device_support/startup/mdk/startup_at32f425.s create mode 100644 libraries/cmsis/cm4/device_support/system_at32f425.c create mode 100644 libraries/cmsis/cm4/device_support/system_at32f425.h create mode 100644 libraries/drivers/inc/at32f425_acc.h create mode 100644 libraries/drivers/inc/at32f425_adc.h create mode 100644 libraries/drivers/inc/at32f425_can.h create mode 100644 libraries/drivers/inc/at32f425_crc.h create mode 100644 libraries/drivers/inc/at32f425_crm.h create mode 100644 libraries/drivers/inc/at32f425_debug.h create mode 100644 libraries/drivers/inc/at32f425_def.h create mode 100644 libraries/drivers/inc/at32f425_dma.h create mode 100644 libraries/drivers/inc/at32f425_ertc.h create mode 100644 libraries/drivers/inc/at32f425_exint.h create mode 100644 libraries/drivers/inc/at32f425_flash.h create mode 100644 libraries/drivers/inc/at32f425_gpio.h create mode 100644 libraries/drivers/inc/at32f425_i2c.h create mode 100644 libraries/drivers/inc/at32f425_misc.h create mode 100644 libraries/drivers/inc/at32f425_pwc.h create mode 100644 libraries/drivers/inc/at32f425_scfg.h create mode 100644 libraries/drivers/inc/at32f425_spi.h create mode 100644 libraries/drivers/inc/at32f425_tmr.h create mode 100644 libraries/drivers/inc/at32f425_usart.h create mode 100644 libraries/drivers/inc/at32f425_usb.h create mode 100644 libraries/drivers/inc/at32f425_wdt.h create mode 100644 libraries/drivers/inc/at32f425_wwdt.h create mode 100644 libraries/drivers/src/at32f425_acc.c create mode 100644 libraries/drivers/src/at32f425_adc.c create mode 100644 libraries/drivers/src/at32f425_can.c create mode 100644 libraries/drivers/src/at32f425_crc.c create mode 100644 libraries/drivers/src/at32f425_crm.c create mode 100644 libraries/drivers/src/at32f425_debug.c create mode 100644 libraries/drivers/src/at32f425_dma.c create mode 100644 libraries/drivers/src/at32f425_ertc.c create mode 100644 libraries/drivers/src/at32f425_exint.c create mode 100644 libraries/drivers/src/at32f425_flash.c create mode 100644 libraries/drivers/src/at32f425_gpio.c create mode 100644 libraries/drivers/src/at32f425_i2c.c create mode 100644 libraries/drivers/src/at32f425_misc.c create mode 100644 libraries/drivers/src/at32f425_pwc.c create mode 100644 libraries/drivers/src/at32f425_scfg.c create mode 100644 libraries/drivers/src/at32f425_spi.c create mode 100644 libraries/drivers/src/at32f425_tmr.c create mode 100644 libraries/drivers/src/at32f425_usart.c create mode 100644 libraries/drivers/src/at32f425_usb.c create mode 100644 libraries/drivers/src/at32f425_wdt.c create mode 100644 libraries/drivers/src/at32f425_wwdt.c create mode 100644 project/MDK_V5/BC5D.uvoptx create mode 100644 project/MDK_V5/BC5D.uvprojx create mode 100644 project/MDK_V5/startup_at32f425.s create mode 100644 project/inc/at32f425_conf.h create mode 100644 project/inc/at32f425_int.h create mode 100644 project/inc/at32f425_wk_config.h create mode 100644 project/inc/by_debug.h create mode 100644 project/src/at32f425_int.c create mode 100644 project/src/at32f425_wk_config.c create mode 100644 project/src/by_debug.c create mode 100644 project/src/main.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..408ff24 --- /dev/null +++ b/.clang-format @@ -0,0 +1,38 @@ +--- +BasedOnStyle: Microsoft +Language: Cpp + +################################### +# indent conf +################################### + +UseTab: Never +IndentWidth: 2 +TabWidth: 2 +ColumnLimit: 0 +AccessModifierOffset: -4 +NamespaceIndentation: All +FixNamespaceComments: false +BreakBeforeBraces: Linux + +################################### +# other styles +################################### + +# +# for more conf, you can ref: https://clang.llvm.org/docs/ClangFormatStyleOptions.html +# + +AllowShortIfStatementsOnASingleLine: true + +AllowShortLoopsOnASingleLine: true + +AllowShortBlocksOnASingleLine: true + +IndentCaseLabels: true + +SortIncludes: false + +AlignConsecutiveMacros: AcrossEmptyLines + +AlignConsecutiveAssignments: Consecutive diff --git a/.eide/bc2d.arm.options.gcc.json b/.eide/bc2d.arm.options.gcc.json new file mode 100644 index 0000000..961a577 --- /dev/null +++ b/.eide/bc2d.arm.options.gcc.json @@ -0,0 +1,29 @@ +{ + "version": 5, + "beforeBuildTasks": [], + "afterBuildTasks": [], + "global": { + "$float-abi-type": "softfp", + "output-debug-info": "enable", + "misc-control": "--specs=nosys.specs --specs=nano.specs" + }, + "c/cpp-compiler": { + "language-c": "c11", + "language-cpp": "c++11", + "optimization": "level-debug", + "warnings": "all-warnings", + "one-elf-section-per-function": true, + "one-elf-section-per-data": true, + "C_FLAGS": "", + "CXX_FLAGS": "" + }, + "asm-compiler": { + "ASM_FLAGS": "" + }, + "linker": { + "output-format": "elf", + "remove-unused-input-sections": true, + "LD_FLAGS": "", + "LIB_FLAGS": "-lm" + } +} \ No newline at end of file diff --git a/.eide/bc2d.arm.options.v5.json b/.eide/bc2d.arm.options.v5.json new file mode 100644 index 0000000..1e7f380 --- /dev/null +++ b/.eide/bc2d.arm.options.v5.json @@ -0,0 +1,24 @@ +{ + "version": 4, + "beforeBuildTasks": [], + "afterBuildTasks": [], + "global": { + "use-microLIB": true, + "output-debug-info": "enable" + }, + "c/cpp-compiler": { + "optimization": "level-0", + "one-elf-section-per-function": true, + "c99-mode": true, + "C_FLAGS": "--diag_suppress=1 --diag_suppress=1295", + "CXX_FLAGS": "--diag_suppress=1 --diag_suppress=1295", + "warnings": "all-warnings" + }, + "asm-compiler": {}, + "linker": { + "output-format": "elf", + "xo-base": "", + "ro-base": "0x08000000", + "rw-base": "0x20000000" + } +} \ No newline at end of file diff --git a/.eide/bc2d.files.options.yml b/.eide/bc2d.files.options.yml new file mode 100644 index 0000000..2486c4f --- /dev/null +++ b/.eide/bc2d.files.options.yml @@ -0,0 +1,31 @@ +########################################################################################## +# Append Compiler Options For Source Files +# +# syntax: +# : +# +# examples: +# 'main.cpp': --cpp11 -Og ... +# 'src/*.c': -gnu -O2 ... +# 'src/lib/**/*.cpp': --cpp11 -Os ... +# '!Application/*.c': -O0 +# '**/*.c': -O2 -gnu ... +# +# For more syntax, please refer to: https://www.npmjs.com/package/micromatch +# +########################################################################################## + +version: '1.0' + +# +# for source files with filesystem paths +# +files: +# './test/**/*.c': --c99 + +# +# for source files with virtual paths +# +virtualPathFiles: +# 'virtual_folder/**/*.c': --c99 + diff --git a/.eide/bc5d-pos.arm.options.gcc.json b/.eide/bc5d-pos.arm.options.gcc.json new file mode 100644 index 0000000..961a577 --- /dev/null +++ b/.eide/bc5d-pos.arm.options.gcc.json @@ -0,0 +1,29 @@ +{ + "version": 5, + "beforeBuildTasks": [], + "afterBuildTasks": [], + "global": { + "$float-abi-type": "softfp", + "output-debug-info": "enable", + "misc-control": "--specs=nosys.specs --specs=nano.specs" + }, + "c/cpp-compiler": { + "language-c": "c11", + "language-cpp": "c++11", + "optimization": "level-debug", + "warnings": "all-warnings", + "one-elf-section-per-function": true, + "one-elf-section-per-data": true, + "C_FLAGS": "", + "CXX_FLAGS": "" + }, + "asm-compiler": { + "ASM_FLAGS": "" + }, + "linker": { + "output-format": "elf", + "remove-unused-input-sections": true, + "LD_FLAGS": "", + "LIB_FLAGS": "-lm" + } +} \ No newline at end of file diff --git a/.eide/bc5d-pos.files.options.yml b/.eide/bc5d-pos.files.options.yml new file mode 100644 index 0000000..2486c4f --- /dev/null +++ b/.eide/bc5d-pos.files.options.yml @@ -0,0 +1,31 @@ +########################################################################################## +# Append Compiler Options For Source Files +# +# syntax: +# : +# +# examples: +# 'main.cpp': --cpp11 -Og ... +# 'src/*.c': -gnu -O2 ... +# 'src/lib/**/*.cpp': --cpp11 -Os ... +# '!Application/*.c': -O0 +# '**/*.c': -O2 -gnu ... +# +# For more syntax, please refer to: https://www.npmjs.com/package/micromatch +# +########################################################################################## + +version: '1.0' + +# +# for source files with filesystem paths +# +files: +# './test/**/*.c': --c99 + +# +# for source files with virtual paths +# +virtualPathFiles: +# 'virtual_folder/**/*.c': --c99 + diff --git a/.eide/bc5d.arm.options.gcc.json b/.eide/bc5d.arm.options.gcc.json new file mode 100644 index 0000000..2843030 --- /dev/null +++ b/.eide/bc5d.arm.options.gcc.json @@ -0,0 +1,25 @@ +{ + "version": 5, + "beforeBuildTasks": [], + "afterBuildTasks": [], + "global": { + "$float-abi-type": "softfp", + "output-debug-info": "enable", + "misc-control": "--specs=nosys.specs --specs=nano.specs" + }, + "c/cpp-compiler": { + "language-c": "c11", + "language-cpp": "c++11", + "optimization": "level-debug", + "warnings": "all-warnings", + "one-elf-section-per-function": true, + "one-elf-section-per-data": true + }, + "asm-compiler": {}, + "linker": { + "output-format": "elf", + "remove-unused-input-sections": true, + "LIB_FLAGS": "-lm", + "$toolName": "auto" + } +} \ No newline at end of file diff --git a/.eide/bc5d.files.options.yml b/.eide/bc5d.files.options.yml new file mode 100644 index 0000000..2486c4f --- /dev/null +++ b/.eide/bc5d.files.options.yml @@ -0,0 +1,31 @@ +########################################################################################## +# Append Compiler Options For Source Files +# +# syntax: +# : +# +# examples: +# 'main.cpp': --cpp11 -Og ... +# 'src/*.c': -gnu -O2 ... +# 'src/lib/**/*.cpp': --cpp11 -Os ... +# '!Application/*.c': -O0 +# '**/*.c': -O2 -gnu ... +# +# For more syntax, please refer to: https://www.npmjs.com/package/micromatch +# +########################################################################################## + +version: '1.0' + +# +# for source files with filesystem paths +# +files: +# './test/**/*.c': --c99 + +# +# for source files with virtual paths +# +virtualPathFiles: +# 'virtual_folder/**/*.c': --c99 + diff --git a/.eide/eide.json b/.eide/eide.json new file mode 100644 index 0000000..454fe08 --- /dev/null +++ b/.eide/eide.json @@ -0,0 +1,86 @@ +{ + "name": "BC5D-POS", + "type": "ARM", + "dependenceList": [], + "srcDirs": [ + ".eide/deps", + "3rd-part", + "libraries/cmsis", + "libraries/drivers", + "project", + "app" + ], + "virtualFolder": { + "name": "", + "files": [], + "folders": [] + }, + "outDir": "build", + "deviceName": null, + "packDir": null, + "miscInfo": { + "uid": "9d909db3024271625a98879e53e2d396" + }, + "targets": { + "BC5D-POS": { + "excludeList": [ + "project/MDK_V5/startup_at32f425.s", + "libraries/cmsis/cm4/device_support/startup/iar", + "libraries/cmsis/cm4/device_support/startup/mdk" + ], + "toolchain": "GCC", + "compileConfig": { + "cpuType": "Cortex-M4", + "floatingPointHardware": "none", + "scatterFilePath": "${workspaceFolder}\\libraries\\cmsis\\cm4\\device_support\\startup\\gcc\\linker\\AT32F425x8_FLASH.ld", + "useCustomScatterFile": true, + "storageLayout": { + "RAM": [], + "ROM": [] + }, + "options": "null" + }, + "uploader": "OpenOCD", + "uploadConfig": { + "bin": "", + "target": "at32f425xx", + "interface": "cmsis-dap", + "baseAddr": "0x08000000" + }, + "uploadConfigMap": { + "JLink": { + "bin": "", + "baseAddr": "", + "cpuInfo": { + "vendor": "null", + "cpuName": "null" + }, + "proType": 1, + "speed": 8000, + "otherCmds": "" + } + }, + "custom_dep": { + "name": "default", + "incList": [ + "libraries/drivers/inc", + "libraries/cmsis/cm4/core_support", + "libraries/cmsis/cm4/device_support", + "project/inc", + ".cmsis/include", + ".eide/deps", + "3rd-part/PID-Library", + "app", + "3rd-part/lwprintf" + ], + "libList": [], + "sourceDirList": [], + "defineList": [ + "USE_STDPERIPH_DRIVER", + "AT32F425C8T7" + ] + } + } + }, + "version": "3.3" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2f4ce9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# dot files +/.vscode/launch.json +/.settings +/.eide/log +/.eide.usr.ctx.json + +# project out +/build +/bin +/obj +/out + +# eide template +*.ept +*.eide-template diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..61e0b1d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "sonarlint.pathToCompileCommands": "${workspaceFolder}\\build\\BC5D-POS\\compile_commands.json", + "workbench.colorCustomizations": { + "activityBar.background": "#4B2304", + "titleBar.activeBackground": "#693006", + "titleBar.activeForeground": "#FFFBF8" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..3e192b9 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,40 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "command": "${command:eide.project.build}", + "group": "build", + "problemMatcher": [] + }, + { + "label": "flash", + "type": "shell", + "command": "${command:eide.project.uploadToDevice}", + "group": "build", + "problemMatcher": [] + }, + { + "label": "build and flash", + "type": "shell", + "command": "${command:eide.project.buildAndFlash}", + "group": "build", + "problemMatcher": [] + }, + { + "label": "rebuild", + "type": "shell", + "command": "${command:eide.project.rebuild}", + "group": "build", + "problemMatcher": [] + }, + { + "label": "clean", + "type": "shell", + "command": "${command:eide.project.clean}", + "group": "build", + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/3rd-part/PID-Library/LICENSE b/3rd-part/PID-Library/LICENSE new file mode 100644 index 0000000..7515c7e --- /dev/null +++ b/3rd-part/PID-Library/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Majid Derhambakhsh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/3rd-part/PID-Library/README.md b/3rd-part/PID-Library/README.md new file mode 100644 index 0000000..317c992 --- /dev/null +++ b/3rd-part/PID-Library/README.md @@ -0,0 +1,164 @@ +![Banner](Banner.png) + +# PID-Library (C Version) +PID Controller library for ARM Cortex M (STM32) + +> #### Download Arduino Library : [Arduino-PID-Library](https://github.com/br3ttb/Arduino-PID-Library) + +## Release +- #### Version : 1.0.0 + +- #### Type : Embedded Software. + +- #### Support : + - ARM STM32 series + +- #### Program Language : C/C++ + +- #### Properties : + +- #### Changes : + +- #### Required Library/Driver : + + +## Overview +### Initialization and de-initialization functions: +```c++ +void PID(PID_TypeDef *uPID, float *Input, float *Output, float *Setpoint, float Kp, float Ki, float Kd, PIDPON_TypeDef POn, PIDCD_TypeDef ControllerDirection); +void PID2(PID_TypeDef *uPID, float *Input, float *Output, float *Setpoint, float Kp, float Ki, float Kd, PIDCD_TypeDef ControllerDirection); +``` + +### Operation functions: +```c++ +/* ::::::::::: Computing ::::::::::: */ +uint8_t PID_Compute(PID_TypeDef *uPID); + +/* ::::::::::: PID Mode :::::::::::: */ +void PID_SetMode(PID_TypeDef *uPID, PIDMode_TypeDef Mode); +PIDMode_TypeDef PID_GetMode(PID_TypeDef *uPID); + +/* :::::::::: PID Limits ::::::::::: */ +void PID_SetOutputLimits(PID_TypeDef *uPID, float Min, float Max); + +/* :::::::::: PID Tunings :::::::::: */ +void PID_SetTunings(PID_TypeDef *uPID, float Kp, float Ki, float Kd); +void PID_SetTunings2(PID_TypeDef *uPID, float Kp, float Ki, float Kd, PIDPON_TypeDef POn); + +/* ::::::::: PID Direction ::::::::: */ +void PID_SetControllerDirection(PID_TypeDef *uPID, PIDCD_TypeDef Direction); +PIDCD_TypeDef PID_GetDirection(PID_TypeDef *uPID); + +/* ::::::::: PID Sampling :::::::::: */ +void PID_SetSampleTime(PID_TypeDef *uPID, int32_t NewSampleTime); + +/* ::::::: Get Tunings Param ::::::: */ +float PID_GetKp(PID_TypeDef *uPID); +float PID_GetKi(PID_TypeDef *uPID); +float PID_GetKd(PID_TypeDef *uPID); +``` + +### Macros: +```diff +non +``` + +## Guide + +#### This library can be used as follows: +#### 1. Add pid.h header +#### 2. Create PID struct and initialize it, for example: +* Initializer: + ```c++ + PID(PID_TypeDef *uPID, float *Input, float *Output, float *Setpoint, float Kp, float Ki, float Kd, PIDPON_TypeDef POn, PIDCD_TypeDef ControllerDirection); + ``` +* Parameters: + * uPID : Pointer to pid struct + * Input : The variable we're trying to control (float) + * Output : The variable that will be adjusted by the pid (float) + * Setpoint : The value we want to Input to maintain (float) + * Kp,Ki,Kd : Tuning Parameters. these affect how the pid will change the output (float>=0) + * POn : Either P_ON_E (Default) or P_ON_M. Allows Proportional on Measurement to be specified. + * ControllerDirection : Either DIRECT or REVERSE. determines which direction the output will move when faced with a given error. DIRECT is most common + + +* Example: + ```c++ + PID_TypeDef TPID; + + float Temp, PIDOut, TempSetpoint; + + PID(&TPID, &Temp, &PIDOut, &TempSetpoint, 2, 5, 1, _PID_P_ON_E, _PID_CD_DIRECT); + ``` +#### 3. Set 'mode', 'sample time' and 'output limit', for example: +* Functions: + ```c++ + void PID_SetMode(PID_TypeDef *uPID, PIDMode_TypeDef Mode); + void PID_SetOutputLimits(PID_TypeDef *uPID, float Min, float Max); + void PID_SetSampleTime(PID_TypeDef *uPID, int32_t NewSampleTime); + ``` +* Parameters: + * uPID : Pointer to pid struct + * Mode : _PID_MODE_AUTOMATIC or _PID_MODE_MANUAL + * Min : Low end of the range. must be < max (float) + * Max : High end of the range. must be > min (float) + * NewSampleTime : How often, in milliseconds, the PID will be evaluated. (int>0) + +* Example: + ```c++ + PID_SetMode(&TPID, _PID_MODE_AUTOMATIC); + PID_SetSampleTime(&TPID, 500); + PID_SetOutputLimits(&TPID, 1, 100); + ``` + +#### 4. Using Compute function, for example: + +```c++ +PID_Compute(&TPID); +``` + +## Examples + +#### Example 1: PID Compute for temperature +```c++ +#include "main.h" +#include "pid.h" + +PID_TypeDef TPID; + +char OutBuf[50]; +float Temp, PIDOut, TempSetpoint; + +int main(void) +{ + + HW_Init(); + + PID(&TPID, &Temp, &PIDOut, &TempSetpoint, 2, 5, 1, _PID_P_ON_E, _PID_CD_DIRECT); + + PID_SetMode(&TPID, _PID_MODE_AUTOMATIC); + PID_SetSampleTime(&TPID, 500); + PID_SetOutputLimits(&TPID, 1, 100); + + while (1) + { + + Temp = GetTemp(); + PID_Compute(&TPID); + + sprintf(OutBuf, "Temp%3.2f : %u\n", Temp, (uint16_t)PIDOut); + UART_Transmit((uint8_t *)OutBuf, strlen(OutBuf)); + + Delay_ms(500); + + } +} + +``` + +## Tests performed: +- [x] Run on STM32 Fx cores + +## Developers: +- ### Majid Derhambakhsh + diff --git a/3rd-part/PID-Library/pid.c b/3rd-part/PID-Library/pid.c new file mode 100644 index 0000000..1eda413 --- /dev/null +++ b/3rd-part/PID-Library/pid.c @@ -0,0 +1,293 @@ + /* +------------------------------------------------------------------------------ +~ File : pid.c +~ Author : Majid Derhambakhsh +~ Version: V1.0.0 +~ Created: 02/11/2021 03:43:00 AM +~ Brief : +~ Support: + E-Mail : Majid.do16@gmail.com (subject : Embedded Library Support) + + Github : https://github.com/Majid-Derhambakhsh +------------------------------------------------------------------------------ +~ Description: + +~ Attention : + +~ Changes : +------------------------------------------------------------------------------ +*/ + +#include "pid.h" + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~ Initialize ~~~~~~~~~~~~~~~~ */ +void PID_Init(PID_TypeDef *uPID) +{ + /* ~~~~~~~~~~ Set parameter ~~~~~~~~~~ */ + uPID->OutputSum = *uPID->MyOutput; + uPID->LastInput = *uPID->MyInput; + + if (uPID->OutputSum > uPID->OutMax) + { + uPID->OutputSum = uPID->OutMax; + } + else if (uPID->OutputSum < uPID->OutMin) + { + uPID->OutputSum = uPID->OutMin; + } + else { } + +} + +void PID(PID_TypeDef *uPID, const float *Input, float *Output, const float *Setpoint, float Kp, float Ki, float Kd, PIDPON_TypeDef POn, PIDCD_TypeDef ControllerDirection) +{ + /* ~~~~~~~~~~ Set parameter ~~~~~~~~~~ */ + uPID->MyOutput = Output; + uPID->MyInput = Input; + uPID->MySetpoint = Setpoint; + uPID->InAuto = (PIDMode_TypeDef)_FALSE; + + PID_SetOutputLimits(uPID, 0, _PID_8BIT_PWM_MAX); + + uPID->SampleTime = _PID_SAMPLE_TIME_MS_DEF; /* default Controller Sample Time is 0.1 seconds */ + + PID_SetControllerDirection(uPID, ControllerDirection); + PID_SetTunings2(uPID, Kp, Ki, Kd, POn); + +} + +void PID2(PID_TypeDef *uPID, const float *Input, float *Output, const float *Setpoint, float Kp, float Ki, float Kd, PIDCD_TypeDef ControllerDirection) +{ + PID(uPID, Input, Output, Setpoint, Kp, Ki, Kd, _PID_P_ON_E, ControllerDirection); +} + +/* ~~~~~~~~~~~~~~~~~ Computing ~~~~~~~~~~~~~~~~~ */ +uint8_t PID_Compute(PID_TypeDef *uPID) +{ + + float input; + float error; + float dInput; + float output; + + /* ~~~~~~~~~~ Check PID mode ~~~~~~~~~~ */ + if (!uPID->InAuto) + { + return _FALSE; + } + + + /* ..... Compute all the working error variables ..... */ + input = *uPID->MyInput; + error = *uPID->MySetpoint - input; + dInput = (input - uPID->LastInput); + + uPID->OutputSum += (uPID->Ki * error); + + /* ..... Add Proportional on Measurement, if P_ON_M is specified ..... */ + if (!uPID->POnE) + { + uPID->OutputSum -= uPID->Kp * dInput; + } + + if (uPID->OutputSum > uPID->OutMax) + { + uPID->OutputSum = uPID->OutMax; + } + else if (uPID->OutputSum < uPID->OutMin) + { + uPID->OutputSum = uPID->OutMin; + } + else { } + + /* ..... Add Proportional on Error, if P_ON_E is specified ..... */ + if (uPID->POnE) + { + output = uPID->Kp * error; + } + else + { + output = 0; + } + + /* ..... Compute Rest of PID Output ..... */ + output += uPID->OutputSum - uPID->Kd * dInput; + + if (output > uPID->OutMax) + { + output = uPID->OutMax; + } + else if (output < uPID->OutMin) + { + output = uPID->OutMin; + } + else { } + + *uPID->MyOutput = output; + + /* ..... Remember some variables for next time ..... */ + uPID->LastInput = input; + + return _TRUE; +} + +/* ~~~~~~~~~~~~~~~~~ PID Mode ~~~~~~~~~~~~~~~~~~ */ +void PID_SetMode(PID_TypeDef *uPID, PIDMode_TypeDef Mode) +{ + + uint8_t newAuto = (Mode == _PID_MODE_AUTOMATIC); + + /* ~~~~~~~~~~ Initialize the PID ~~~~~~~~~~ */ + if (newAuto && !uPID->InAuto) + { + PID_Init(uPID); + } + + uPID->InAuto = (PIDMode_TypeDef)newAuto; + +} +PIDMode_TypeDef PID_GetMode(PID_TypeDef *uPID) +{ + return uPID->InAuto ? _PID_MODE_AUTOMATIC : _PID_MODE_MANUAL; +} + +/* ~~~~~~~~~~~~~~~~ PID Limits ~~~~~~~~~~~~~~~~~ */ +void PID_SetOutputLimits(PID_TypeDef *uPID, float Min, float Max) +{ + /* ~~~~~~~~~~ Check value ~~~~~~~~~~ */ + if (Min >= Max) + { + return; + } + + uPID->OutMin = Min; + uPID->OutMax = Max; + + /* ~~~~~~~~~~ Check PID Mode ~~~~~~~~~~ */ + if (uPID->InAuto) + { + + /* ..... Check out value ..... */ + if (*uPID->MyOutput > uPID->OutMax) + { + *uPID->MyOutput = uPID->OutMax; + } + else if (*uPID->MyOutput < uPID->OutMin) + { + *uPID->MyOutput = uPID->OutMin; + } + else { } + + /* ..... Check out value ..... */ + if (uPID->OutputSum > uPID->OutMax) + { + uPID->OutputSum = uPID->OutMax; + } + else if (uPID->OutputSum < uPID->OutMin) + { + uPID->OutputSum = uPID->OutMin; + } + else { } + + } + +} + +/* ~~~~~~~~~~~~~~~~ PID Tunings ~~~~~~~~~~~~~~~~ */ +void PID_SetTunings(PID_TypeDef *uPID, float Kp, float Ki, float Kd) +{ + PID_SetTunings2(uPID, Kp, Ki, Kd, uPID->POn); +} +void PID_SetTunings2(PID_TypeDef *uPID, float Kp, float Ki, float Kd, PIDPON_TypeDef POn) +{ + + float SampleTimeInSec; + + /* ~~~~~~~~~~ Check value ~~~~~~~~~~ */ + if (Kp < 0 || Ki < 0 || Kd < 0) + { + return; + } + + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + uPID->POn = POn; + uPID->POnE = (PIDPON_TypeDef)(POn == _PID_P_ON_E); + + uPID->DispKp = Kp; + uPID->DispKi = Ki; + uPID->DispKd = Kd; + + /* ~~~~~~~~~ Calculate time ~~~~~~~~ */ + SampleTimeInSec = ((float)uPID->SampleTime) / 1000; + + uPID->Kp = Kp; + uPID->Ki = Ki * SampleTimeInSec; + uPID->Kd = Kd / SampleTimeInSec; + + /* ~~~~~~~~ Check direction ~~~~~~~~ */ + if (uPID->ControllerDirection == _PID_CD_REVERSE) + { + + uPID->Kp = (0 - uPID->Kp); + uPID->Ki = (0 - uPID->Ki); + uPID->Kd = (0 - uPID->Kd); + + } + +} + +/* ~~~~~~~~~~~~~~~ PID Direction ~~~~~~~~~~~~~~~ */ +void PID_SetControllerDirection(PID_TypeDef *uPID, PIDCD_TypeDef Direction) +{ + /* ~~~~~~~~~~ Check parameters ~~~~~~~~~~ */ + if ((uPID->InAuto) && (Direction !=uPID->ControllerDirection)) + { + + uPID->Kp = (0 - uPID->Kp); + uPID->Ki = (0 - uPID->Ki); + uPID->Kd = (0 - uPID->Kd); + + } + + uPID->ControllerDirection = Direction; + +} +PIDCD_TypeDef PID_GetDirection(PID_TypeDef *uPID) +{ + return uPID->ControllerDirection; +} + +/* ~~~~~~~~~~~~~~~ PID Sampling ~~~~~~~~~~~~~~~~ */ +void PID_SetSampleTime(PID_TypeDef *uPID, int32_t NewSampleTime) +{ + + float ratio; + + /* ~~~~~~~~~~ Check value ~~~~~~~~~~ */ + if (NewSampleTime > 0) + { + + ratio = (float)NewSampleTime / (float)uPID->SampleTime; + + uPID->Ki *= ratio; + uPID->Kd /= ratio; + uPID->SampleTime = (uint32_t)NewSampleTime; + + } + +} + +/* ~~~~~~~~~~~~~ Get Tunings Param ~~~~~~~~~~~~~ */ +float PID_GetKp(PID_TypeDef *uPID) +{ + return uPID->DispKp; +} +float PID_GetKi(PID_TypeDef *uPID) +{ + return uPID->DispKi; +} +float PID_GetKd(PID_TypeDef *uPID) +{ + return uPID->DispKd; +} diff --git a/3rd-part/PID-Library/pid.h b/3rd-part/PID-Library/pid.h new file mode 100644 index 0000000..374bc53 --- /dev/null +++ b/3rd-part/PID-Library/pid.h @@ -0,0 +1,170 @@ +/* +------------------------------------------------------------------------------ +~ File : pid.h +~ Author : Majid Derhambakhsh +~ Version: V1.0.0 +~ Created: 02/11/2021 03:43:00 AM +~ Brief : +~ Support: + E-Mail : Majid.do16@gmail.com (subject : Embedded Library Support) + + Github : https://github.com/Majid-Derhambakhsh +------------------------------------------------------------------------------ +~ Description: + +~ Attention : + +~ Changes : +------------------------------------------------------------------------------ +*/ + +#ifndef __PID_H_ +#define __PID_H_ + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Include ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +#include +#include + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Defines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ------------------------ Library ------------------------ */ +#define _PID_LIBRARY_VERSION 1.0.0 + +/* ------------------------ Public ------------------------- */ +#define _PID_8BIT_PWM_MAX UINT8_MAX +#define _PID_SAMPLE_TIME_MS_DEF 100 + +#ifndef _FALSE + +#define _FALSE 0 + +#endif + +#ifndef _TRUE + +#define _TRUE 1 + +#endif + +/* ---------------------- By compiler ---------------------- */ +#ifndef GetTime + +/* ---------------------- By compiler ---------------------- */ + +#ifdef __CODEVISIONAVR__ /* Check compiler */ + +#define GetTime() 0 + +/* ------------------------------------------------------------------ */ + +#elif defined(__GNUC__) /* Check compiler */ + +#define GetTime() 0 + +/* ------------------------------------------------------------------ */ + +#else +#endif /* __CODEVISIONAVR__ */ + /* ------------------------------------------------------------------ */ + +#endif + +/* --------------------------------------------------------- */ + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* PID Mode */ +typedef enum { + + _PID_MODE_MANUAL = 0, + _PID_MODE_AUTOMATIC = 1 + +} PIDMode_TypeDef; + +/* PID P On x */ +typedef enum { + + _PID_P_ON_M = 0, /* Proportional on Measurement */ + _PID_P_ON_E = 1 + +} PIDPON_TypeDef; + +/* PID Control direction */ +typedef enum { + + _PID_CD_DIRECT = 0, + _PID_CD_REVERSE = 1 + +} PIDCD_TypeDef; + +/* PID Structure */ +typedef struct +{ + + PIDPON_TypeDef POnE; + PIDMode_TypeDef InAuto; + + PIDPON_TypeDef POn; + PIDCD_TypeDef ControllerDirection; + + uint32_t LastTime; + uint32_t SampleTime; + + float DispKp; + float DispKi; + float DispKd; + + float Kp; + float Ki; + float Kd; + + float *MyInput; + float *MyOutput; + float *MySetpoint; + + float OutputSum; + float LastInput; + + float OutMin; + float OutMax; + +} PID_TypeDef; + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Enum ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Struct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prototype ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* :::::::::::::: Init ::::::::::::: */ +void PID_Init(PID_TypeDef *uPID); + +void PID(PID_TypeDef *uPID, const float *Input, float *Output, const float *Setpoint, float Kp, float Ki, float Kd, PIDPON_TypeDef POn, PIDCD_TypeDef ControllerDirection); +void PID2(PID_TypeDef *uPID, const float *Input, float *Output, const float *Setpoint, float Kp, float Ki, float Kd, PIDCD_TypeDef ControllerDirection); + +/* ::::::::::: Computing ::::::::::: */ +uint8_t PID_Compute(PID_TypeDef *uPID); + +/* ::::::::::: PID Mode :::::::::::: */ +void PID_SetMode(PID_TypeDef *uPID, PIDMode_TypeDef Mode); +PIDMode_TypeDef PID_GetMode(PID_TypeDef *uPID); + +/* :::::::::: PID Limits ::::::::::: */ +void PID_SetOutputLimits(PID_TypeDef *uPID, float Min, float Max); + +/* :::::::::: PID Tunings :::::::::: */ +void PID_SetTunings(PID_TypeDef *uPID, float Kp, float Ki, float Kd); +void PID_SetTunings2(PID_TypeDef *uPID, float Kp, float Ki, float Kd, PIDPON_TypeDef POn); + +/* ::::::::: PID Direction ::::::::: */ +void PID_SetControllerDirection(PID_TypeDef *uPID, PIDCD_TypeDef Direction); +PIDCD_TypeDef PID_GetDirection(PID_TypeDef *uPID); + +/* ::::::::: PID Sampling :::::::::: */ +void PID_SetSampleTime(PID_TypeDef *uPID, int32_t NewSampleTime); + +/* ::::::: Get Tunings Param ::::::: */ +float PID_GetKp(PID_TypeDef *uPID); +float PID_GetKi(PID_TypeDef *uPID); +float PID_GetKd(PID_TypeDef *uPID); + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ End of the program ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +#endif /* __PID_H_ */ diff --git a/3rd-part/lwprintf/.gitignore b/3rd-part/lwprintf/.gitignore new file mode 100644 index 0000000..4674b8a --- /dev/null +++ b/3rd-part/lwprintf/.gitignore @@ -0,0 +1,400 @@ +#Build Keil files +*.rar +*.o +*.d +*.crf +*.htm +*.dep +*.map +*.bak +*.axf +*.lnp +*.lst +*.ini +*.scvd +*.iex +*.sct +*.MajerleT +*.tjuln +*.tilen +*.dbgconf +*.uvguix +*.uvoptx +*.__i +*.i +*.txt +!docs/*.txt +!CMakeLists.txt +RTE/ + +*debug + +# IAR Settings +**/settings/*.crun +**/settings/*.dbgdt +**/settings/*.cspy +**/settings/*.cspy.* +**/settings/*.xcl +**/settings/*.dni +**/settings/*.wsdt +**/settings/*.wspos + +# IAR Debug Exe +**/Exe/*.sim + +# IAR Debug Obj +**/Obj/*.pbd +**/Obj/*.pbd.* +**/Obj/*.pbi +**/Obj/*.pbi.* + +*.TMP +/docs_src/x_Doxyfile.doxy + +.DS_Store + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +[Dd]ebug*/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +_build/ +build/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc +*.out +*.sim + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# TypeScript v1 declaration files +typings/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +log_file.txt +.metadata/ +.mxproject +.settings/ +project.ioc +mx.scratch +*.tilen majerle + + +# Altium +Project outputs* +History/ +*.SchDocPreview +*.$$$Preview + +# VSCode projects +project_vscode_compiled.exe \ No newline at end of file diff --git a/3rd-part/lwprintf/AUTHORS b/3rd-part/lwprintf/AUTHORS new file mode 100644 index 0000000..bbb2e36 --- /dev/null +++ b/3rd-part/lwprintf/AUTHORS @@ -0,0 +1,6 @@ +Tilen Majerle +Tilen Majerle +Okarss <104319900+Okarss@users.noreply.github.com> +Dmitry Karasev +Brian +Peter Maxwell Warasila \ No newline at end of file diff --git a/3rd-part/lwprintf/CHANGELOG.md b/3rd-part/lwprintf/CHANGELOG.md new file mode 100644 index 0000000..5d11011 --- /dev/null +++ b/3rd-part/lwprintf/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog + +## Develop + +- Add `lwprintf_debug` and `lwprintf_debug_cond` functions + +## v1.0.5 + +- Fix building the library with `LWPRINTF_CFG_OS=1` and `LWPRINTF_CFG_OS_MANUAL_PROTECT=0` options + +## v1.0.4 + +- Fix calculation for NULL terminated string and precision with 0 as an input +- Split CMakeLists.txt files between library and executable +- Fix missing break in switch statement +- Add support for manual mutual-exclusion setup in OS mode +- Change license year to 2022 +- Update code style with astyle +- Add `.clang-format` draft +- Fix protection functions for when print mode is not used + +## v1.0.3 + +- CMSIS-OS improvements for Kernel aware debuggers + +## v1.0.2 + +- Fixed `float` output when engineering mode is disabled + +## v1.0.1 + +- Fixed compiler error when engineering mode disabled but float enabled +- Properly handled `zero` float inputs + +## v1.0.0 + +- First stable release +- Embedded systems optimized library +- Apply all modifiers except `%a` +- Extensive docs available +- Operating system ready with CMSIS-OS template diff --git a/3rd-part/lwprintf/LICENSE b/3rd-part/lwprintf/LICENSE new file mode 100644 index 0000000..42c1b5c --- /dev/null +++ b/3rd-part/lwprintf/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Tilen MAJERLE + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/3rd-part/lwprintf/README.md b/3rd-part/lwprintf/README.md new file mode 100644 index 0000000..d49826d --- /dev/null +++ b/3rd-part/lwprintf/README.md @@ -0,0 +1,29 @@ +# Lightweight printf stdio manager + +

Read first: Documentation

+ +## Features + +* Written in C (C11), compatible with ``size_t`` and ``uintmax_t`` types for some specifiers +* Implements output functions compatible with ``printf``, ``vprintf``, ``snprintf``, ``sprintf`` and ``vsnprintf`` +* Low-memory footprint, suitable for embedded systems +* Reentrant access to all API functions +* Operating-system ready +* Requires single output function to be implemented by user for ``printf``-like API calls +* With optional functions for operating systems to protect multiple threads printing to the same output stream +* Allows multiple output stream functions (unlike standard ``printf`` which supports only one) to separate parts of application +* Added additional specifiers vs original features +* User friendly MIT license + +## Contribute + +Fresh contributions are always welcome. Simple instructions to proceed: + +1. Fork Github repository +2. Follow [C style & coding rules](https://github.com/MaJerle/c-code-style) already used in the project +3. Create a pull request to develop branch with new features or bug fixes + +Alternatively you may: + +1. Report a bug +2. Ask for a feature request diff --git a/3rd-part/lwprintf/lwprintf.c b/3rd-part/lwprintf/lwprintf.c new file mode 100644 index 0000000..c2040c8 --- /dev/null +++ b/3rd-part/lwprintf/lwprintf.c @@ -0,0 +1,1274 @@ +/** + * \file lwprintf.c + * \brief Lightweight stdio manager + */ + +/* + * Copyright (c) 2024 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwPRINTF - Lightweight stdio manager library. + * + * Author: Tilen MAJERLE + * Version: v1.0.5 + */ +#include "lwprintf.h" +#include +#include +#include + +#if LWPRINTF_CFG_OS +#include "system/lwprintf_sys.h" +#endif /* LWPRINTF_CFG_OS */ + +/* Static checks */ +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING && !LWPRINTF_CFG_SUPPORT_TYPE_FLOAT +#error "Cannot use engineering type without float!" +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING && !LWPRINTF_CFG_SUPPORT_TYPE_FLOAT */ +#if !LWPRINTF_CFG_OS && LWPRINTF_CFG_OS_MANUAL_PROTECT +#error "LWPRINTF_CFG_OS_MANUAL_PROTECT can only be used if LWPRINTF_CFG_OS is enabled" +#endif /* !LWPRINTF_CFG_OS && LWPRINTF_CFG_OS_MANUAL_PROTECT */ + +#define CHARISNUM(x) ((x) >= '0' && (x) <= '9') +#define CHARTONUM(x) ((x) - '0') +#define IS_PRINT_MODE(p) ((p)->out_fn == prv_out_fn_print) + +/* Define custom types */ +#if LWPRINTF_CFG_SUPPORT_LONG_LONG +typedef long long int float_long_t; +#else +typedef long int float_long_t; +#endif /* LWPRINTF_CFG_SUPPORT_LONG_LONG */ + +/** + * \brief Float number splitted by parts + */ +typedef struct { + float_long_t integer_part; /*!< Integer type of double number */ + double decimal_part_dbl; /*!< Decimal part of double number multiplied by 10^precision */ + float_long_t decimal_part; /*!< Decimal part of double number in integer format */ + double diff; /*!< Difference between decimal parts (double - int) */ + + short digits_cnt_integer_part; /*!< Number of digits for integer part */ + short digits_cnt_decimal_part; /*!< Number of digits for decimal part */ + short digits_cnt_decimal_part_useful; /*!< Number of useful digits to print */ +} float_num_t; + +#if LWPRINTF_CFG_SUPPORT_TYPE_FLOAT +/* Powers of 10 from beginning up to precision level */ +static const float_long_t powers_of_10[] = { + (float_long_t)1E00, (float_long_t)1E01, (float_long_t)1E02, (float_long_t)1E03, (float_long_t)1E04, + (float_long_t)1E05, (float_long_t)1E06, (float_long_t)1E07, (float_long_t)1E08, (float_long_t)1E09, +#if LWPRINTF_CFG_SUPPORT_LONG_LONG + (float_long_t)1E10, (float_long_t)1E11, (float_long_t)1E12, (float_long_t)1E13, (float_long_t)1E14, + (float_long_t)1E15, (float_long_t)1E16, (float_long_t)1E17, (float_long_t)1E18, +#endif /* LWPRINTF_CFG_SUPPORT_LONG_LONG */ +}; +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_FLOAT */ +#define FLOAT_MAX_B_ENG (powers_of_10[LWPRINTF_ARRAYSIZE(powers_of_10) - 1]) + +/** + * \brief Outputs any integer type to stream + * Implemented as big macro since `d`, `digit` and `num` are of different types vs int size + */ +#define OUTPUT_ANY_INT_TYPE(ttype, num) \ + { \ + ttype den, digit; \ + uint8_t digits_cnt; \ + char chr; \ + \ + /* Check if number is zero */ \ + lwi->m.flags.is_num_zero = (num) == 0; \ + if ((num) == 0) { \ + prv_out_str_before(lwi, 1); \ + lwi->out_fn(lwi, '0'); \ + prv_out_str_after(lwi, 1); \ + } else { \ + /* Start with digits length */ \ + for (digits_cnt = 0, den = (num); den > 0; ++digits_cnt, den /= lwi->m.base) {} \ + for (den = 1; ((num) / den) >= lwi->m.base; den *= lwi->m.base) {} \ + \ + prv_out_str_before(lwi, digits_cnt); \ + for (; den > 0;) { \ + digit = (num) / den; \ + (num) = (num) % den; \ + den = den / lwi->m.base; \ + chr = (char)digit + (char)(digit >= 10 ? ((lwi->m.flags.uc ? 'A' : 'a') - 10) : '0'); \ + lwi->out_fn(lwi, chr); \ + } \ + prv_out_str_after(lwi, digits_cnt); \ + } \ + } + +/** + * \brief Check for negative input number before outputting signed integers + * \param[in] pp: Parsing object + * \param[in] nnum: Number to check + */ +#define SIGNED_CHECK_NEGATIVE(pp, nnum) \ + { \ + if ((nnum) < 0) { \ + (pp)->m.flags.is_negative = 1; \ + (nnum) = -(nnum); \ + } \ + } + +/** + * \brief Forward declaration + */ +struct lwprintf_int; + +/** + * \brief Private output function declaration + * \param[in] lwi: Internal working structure + * \param[in] chr: Character to print + */ +typedef int (*prv_output_fn)(struct lwprintf_int* lwi, const char chr); + +/** + * \brief Internal structure + */ +typedef struct lwprintf_int { + lwprintf_t* lwobj; /*!< Instance handle */ + const char* fmt; /*!< Format string */ + char* const buff; /*!< Pointer to buffer when not using print option */ + const size_t buff_size; /*!< Buffer size of input buffer (when used) */ + size_t n_len; /*!< Full length of formatted text */ + prv_output_fn out_fn; /*!< Output internal function */ + uint8_t is_print_cancelled; /*!< Status if print should be cancelled */ + + /* This must all be reset every time new % is detected */ + struct { + struct { + uint8_t left_align : 1; /*!< Minus for left alignment */ + uint8_t plus : 1; /*!< Prepend + for positive numbers on the output */ + uint8_t space : 1; /*!< Prepend spaces. Not used with plus modifier */ + uint8_t zero : 1; /*!< Zero pad flag detection, add zeros if number length is less than width modifier */ + uint8_t thousands : 1; /*!< Thousands has grouping applied */ + uint8_t alt : 1; /*!< Alternate form with hash */ + uint8_t precision : 1; /*!< Precision flag has been used */ + + /* Length modified flags */ + uint8_t longlong : 2; /*!< Flag indicatin long-long number, used with 'l' (1) or 'll' (2) mode */ + uint8_t char_short : 2; /*!< Used for 'h' (1 = short) or 'hh' (2 = char) length modifier */ + uint8_t sz_t : 1; /*!< Status for size_t length integer type */ + uint8_t umax_t : 1; /*!< Status for uintmax_z length integer type */ + + uint8_t uc : 1; /*!< Uppercase flag */ + uint8_t is_negative : 1; /*!< Status if number is negative */ + uint8_t is_num_zero : 1; /*!< Status if input number is zero */ + } flags; /*!< List of flags */ + + int precision; /*!< Selected precision */ + int width; /*!< Text width indicator */ + uint8_t base; /*!< Base for number format output */ + char type; /*!< Format type */ + } m; /*!< Block that is reset on every start of format */ +} lwprintf_int_t; + +/** + * \brief Get LwPRINTF instance based on user input + * \param[in] lwi: LwPRINTF instance. + * Set to `NULL` for default instance + */ +#define LWPRINTF_GET_LWOBJ(ptr) ((ptr) != NULL ? (ptr) : (&lwprintf_default)) + +/** + * \brief LwPRINTF default structure used by application + */ +static lwprintf_t lwprintf_default; + +/** + * \brief Output function to print data + * \param[in] ptr: LwPRINTF internal instance + * \param[in] chr: Character to print + * \return `1` on success, `0` otherwise + */ +static int +prv_out_fn_print(lwprintf_int_t* lwi, const char chr) { + if (lwi->is_print_cancelled) { + return 0; + } + /*!< Send character to output */ + if (!lwi->lwobj->out_fn(chr, lwi->lwobj)) { + lwi->is_print_cancelled = 1; + } + if (chr != '\0' && !lwi->is_print_cancelled) { + ++lwi->n_len; + } + return 1; +} + +/** + * \brief Output function to generate buffer data + * \param[in] lwi: LwPRINTF internal instance + * \param[in] chr: Character to write + * \return `1` on success, `0` otherwise + */ +static int +prv_out_fn_write_buff(lwprintf_int_t* lwi, const char chr) { + if (lwi->n_len < (lwi->buff_size - 1)) { + lwi->buff[lwi->n_len] = chr; + if (chr != '\0') { + lwi->buff[++lwi->n_len] = '\0'; + } + return 1; + } + return 0; +} + +/** + * \brief Parse number from input string + * \param[in,out] format: Input text to process + * \return Parsed number + */ +static int +prv_parse_num(const char** format) { + const char* fmt = *format; + int num = 0; + + for (; CHARISNUM(*fmt); ++fmt) { + num = (int)10 * num + CHARTONUM(*fmt); + } + *format = fmt; + return num; +} + +/** + * \brief Format data that are printed before actual value + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] buff_size: Expected buffer size of output string + * \return `1` on success, `0` otherwise + */ +static int +prv_out_str_before(lwprintf_int_t* lwi, size_t buff_size) { + /* Check for width */ + if (lwi->m.width > 0 + /* If number is negative, add negative sign or if positive and has plus sign forced */ + && (lwi->m.flags.is_negative || lwi->m.flags.plus)) { + --lwi->m.width; + } + + /* Check for alternate mode */ + if (lwi->m.flags.alt && !lwi->m.flags.is_num_zero) { + if (lwi->m.base == 8) { + if (lwi->m.width > 0) { + --lwi->m.width; + } + } else if (lwi->m.base == 16 || lwi->m.base == 2) { + if (lwi->m.width >= 2) { + lwi->m.width -= 2; + } else { + lwi->m.width = 0; + } + } + } + + /* Add negative sign (or positive in case of + flag or space in case of space flag) before when zeros are used to fill width */ + if (lwi->m.flags.zero) { + if (lwi->m.flags.is_negative) { + lwi->out_fn(lwi, '-'); + } else if (lwi->m.flags.plus) { + lwi->out_fn(lwi, '+'); + } else if (lwi->m.flags.space) { + lwi->out_fn(lwi, ' '); + } + } + + /* Check for flags output */ + if (lwi->m.flags.alt && !lwi->m.flags.is_num_zero) { + if (lwi->m.base == 8) { + lwi->out_fn(lwi, '0'); + } else if (lwi->m.base == 16) { + lwi->out_fn(lwi, '0'); + lwi->out_fn(lwi, lwi->m.flags.uc ? 'X' : 'x'); + } else if (lwi->m.base == 2) { + lwi->out_fn(lwi, '0'); + lwi->out_fn(lwi, lwi->m.flags.uc ? 'B' : 'b'); + } + } + + /* Right alignment, spaces or zeros */ + if (!lwi->m.flags.left_align && lwi->m.width > 0) { + for (size_t idx = buff_size; !lwi->m.flags.left_align && idx < (size_t)lwi->m.width; ++idx) { + lwi->out_fn(lwi, lwi->m.flags.zero ? '0' : ' '); + } + } + + /* Add negative sign here when spaces are used for width */ + if (!lwi->m.flags.zero) { + if (lwi->m.flags.is_negative) { + lwi->out_fn(lwi, '-'); + } else if (lwi->m.flags.plus) { + lwi->out_fn(lwi, '+'); + } else if (lwi->m.flags.space && buff_size >= (size_t)lwi->m.width) { + lwi->out_fn(lwi, ' '); + } + } + + return 1; +} + +/** + * \brief Format data that are printed after actual value + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] buff_size: Expected buffer size of output string + * \return `1` on success, `0` otherwise + */ +static int +prv_out_str_after(lwprintf_int_t* lwi, size_t buff_size) { + /* Left alignment, but only with spaces */ + if (lwi->m.flags.left_align) { + for (size_t idx = buff_size; idx < (size_t)lwi->m.width; ++idx) { + lwi->out_fn(lwi, ' '); + } + } + return 1; +} + +/** + * \brief Output raw string without any formatting + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] buff: Buffer string + * \param[in] buff_size: Length of buffer to output + * \return `1` on success, `0` otherwise + */ +static int +prv_out_str_raw(lwprintf_int_t* lwi, const char* buff, size_t buff_size) { + for (size_t idx = 0; idx < buff_size; ++idx) { + lwi->out_fn(lwi, buff[idx]); + } + return 1; +} + +/** + * \brief Output generated string from numbers/digits + * Paddings before and after are applied at this stage + * + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] buff: Buffer string + * \param[in] buff_size: Length of buffer to output + * \return `1` on success, `0` otherwise + */ +static int +prv_out_str(lwprintf_int_t* lwi, const char* buff, size_t buff_size) { + prv_out_str_before(lwi, buff_size); /* Implement pre-format */ + prv_out_str_raw(lwi, buff, buff_size); /* Print actual string */ + prv_out_str_after(lwi, buff_size); /* Implement post-format */ + + return 1; +} + +/** + * \brief Convert `unsigned int` to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_unsigned_int_to_str(lwprintf_int_t* lwi, unsigned int num) { + OUTPUT_ANY_INT_TYPE(unsigned int, num); + return 1; +} + +/** + * \brief Convert `unsigned long` to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_unsigned_long_int_to_str(lwprintf_int_t* lwi, unsigned long int num) { + OUTPUT_ANY_INT_TYPE(unsigned long int, num); + return 1; +} + +#if LWPRINTF_CFG_SUPPORT_LONG_LONG + +/** + * \brief Convert `unsigned long-long` to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_unsigned_longlong_int_to_str(lwprintf_int_t* lwi, unsigned long long int num) { + OUTPUT_ANY_INT_TYPE(unsigned long long int, num); + return 1; +} + +#endif /* LWPRINTF_CFG_SUPPORT_LONG_LONG */ + +#if LWPRINTF_CFG_SUPPORT_TYPE_POINTER + +/** + * \brief Convert `uintptr_t` to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_uintptr_to_str(lwprintf_int_t* lwi, uintptr_t num) { + OUTPUT_ANY_INT_TYPE(uintptr_t, num); + return 1; +} + +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_POINTER */ + +/** + * \brief Convert `size_t` number to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_sizet_to_str(lwprintf_int_t* lwi, size_t num) { + OUTPUT_ANY_INT_TYPE(size_t, num); + return 1; +} + +/** + * \brief Convert `uintmax_t` number to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_umaxt_to_str(lwprintf_int_t* lwi, uintmax_t num) { + OUTPUT_ANY_INT_TYPE(uintmax_t, num); + return 1; +} + +/** + * \brief Convert signed int to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_signed_int_to_str(lwprintf_int_t* lwi, signed int num) { + SIGNED_CHECK_NEGATIVE(lwi, num); + return prv_unsigned_int_to_str(lwi, num); +} + +/** + * \brief Convert signed long int to string + * \param[in,out] lwi: LwPRINTF instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_signed_long_int_to_str(lwprintf_int_t* lwi, signed long int num) { + SIGNED_CHECK_NEGATIVE(lwi, num); + return prv_unsigned_long_int_to_str(lwi, num); +} + +#if LWPRINTF_CFG_SUPPORT_LONG_LONG + +/** + * \brief Convert signed long-long int to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_signed_longlong_int_to_str(lwprintf_int_t* lwi, signed long long int num) { + SIGNED_CHECK_NEGATIVE(lwi, num); + return prv_unsigned_longlong_int_to_str(lwi, num); +} + +#endif /* LWPRINTF_CFG_SUPPORT_LONG_LONG */ + +#if LWPRINTF_CFG_SUPPORT_TYPE_FLOAT + +/** + * \brief Calculate necessary parameters for input number + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] n: Float number instance + * \param[in] num: Input number + * \param[in] type: Format type + */ +static void +prv_calculate_dbl_num_data(lwprintf_int_t* lwi, float_num_t* n, double num, const char type) { + memset(n, 0x00, sizeof(*n)); + + if (lwi->m.precision >= (int)LWPRINTF_ARRAYSIZE(powers_of_10)) { + lwi->m.precision = (int)LWPRINTF_ARRAYSIZE(powers_of_10) - 1; + } + + /* + * Get integer and decimal parts, both in integer formats + * + * As an example, with input number of 12.345678 and precision digits set as 4, then result is the following: + * + * integer_part = 12 -> Actual integer part of the double number + * decimal_part_dbl = 3456.78 -> Decimal part multiplied by 10^precision, keeping it in double format + * decimal_part = 3456 -> Integer part of decimal number + * diff = 0.78 -> Difference between actual decimal and integer part of decimal + * This is used for rounding of last digit (if necessary) + */ + num += 0.000000000000005; + n->integer_part = (float_long_t)num; + n->decimal_part_dbl = (num - (double)n->integer_part) * (double)powers_of_10[lwi->m.precision]; + n->decimal_part = (float_long_t)n->decimal_part_dbl; + n->diff = n->decimal_part_dbl - (double)((float_long_t)n->decimal_part); + + /* Rounding check of last digit */ + if (n->diff > 0.5) { + ++n->decimal_part; + if (n->decimal_part >= powers_of_10[lwi->m.precision]) { + n->decimal_part = 0; + ++n->integer_part; + } + } else if (n->diff < 0.5) { + /* Used in separate if, since comparing float to == will certainly result to false */ + } else { + /* Difference is exactly 0.5 */ + if (n->decimal_part == 0) { + ++n->integer_part; + } else { + ++n->decimal_part; + } + } + + /* Calculate number of digits for integer and decimal parts */ + if (n->integer_part == 0) { + n->digits_cnt_integer_part = 1; + } else { + float_long_t tmp; + for (n->digits_cnt_integer_part = 0, tmp = n->integer_part; tmp > 0; ++n->digits_cnt_integer_part, tmp /= 10) {} + } + n->digits_cnt_decimal_part = (short)lwi->m.precision; + +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + /* Calculate minimum useful digits for decimal (excl last useless zeros) */ + if (type == 'g') { + float_long_t tmp = n->decimal_part; + short adder, i; + + for (adder = 0, i = 0; tmp > 0 || i < (short)lwi->m.precision; + tmp /= 10, n->digits_cnt_decimal_part_useful += adder, ++i) { + if (adder == 0 && (tmp % 10) > 0) { + adder = 1; + } + } + } else +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + { + n->digits_cnt_decimal_part_useful = (short)lwi->m.precision; + } +} + +/** + * \brief Convert double number to string + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] num: Number to convert to string + * \return `1` on success, `0` otherwise + */ +static int +prv_double_to_str(lwprintf_int_t* lwi, double in_num) { + float_num_t dblnum; + double orig_num = in_num; + int digits_cnt, chosen_precision, i; +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + int exp_cnt = 0; +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + char def_type = lwi->m.type; + char str[LWPRINTF_CFG_SUPPORT_LONG_LONG ? 22 : 11]; + + /* + * Check for corner cases + * + * - Print "nan" if number is not valid + * - Print negative infinity if number is less than absolute minimum + * - Print negative infinity if number is less than -FLOAT_MAX_B_ENG and engineering mode is disabled + * - Print positive infinity if number is greater than absolute minimum + * - Print positive infinity if number is greater than FLOAT_MAX_B_ENG and engineering mode is disabled + * - Go to engineering mode if it is enabled and `in_num < -FLOAT_MAX_B_ENG` or `in_num > FLOAT_MAX_B_ENG` + */ + if (in_num != in_num) { + return prv_out_str(lwi, lwi->m.flags.uc ? "NAN" : "nan", 3); + } else if (in_num < -DBL_MAX +#if !LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + || in_num < -FLOAT_MAX_B_ENG +#endif /* !LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + ) { + return prv_out_str(lwi, lwi->m.flags.uc ? "-INF" : "-inf", 4); + } else if (in_num > DBL_MAX +#if !LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + || in_num > FLOAT_MAX_B_ENG +#endif /* !LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + ) { + char str[5], *s_ptr = str; + if (lwi->m.flags.plus) { + *s_ptr++ = '+'; + } + strcpy(s_ptr, lwi->m.flags.uc ? "INF" : "inf"); + return prv_out_str(lwi, str, lwi->m.flags.plus ? 4 : 3); +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + } else if ((in_num < -FLOAT_MAX_B_ENG || in_num > FLOAT_MAX_B_ENG) && def_type != 'g') { + lwi->m.type = def_type = 'e'; /* Go to engineering mode */ +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + } + + /* Check sign of the number */ + SIGNED_CHECK_NEGATIVE(lwi, in_num); + orig_num = in_num; + +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + /* Engineering mode check for number of exponents */ + if (def_type == 'e' || def_type == 'g' + || in_num > (double)(powers_of_10[LWPRINTF_ARRAYSIZE(powers_of_10) - 1])) { /* More vs what float can hold */ + if (lwi->m.type != 'g') { + lwi->m.type = 'e'; + } + + /* Normalize number to be between 0 and 1 and count decimals for exponent */ + if (in_num < 1) { + for (exp_cnt = 0; in_num < 1 && in_num > 0; in_num *= 10, --exp_cnt) {} + } else { + for (exp_cnt = 0; in_num >= 10; in_num /= 10, ++exp_cnt) {} + } + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + + /* Check precision data */ + chosen_precision = lwi->m.precision; /* This is default value coming from app */ + if (lwi->m.precision >= (int)LWPRINTF_ARRAYSIZE(powers_of_10)) { + lwi->m.precision = (int)LWPRINTF_ARRAYSIZE(powers_of_10) - 1; /* Limit to maximum precision */ + /* + * Precision is lower than the one selected by app (or user). + * It means that we have to append ending zeros for precision when printing data + */ + } else if (!lwi->m.flags.precision) { + lwi->m.precision = LWPRINTF_CFG_FLOAT_DEFAULT_PRECISION; /* Default precision when not used */ + chosen_precision = lwi->m.precision; /* There was no precision, update chosen precision */ + } else if (lwi->m.flags.precision && lwi->m.precision == 0) { +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + /* Precision must be set to 1 if set to 0 by default */ + if (def_type == 'g') { + lwi->m.precision = 1; + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + } + + /* Check if type is g and decide if final output should be 'f' or 'e' */ + /* + * For 'g/G' specifier + * + * A double argument representing a floating-point number is converted + * in style 'f' or 'e' (or in style 'F' or 'E' in the case of a 'G' conversion specifier), + * depending on the value converted and the precision. + * Let 'P' equal the precision if nonzero, '6' if the precision is omitted, or '1' if the precision is zero. + * Then, if a conversion with style 'E' would have an exponent of 'X': + * + * if 'P > X >= -4', the conversion is with style 'f' (or 'F') and precision 'P - (X + 1)'. + * otherwise, the conversion is with style 'e' (or 'E') and precision 'P - 1'. + * + * Finally, unless the '#' flag is used, + * any trailing zeros are removed from the fractional portion of the result + * and the decimal-point character is removed if there is no fractional portion remaining. + * + * A double argument representing an infinity or 'NaN' is converted in the style of an 'f' or 'F' conversion specifier. + */ + + /* Calculate data for number */ + prv_calculate_dbl_num_data(lwi, &dblnum, def_type == 'e' ? in_num : orig_num, def_type); + +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + /* Set type G */ + if (def_type == 'g') { + /* As per standard to decide level of precision */ + if (exp_cnt >= -4 && exp_cnt < lwi->m.precision) { + if (lwi->m.precision > exp_cnt) { + lwi->m.precision -= exp_cnt + 1; + chosen_precision -= exp_cnt + 1; + } else { + lwi->m.precision = 0; + chosen_precision = 0; + } + lwi->m.type = 'f'; + in_num = orig_num; + } else { + lwi->m.type = 'e'; + if (lwi->m.precision > 0) { + --lwi->m.precision; + --chosen_precision; + } + } + prv_calculate_dbl_num_data(lwi, &dblnum, in_num, def_type); + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + + /* Set number of digits to display */ + digits_cnt = dblnum.digits_cnt_integer_part; + if (0) { +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + } else if (def_type == 'g' && lwi->m.precision > 0) { + digits_cnt += dblnum.digits_cnt_decimal_part_useful; + if (dblnum.digits_cnt_decimal_part_useful > 0) { + ++digits_cnt; + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + } else { + if (chosen_precision > 0 && lwi->m.flags.precision) { + /* Add precision digits + dot separator */ + digits_cnt += chosen_precision + 1; + } + } + +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + /* Increase number of digits to display */ + if (lwi->m.type == 'e') { + /* Format is +Exxx, so add 4 or 5 characters (max is 307, min is 00 for exponent) */ + digits_cnt += 4 + (exp_cnt >= 100 || exp_cnt <= -100); + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + + /* Output strings */ + prv_out_str_before(lwi, digits_cnt); + + /* Output integer part of number */ + if (dblnum.integer_part == 0) { + lwi->out_fn(lwi, '0'); + } else { + for (i = 0; dblnum.integer_part > 0; dblnum.integer_part /= 10, ++i) { + str[i] = (char)'0' + (char)(dblnum.integer_part % 10); + } + for (; i > 0; --i) { + lwi->out_fn(lwi, str[i - 1]); + } + } + + /* Output decimal part */ + if (lwi->m.precision > 0) { + int x; + if (dblnum.digits_cnt_decimal_part_useful > 0) { + lwi->out_fn(lwi, '.'); + } + for (i = 0; dblnum.decimal_part > 0; dblnum.decimal_part /= 10, ++i) { + str[i] = (char)'0' + (char)(dblnum.decimal_part % 10); + } + + /* Output relevant zeros first, string to print is opposite way */ +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + if (def_type == 'g') { + /* TODO: This is to be checked */ + for (x = 0; x < (lwi->m.precision - i) && dblnum.digits_cnt_decimal_part_useful > 0; + ++x, --dblnum.digits_cnt_decimal_part_useful) { + lwi->out_fn(lwi, '0'); + } + } else +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + { + for (x = i; x < lwi->m.precision; ++x) { + lwi->out_fn(lwi, '0'); + } + } + + /* Now print string itself */ + for (; i > 0; --i) { + lwi->out_fn(lwi, str[i - 1]); +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + if (def_type == 'g' && --dblnum.digits_cnt_decimal_part_useful == 0) { + break; + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + } + + /* Print ending zeros if selected precision is bigger than maximum supported */ + if (def_type != 'g') { + for (; x < chosen_precision; ++x) { + lwi->out_fn(lwi, '0'); + } + } + } + +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + /* Engineering mode output, add exponent part */ + if (lwi->m.type == 'e') { + lwi->out_fn(lwi, lwi->m.flags.uc ? 'E' : 'e'); + lwi->out_fn(lwi, exp_cnt >= 0 ? '+' : '-'); + if (exp_cnt < 0) { + exp_cnt = -exp_cnt; + } + if (exp_cnt >= 100) { + lwi->out_fn(lwi, (char)'0' + (char)(exp_cnt / 100)); + exp_cnt /= 100; + } + lwi->out_fn(lwi, (char)'0' + (char)(exp_cnt / 10)); + lwi->out_fn(lwi, (char)'0' + (char)(exp_cnt % 10)); + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + prv_out_str_after(lwi, digits_cnt); + + return 1; +} + +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_FLOAT */ + +/** + * \brief Process format string and parse variable parameters + * \param[in,out] lwi: LwPRINTF internal instance + * \param[in] arg: Variable parameters list + * \return `1` on success, `0` otherwise + */ +static uint8_t +prv_format(lwprintf_int_t* lwi, va_list arg) { + uint8_t detected = 0; + const char* fmt = lwi->fmt; + +#if LWPRINTF_CFG_OS && !LWPRINTF_CFG_OS_MANUAL_PROTECT + if (IS_PRINT_MODE(lwi) && /* OS protection only for print */ + (!lwprintf_sys_mutex_isvalid(&lwi->lwobj->mutex) /* Invalid mutex handle */ + || !lwprintf_sys_mutex_wait(&lwi->lwobj->mutex))) { /* Cannot acquire mutex */ + return 0; + } +#endif /* LWPRINTF_CFG_OS && !LWPRINTF_CFG_OS_MANUAL_PROTECT */ + + while (fmt != NULL && *fmt != '\0') { + /* Check if we should stop processing */ + if (lwi->is_print_cancelled) { + break; + } + + /* Detect beginning */ + if (*fmt != '%') { + lwi->out_fn(lwi, *fmt); /* Output character */ + ++fmt; + continue; + } + ++fmt; + memset(&lwi->m, 0x00, sizeof(lwi->m)); /* Reset structure */ + + /* Parse format */ + /* %[flags][width][.precision][length]type */ + /* Go to https://docs.majerle.eu for more info about supported features */ + + /* Check [flags] */ + /* It can have multiple flags in any order */ + detected = 1; + do { + switch (*fmt) { + case '-': lwi->m.flags.left_align = 1; break; + case '+': lwi->m.flags.plus = 1; break; + case ' ': lwi->m.flags.space = 1; break; + case '0': lwi->m.flags.zero = 1; break; + case '\'': lwi->m.flags.thousands = 1; break; + case '#': lwi->m.flags.alt = 1; break; + default: detected = 0; break; + } + if (detected) { + ++fmt; + } + } while (detected); + + /* Check [width] */ + lwi->m.width = 0; + if (CHARISNUM(*fmt)) { /* Fixed width check */ + /* If number is negative, it has been captured from previous step (left align) */ + lwi->m.width = prv_parse_num(&fmt); /* Number from string directly */ + } else if (*fmt == '*') { /* Or variable check */ + const int w = (int)va_arg(arg, int); + if (w < 0) { + lwi->m.flags.left_align = 1; /* Negative width means left aligned */ + lwi->m.width = -w; + } else { + lwi->m.width = w; + } + ++fmt; + } + + /* Check [.precision] */ + lwi->m.precision = 0; + if (*fmt == '.') { /* Precision flag is detected */ + lwi->m.flags.precision = 1; + if (*++fmt == '*') { /* Variable check */ + const int pr = (int)va_arg(arg, int); + lwi->m.precision = pr > 0 ? pr : 0; + ++fmt; + } else if (CHARISNUM(*fmt)) { /* Directly in the string */ + lwi->m.precision = prv_parse_num(&fmt); + } + } + + /* Check [length] */ + detected = 1; + switch (*fmt) { + case 'h': + lwi->m.flags.char_short = 1; /* Single h detected */ + if (*++fmt == 'h') { /* Does it follow by another h? */ + lwi->m.flags.char_short = 2; /* Second h detected */ + ++fmt; + } + break; + case 'l': + lwi->m.flags.longlong = 1; /* Single l detected */ + if (*++fmt == 'l') { /* Does it follow by another l? */ + lwi->m.flags.longlong = 2; /* Second l detected */ + ++fmt; + } + break; + case 'L': break; + case 'z': + lwi->m.flags.sz_t = 1; /* Size T flag */ + ++fmt; + break; + case 'j': + lwi->m.flags.umax_t = 1; /* uintmax_t flag */ + ++fmt; + break; + case 't': break; + default: detected = 0; + } + + /* Check type */ + lwi->m.type = *fmt + (char)((*fmt >= 'A' && *fmt <= 'Z') ? 0x20 : 0x00); + if (*fmt >= 'A' && *fmt <= 'Z') { + lwi->m.flags.uc = 1; + } + switch (*fmt) { + case 'a': + case 'A': + /* Double in hexadecimal notation */ + (void)va_arg(arg, double); /* Read argument to ignore it and move to next one */ + prv_out_str_raw(lwi, "NaN", 3); /* Print string */ + break; + case 'c': lwi->out_fn(lwi, (char)va_arg(arg, int)); break; +#if LWPRINTF_CFG_SUPPORT_TYPE_INT + case 'd': + case 'i': { + /* Check for different length parameters */ + lwi->m.base = 10; + if (lwi->m.flags.longlong == 0) { + prv_signed_int_to_str(lwi, (signed int)va_arg(arg, signed int)); + } else if (lwi->m.flags.longlong == 1) { + prv_signed_long_int_to_str(lwi, (signed long int)va_arg(arg, signed long int)); +#if LWPRINTF_CFG_SUPPORT_LONG_LONG + } else if (lwi->m.flags.longlong == 2) { + prv_signed_longlong_int_to_str(lwi, (signed long long int)va_arg(arg, signed long long int)); +#endif /* LWPRINTF_CFG_SUPPORT_LONG_LONG */ + } + break; + } + case 'b': + case 'B': + case 'o': + case 'u': + case 'x': + case 'X': + if (*fmt == 'b' || *fmt == 'B') { + lwi->m.base = 2; + } else if (*fmt == 'o') { + lwi->m.base = 8; + } else if (*fmt == 'u') { + lwi->m.base = 10; + } else if (*fmt == 'x' || *fmt == 'X') { + lwi->m.base = 16; + } + lwi->m.flags.space = 0; /* Space flag has no meaning here */ + + /* Check for different length parameters */ + if (0) { + + } else if (lwi->m.flags.sz_t) { + prv_sizet_to_str(lwi, (size_t)va_arg(arg, size_t)); + } else if (lwi->m.flags.umax_t) { + prv_umaxt_to_str(lwi, (uintmax_t)va_arg(arg, uintmax_t)); + } else if (lwi->m.flags.longlong == 0 || lwi->m.base == 2) { + unsigned int v; + switch (lwi->m.flags.char_short) { + case 2: v = (unsigned int)((unsigned char)va_arg(arg, unsigned int)); break; + case 1: v = (unsigned int)((unsigned short int)va_arg(arg, unsigned int)); break; + default: v = (unsigned int)((unsigned int)va_arg(arg, unsigned int)); break; + } + prv_unsigned_int_to_str(lwi, v); + } else if (lwi->m.flags.longlong == 1) { + prv_unsigned_long_int_to_str(lwi, (unsigned long int)va_arg(arg, unsigned long int)); +#if LWPRINTF_CFG_SUPPORT_LONG_LONG + } else if (lwi->m.flags.longlong == 2) { + prv_unsigned_longlong_int_to_str(lwi, (unsigned long long int)va_arg(arg, unsigned long long int)); +#endif /* LWPRINTF_CFG_SUPPORT_LONG_LONG */ + } + break; +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_INT */ +#if LWPRINTF_CFG_SUPPORT_TYPE_STRING + case 's': { + const char* b = va_arg(arg, const char*); + /* + * Calculate length of the string: + * + * - If precision is given, max len is up to precision value + * - if user selects write to buffer, go up to buffer size (-1 actually, but handled by write function) + * - Otherwise use max available system length + */ + prv_out_str(lwi, b, + strnlen(b, lwi->m.flags.precision ? (size_t)lwi->m.precision + : (lwi->buff != NULL ? lwi->buff_size : SIZE_MAX))); + break; + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_STRING */ +#if LWPRINTF_CFG_SUPPORT_TYPE_POINTER + case 'p': { + lwi->m.base = 16; /* Go to hex format */ + lwi->m.flags.uc = 0; /* Uppercase characters */ + lwi->m.flags.zero = 1; /* Zero padding */ + lwi->m.width = + sizeof(uintptr_t) * 2; /* Number is in hex format and byte is represented with 2 letters */ + + prv_uintptr_to_str(lwi, (uintptr_t)va_arg(arg, uintptr_t)); + break; + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_POINTER */ +#if LWPRINTF_CFG_SUPPORT_TYPE_FLOAT + case 'f': + case 'F': +#if LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING + case 'e': + case 'E': + case 'g': + case 'G': +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING */ + /* Double number in different format. Final output depends on type of format */ + prv_double_to_str(lwi, (double)va_arg(arg, double)); + break; +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_FLOAT */ + case 'n': { + int* ptr = (void*)va_arg(arg, int*); + *ptr = (int)lwi->n_len; /* Write current length */ + + break; + } + case '%': lwi->out_fn(lwi, '%'); break; +#if LWPRINTF_CFG_SUPPORT_TYPE_BYTE_ARRAY + /* + * This is to print unsigned-char formatted pointer in hex string + * + * char arr[] = {0, 1, 2, 3, 255}; + * "%5K" would produce 00010203FF + */ + case 'k': + case 'K': { + unsigned char* ptr = + (void*)va_arg(arg, unsigned char*); /* Get input parameter as unsigned char pointer */ + int len = lwi->m.width, full_width; + uint8_t is_space = lwi->m.flags.space == 1; + + if (ptr == NULL || len == 0) { + break; + } + + lwi->m.flags.zero = 1; /* Prepend with zeros if necessary */ + lwi->m.width = 0; /* No width parameter */ + lwi->m.base = 16; /* Hex format */ + lwi->m.flags.space = 0; /* Delete any flag for space */ + + /* Full width of digits to print */ + full_width = len * (2 + (int)is_space); + if (is_space && full_width > 0) { + --full_width; /* Remove space after last number */ + } + + /* Output byte by byte w/o hex prefix */ + prv_out_str_before(lwi, full_width); + for (int i = 0; i < len; ++i, ++ptr) { + uint8_t d; + + d = (*ptr >> 0x04) & 0x0F; /* Print MSB */ + lwi->out_fn(lwi, (char)(d) + (char)(d >= 10 ? ((lwi->m.flags.uc ? 'A' : 'a') - 10) : '0')); + d = *ptr & 0x0F; /* Print LSB */ + lwi->out_fn(lwi, (char)(d) + (char)(d >= 10 ? ((lwi->m.flags.uc ? 'A' : 'a') - 10) : '0')); + + if (is_space && i < (len - 1)) { + lwi->out_fn(lwi, ' '); /* Generate space between numbers */ + } + } + prv_out_str_after(lwi, full_width); + break; + } +#endif /* LWPRINTF_CFG_SUPPORT_TYPE_BYTE_ARRAY */ + default: lwi->out_fn(lwi, *fmt); + } + ++fmt; + } + lwi->out_fn(lwi, '\0'); /* Output last zero number */ +#if LWPRINTF_CFG_OS && !LWPRINTF_CFG_OS_MANUAL_PROTECT + if (IS_PRINT_MODE(lwi)) { /* Mutex only for print operation */ + lwprintf_sys_mutex_release(&lwi->lwobj->mutex); + } +#endif /* LWPRINTF_CFG_OS && !LWPRINTF_CFG_OS_MANUAL_PROTECT */ + return 1; +} + +/** + * \brief Initialize LwPRINTF instance + * \param[in,out] lwobj: LwPRINTF working instance + * \param[in] out_fn: Output function used for print operation. + * When set to `NULL`, direct print to stream functions won't work + * and will return error if called by the application. + * Also, system mutex for this specific instance won't be called + * as system mutex isn't needed. All formatting functions (with print being an exception) + * are thread safe. Library utilizes stack-based variables + * \return `1` on success, `0` otherwise + */ +uint8_t +lwprintf_init_ex(lwprintf_t* lwobj, lwprintf_output_fn out_fn) { + LWPRINTF_GET_LWOBJ(lwobj)->out_fn = out_fn; + +#if LWPRINTF_CFG_OS + /* Create system mutex, but only if user selected to ever use print mode */ + if (out_fn != NULL + && (lwprintf_sys_mutex_isvalid(&LWPRINTF_GET_LWOBJ(lwobj)->mutex) + || !lwprintf_sys_mutex_create(&LWPRINTF_GET_LWOBJ(lwobj)->mutex))) { + return 0; + } +#endif /* LWPRINTF_CFG_OS */ + return 1; +} + +/** + * \brief Print formatted data from variable argument list to the output + * \param[in,out] lwobj: LwPRINTF instance. Set to `NULL` to use default instance + * \param[in] format: C string that contains the text to be written to output + * \param[in] arg: A value identifying a variable arguments list initialized with `va_start`. + * `va_list` is a special type defined in ``. + * \return The number of characters that would have been written if `n` had been sufficiently large, + * not counting the terminating null character. + */ +int +lwprintf_vprintf_ex(lwprintf_t* const lwobj, const char* format, va_list arg) { + lwprintf_int_t fobj = { + .lwobj = LWPRINTF_GET_LWOBJ(lwobj), + .out_fn = prv_out_fn_print, + .fmt = format, + .buff = NULL, + .buff_size = 0, + }; + /* For direct print, output function must be set by user */ + if (fobj.lwobj->out_fn == NULL) { + return 0; + } + if (prv_format(&fobj, arg)) { + return (int)fobj.n_len; + } + return 0; +} + +/** + * \brief Print formatted data to the output + * \param[in,out] lwobj: LwPRINTF instance. Set to `NULL` to use default instance + * \param[in] format: C string that contains the text to be written to output + * \param[in] ...: Optional arguments for format string + * \return The number of characters that would have been written if `n` had been sufficiently large, + * not counting the terminating null character. + */ +int +lwprintf_printf_ex(lwprintf_t* const lwobj, const char* format, ...) { + va_list valist; + int n_len; + + va_start(valist, format); + n_len = lwprintf_vprintf_ex(lwobj, format, valist); + va_end(valist); + + return n_len; +} + +/** + * \brief Write formatted data from variable argument list to sized buffer + * \param[in,out] lwobj: LwPRINTF instance. Set to `NULL` to use default instance + * \param[in] s_out: Pointer to a buffer where the resulting C-string is stored. + * The buffer should have a size of at least `n` characters + * \param[in] n_maxlen: Maximum number of bytes to be used in the buffer. + * The generated string has a length of at most `n - 1`, + * leaving space for the additional terminating null character + * \param[in] format: C string that contains a format string that follows the same specifications as format in printf + * \param[in] arg: A value identifying a variable arguments list initialized with `va_start`. + * `va_list` is a special type defined in ``. + * \return The number of characters that would have been written if `n` had been sufficiently large, + * not counting the terminating null character. + */ +int +lwprintf_vsnprintf_ex(lwprintf_t* const lwobj, char* s_out, size_t n_maxlen, const char* format, va_list arg) { + lwprintf_int_t fobj = { + .lwobj = LWPRINTF_GET_LWOBJ(lwobj), + .out_fn = prv_out_fn_write_buff, + .fmt = format, + .buff = s_out, + .buff_size = n_maxlen, + }; + if (prv_format(&fobj, arg)) { + return (int)fobj.n_len; + } + return 0; +} + +/** + * \brief Write formatted data from variable argument list to sized buffer + * \param[in,out] lwobj: LwPRINTF instance. Set to `NULL` to use default instance + * \param[in] s_out: Pointer to a buffer where the resulting C-string is stored. + * The buffer should have a size of at least `n` characters + * \param[in] n_maxlen: Maximum number of bytes to be used in the buffer. + * The generated string has a length of at most `n - 1`, + * leaving space for the additional terminating null character + * \param[in] format: C string that contains a format string that follows the same specifications as format in printf + * \param[in] ...: Optional arguments for format string + * \return The number of characters that would have been written if `n` had been sufficiently large, + * not counting the terminating null character. + */ +int +lwprintf_snprintf_ex(lwprintf_t* const lwobj, char* s_out, size_t n_maxlen, const char* format, ...) { + va_list valist; + int len; + + va_start(valist, format); + len = lwprintf_vsnprintf_ex(lwobj, s_out, n_maxlen, format, valist); + va_end(valist); + + return len; +} + +#if LWPRINTF_CFG_OS_MANUAL_PROTECT || __DOXYGEN__ + +/** + * \brief Manually enable mutual exclusion + * \param[in,out] lwobj: LwPRINTF instance. Set to `NULL` to use default instance + * \return `1` if protected, `0` otherwise + */ +uint8_t +lwprintf_protect_ex(lwprintf_t* const lwobj) { + lwprintf_t* obj = LWPRINTF_GET_LWOBJ(lwobj); + return obj->out_fn != NULL && lwprintf_sys_mutex_isvalid(&obj->mutex) && lwprintf_sys_mutex_wait(&obj->mutex); +} + +/** + * \brief Manually disable mutual exclusion + * \param[in,out] lwobj: LwPRINTF instance. Set to `NULL` to use default instance + * \return `1` if protection disabled, `0` otherwise + */ +uint8_t +lwprintf_unprotect_ex(lwprintf_t* const lwobj) { + lwprintf_t* obj = LWPRINTF_GET_LWOBJ(lwobj); + return obj->out_fn != NULL && lwprintf_sys_mutex_release(&obj->mutex); +} + +#endif /* LWPRINTF_CFG_OS_MANUAL_PROTECT || __DOXYGEN__ */ diff --git a/3rd-part/lwprintf/lwprintf.h b/3rd-part/lwprintf/lwprintf.h new file mode 100644 index 0000000..e19adb0 --- /dev/null +++ b/3rd-part/lwprintf/lwprintf.h @@ -0,0 +1,313 @@ +/** + * \file lwprintf.h + * \brief Lightweight stdio manager + */ + +/* + * Copyright (c) 2024 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwPRINTF - Lightweight stdio manager library. + * + * Author: Tilen MAJERLE + * Version: v1.0.5 + */ +#ifndef LWPRINTF_HDR_H +#define LWPRINTF_HDR_H + +#include +#include +#include +#include +#include "lwprintf_opt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \defgroup LWPRINTF Lightweight stdio manager + * \brief Lightweight stdio manager + * \{ + */ + +/** + * \brief Unused variable macro + * \param[in] x: Unused variable + */ +#define LWPRINTF_UNUSED(x) ((void)(x)) + +/** + * \brief Calculate size of statically allocated array + * \param[in] x: Input array + * \return Number of array elements + */ +#define LWPRINTF_ARRAYSIZE(x) (sizeof(x) / sizeof((x)[0])) + +/** + * \brief Forward declaration for LwPRINTF instance + */ +struct lwprintf; + +/** + * \brief Callback function for character output + * \param[in] ch: Character to print + * \param[in] lwobj: LwPRINTF instance + * \return `ch` on success, `0` to terminate further string processing + */ +typedef int (*lwprintf_output_fn)(int ch, struct lwprintf* lwobj); + +/** + * \brief LwPRINTF instance + */ +typedef struct lwprintf { + lwprintf_output_fn out_fn; /*!< Output function for direct print operations */ +#if LWPRINTF_CFG_OS || __DOXYGEN__ + LWPRINTF_CFG_OS_MUTEX_HANDLE mutex; /*!< OS mutex handle */ +#endif /* LWPRINTF_CFG_OS || __DOXYGEN__ */ +} lwprintf_t; + +uint8_t lwprintf_init_ex(lwprintf_t* lwobj, lwprintf_output_fn out_fn); +int lwprintf_vprintf_ex(lwprintf_t* const lwobj, const char* format, va_list arg); +int lwprintf_printf_ex(lwprintf_t* const lwobj, const char* format, ...); +int lwprintf_vsnprintf_ex(lwprintf_t* const lwobj, char* s, size_t n, const char* format, va_list arg); +int lwprintf_snprintf_ex(lwprintf_t* const lwobj, char* s, size_t n, const char* format, ...); +uint8_t lwprintf_protect_ex(lwprintf_t* const lwobj); +uint8_t lwprintf_unprotect_ex(lwprintf_t* const lwobj); + +/** + * \brief Write formatted data from variable argument list to sized buffer + * \param[in,out] lwobj: LwPRINTF instance. Set to `NULL` to use default instance + * \param[in] s: Pointer to a buffer where the resulting C-string is stored. + * The buffer should have a size of at least `n` characters + * \param[in] format: C string that contains a format string that follows the same specifications as format in printf + * \param[in] ...: Optional arguments for format string + * \return The number of characters that would have been written, + * not counting the terminating null character. + */ +#define lwprintf_sprintf_ex(lwobj, s, format, ...) lwprintf_snprintf_ex((lwobj), (s), SIZE_MAX, (format), ##__VA_ARGS__) + +/** + * \brief Initialize default LwPRINTF instance + * \param[in] out_fn: Output function used for print operation + * \return `1` on success, `0` otherwise + * \sa lwprintf_init_ex + */ +#define lwprintf_init(out_fn) lwprintf_init_ex(NULL, (out_fn)) + +/** + * \brief Print formatted data from variable argument list to the output with default LwPRINTF instance + * \param[in] format: C string that contains the text to be written to output + * \param[in] arg: A value identifying a variable arguments list initialized with `va_start`. + * `va_list` is a special type defined in ``. + * \return The number of characters that would have been written if `n` had been sufficiently large, + * not counting the terminating null character. + */ +#define lwprintf_vprintf(format, arg) lwprintf_vprintf_ex(NULL, (format), (arg)) + +/** + * \brief Print formatted data to the output with default LwPRINTF instance + * \param[in] format: C string that contains the text to be written to output + * \param[in] ...: Optional arguments for format string + * \return The number of characters that would have been written if `n` had been sufficiently large, + * not counting the terminating null character. + */ +#define lwprintf_printf(format, ...) lwprintf_printf_ex(NULL, (format), ##__VA_ARGS__) + +/** + * \brief Write formatted data from variable argument list to sized buffer with default LwPRINTF instance + * \param[in] s: Pointer to a buffer where the resulting C-string is stored. + * The buffer should have a size of at least `n` characters + * \param[in] n: Maximum number of bytes to be used in the buffer. + * The generated string has a length of at most `n - 1`, + * leaving space for the additional terminating null character + * \param[in] format: C string that contains a format string that follows the same specifications as format in printf + * \param[in] arg: A value identifying a variable arguments list initialized with `va_start`. + * `va_list` is a special type defined in ``. + * \return The number of characters that would have been written if `n` had been sufficiently large, + * not counting the terminating null character. + */ +#define lwprintf_vsnprintf(s, n, format, arg) lwprintf_vsnprintf_ex(NULL, (s), (n), (format), (arg)) + +/** + * \brief Write formatted data from variable argument list to sized buffer with default LwPRINTF instance + * \param[in] s: Pointer to a buffer where the resulting C-string is stored. + * The buffer should have a size of at least `n` characters + * \param[in] n: Maximum number of bytes to be used in the buffer. + * The generated string has a length of at most `n - 1`, + * leaving space for the additional terminating null character + * \param[in] format: C string that contains a format string that follows the same specifications as format in printf + * \param[in] ...: Optional arguments for format string + * \return The number of characters that would have been written if `n` had been sufficiently large, + * not counting the terminating null character. + */ +#define lwprintf_snprintf(s, n, format, ...) lwprintf_snprintf_ex(NULL, (s), (n), (format), ##__VA_ARGS__) + +/** + * \brief Write formatted data from variable argument list to sized buffer with default LwPRINTF instance + * \param[in] s: Pointer to a buffer where the resulting C-string is stored. + * The buffer should have a size of at least `n` characters + * \param[in] format: C string that contains a format string that follows the same specifications as format in printf + * \param[in] ...: Optional arguments for format string + * \return The number of characters that would have been written, + * not counting the terminating null character. + */ +#define lwprintf_sprintf(s, format, ...) lwprintf_sprintf_ex(NULL, (s), (format), ##__VA_ARGS__) + +/** + * \brief Manually enable mutual exclusion + * \return `1` if protected, `0` otherwise + */ +#define lwprintf_protect() lwprintf_protect_ex(NULL) + +/** + * \brief Manually disable mutual exclusion + * \return `1` if protected, `0` otherwise + */ +#define lwprintf_unprotect() lwprintf_unprotect_ex(NULL) + +#if LWPRINTF_CFG_ENABLE_SHORTNAMES || __DOXYGEN__ + +/** + * \copydoc lwprintf_printf + * \note This function is equivalent to \ref lwprintf_printf + * and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled + */ +#define lwprintf lwprintf_printf + +/** + * \copydoc lwprintf_vprintf + * \note This function is equivalent to \ref lwprintf_vprintf + * and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled + */ +#define lwvprintf lwprintf_vprintf + +/** + * \copydoc lwprintf_vsnprintf + * \note This function is equivalent to \ref lwprintf_vsnprintf + * and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled + */ +#define lwvsnprintf lwprintf_vsnprintf + +/** + * \copydoc lwprintf_snprintf + * \note This function is equivalent to \ref lwprintf_snprintf + * and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled + */ +#define lwsnprintf lwprintf_snprintf + +/** + * \copydoc lwprintf_sprintf + * \note This function is equivalent to \ref lwprintf_sprintf + * and available only if \ref LWPRINTF_CFG_ENABLE_SHORTNAMES is enabled + */ +#define lwsprintf lwprintf_sprintf + +#endif /* LWPRINTF_CFG_ENABLE_SHORTNAMES || __DOXYGEN__ */ + +#if LWPRINTF_CFG_ENABLE_STD_NAMES || __DOXYGEN__ + +/** + * \copydoc lwprintf_printf + * \note This function is equivalent to \ref lwprintf_printf + * and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled + */ +#define printf lwprintf_printf + +/** + * \copydoc lwprintf_vprintf + * \note This function is equivalent to \ref lwprintf_vprintf + * and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled + */ +#define vprintf lwprintf_vprintf + +/** + * \copydoc lwprintf_vsnprintf + * \note This function is equivalent to \ref lwprintf_vsnprintf + * and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled + */ +#define vsnprintf lwprintf_vsnprintf + +/** + * \copydoc lwprintf_snprintf + * \note This function is equivalent to \ref lwprintf_snprintf + * and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled + */ +#define snprintf lwprintf_snprintf + +/** + * \copydoc lwprintf_sprintf + * \note This function is equivalent to \ref lwprintf_sprintf + * and available only if \ref LWPRINTF_CFG_ENABLE_STD_NAMES is enabled + */ +#define sprintf lwprintf_sprintf + +#endif /* LWPRINTF_CFG_ENABLE_STD_NAMES || __DOXYGEN__ */ + +/* Debug module */ +#if !defined(NDEBUG) +/** + * \brief Debug output function + * + * Its purpose is to have a debug printout to the defined output, + * which will get disabled for the release build (when NDEBUG is defined). + * + * \note It calls \ref lwprintf_printf to execute the print + * \note Defined as empty when \ref NDEBUG is enabled + * \param[in] fmt: Format text + * \param[in] ...: Optional formatting parameters + */ +#define lwprintf_debug(fmt, ...) lwprintf_printf((fmt), ##__VA_ARGS__) +/** + * \brief Conditional debug output + * + * It prints the formatted text only if condition is true + * + * Its purpose is to have a debug printout to the defined output, + * which will get disabled for the release build (when NDEBUG is defined). + * + * \note It calls \ref lwprintf_debug to execute the print + * \note Defined as empty when \ref NDEBUG is enabled + * \param[in] cond: Condition to check before outputing the message + * \param[in] fmt: Format text + * \param[in] ...: Optional formatting parameters + */ +#define lwprintf_debug_cond(cond, fmt, ...) \ + do { \ + if ((cond)) { \ + lwprintf_debug((fmt), ##__VA_ARGS__) \ + } \ + } while (0) +#else +#define lwprintf_debug(fmt, ...) ((void)0) +#define lwprintf_debug_cond(cond, fmt, ...) ((void)0) +#endif + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LWPRINTF_HDR_H */ \ No newline at end of file diff --git a/3rd-part/lwprintf/lwprintf_opt.h b/3rd-part/lwprintf/lwprintf_opt.h new file mode 100644 index 0000000..8d36cbb --- /dev/null +++ b/3rd-part/lwprintf/lwprintf_opt.h @@ -0,0 +1,191 @@ +/** + * \file lwprintf_opt.h + * \brief LwPRINTF options + */ + +/* + * Copyright (c) 2024 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwPRINTF - Lightweight stdio manager library. + * + * Author: Tilen MAJERLE + * Version: v1.0.5 + */ +#ifndef LWPRINTF_OPT_HDR_H +#define LWPRINTF_OPT_HDR_H + +/* Uncomment to ignore user options (or set macro in compiler flags) */ +/* #define LWPRINTF_IGNORE_USER_OPTS */ + +/* Include application options */ +#ifndef LWPRINTF_IGNORE_USER_OPTS +#include "lwprintf_opts.h" +#endif /* LWPRINTF_IGNORE_USER_OPTS */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \defgroup LWPRINTF_OPT Configuration + * \brief LwPRINTF options + * \{ + */ + +/** + * \brief Enables `1` or disables `0` operating system support in the library + * + * \note When `LWPRINTF_CFG_OS` is enabled, user must implement functions in \ref LWPRINTF_SYS group. + */ +#ifndef LWPRINTF_CFG_OS +#define LWPRINTF_CFG_OS 0 +#endif + +/** + * \brief Mutex handle type + * + * \note This value must be set in case \ref LWPRINTF_CFG_OS is set to `1`. + * If data type is not known to compiler, include header file with + * definition before you define handle type + */ +#ifndef LWPRINTF_CFG_OS_MUTEX_HANDLE +#define LWPRINTF_CFG_OS_MUTEX_HANDLE void* +#endif + +/** + * \brief Enables `1` or disables `0` manual mutex lock. + * + * When this feature is enabled, together with \ref LWPRINTF_CFG_OS, behavior is as following: + * - System mutex is kept created during init phase + * - Calls to direct printing functions are not thread-safe by default anymore + * - Calls to sprintf (buffer functions) are kept thread-safe + * - User must manually call \ref lwprintf_protect or \ref lwprintf_protect_ex functions to protect direct printing operation + * - User must manually call \ref lwprintf_unprotect or \ref lwprintf_unprotect_ex functions to exit protected area + * + * \note If you prefer to completely disable locking mechanism with this library, + * turn off \ref LWPRINTF_CFG_OS and fully manually handle mutual exclusion for non-reentrant functions + */ +#ifndef LWPRINTF_CFG_OS_MANUAL_PROTECT +#define LWPRINTF_CFG_OS_MANUAL_PROTECT 0 +#endif + +/** + * \brief Enables `1` or disables `0` support for `long long int` type, signed or unsigned. + * + */ +#ifndef LWPRINTF_CFG_SUPPORT_LONG_LONG +#define LWPRINTF_CFG_SUPPORT_LONG_LONG 1 +#endif + +/** + * \brief Enables `1` or disables `0` support for any specifier accepting any kind of integer types. + * This is enabling `%d, %b, %u, %o, %i, %x` specifiers + * + */ +#ifndef LWPRINTF_CFG_SUPPORT_TYPE_INT +#define LWPRINTF_CFG_SUPPORT_TYPE_INT 1 +#endif + +/** + * \brief Enables `1` or disables `0` support `%p` pointer print type + * + * When enabled, architecture must support `uintptr_t` type, normally available with C11 standard + */ +#ifndef LWPRINTF_CFG_SUPPORT_TYPE_POINTER +#define LWPRINTF_CFG_SUPPORT_TYPE_POINTER 1 +#endif + +/** + * \brief Enables `1` or disables `0` support `%f` float type + * + */ +#ifndef LWPRINTF_CFG_SUPPORT_TYPE_FLOAT +#define LWPRINTF_CFG_SUPPORT_TYPE_FLOAT 1 +#endif + +/** + * \brief Enables `1` or disables `0` support for `%e` engineering output type for float numbers + * + * \note \ref LWPRINTF_CFG_SUPPORT_TYPE_FLOAT has to be enabled to use this feature + * + */ +#ifndef LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING +#define LWPRINTF_CFG_SUPPORT_TYPE_ENGINEERING 1 +#endif + +/** + * \brief Enables `1` or disables `0` support for `%s` for string output + * + */ +#ifndef LWPRINTF_CFG_SUPPORT_TYPE_STRING +#define LWPRINTF_CFG_SUPPORT_TYPE_STRING 1 +#endif + +/** + * \brief Enables `1` or disables `0` support for `%k` for hex byte array output + * + */ +#ifndef LWPRINTF_CFG_SUPPORT_TYPE_BYTE_ARRAY +#define LWPRINTF_CFG_SUPPORT_TYPE_BYTE_ARRAY 1 +#endif + +/** + * \brief Specifies default number of precision for floating number + * + * Represents number of digits to be used after comma if no precision + * is set with specifier itself + * + */ +#ifndef LWPRINTF_CFG_FLOAT_DEFAULT_PRECISION +#define LWPRINTF_CFG_FLOAT_DEFAULT_PRECISION 6 +#endif + +/** + * \brief Enables `1` or disables `0` optional short names for LwPRINTF API functions. + * + * It adds functions for default instance: `lwprintf`, `lwsnprintf` and others + */ +#ifndef LWPRINTF_CFG_ENABLE_SHORTNAMES +#define LWPRINTF_CFG_ENABLE_SHORTNAMES 1 +#endif /* LWPRINTF_CFG_ENABLE_SHORTNAMES */ + +/** + * \brief Enables `1` or disables `0` C standard API names + * + * Disabled by default not to interfere with compiler implementation. + * Application may need to remove standard C STDIO library from linkage + * to be able to properly compile LwPRINTF with this option enabled + */ +#ifndef LWPRINTF_CFG_ENABLE_STD_NAMES +#define LWPRINTF_CFG_ENABLE_STD_NAMES 0 +#endif /* LWPRINTF_CFG_ENABLE_SHORTNAMES */ + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LWPRINTF_OPT_HDR_H */ diff --git a/3rd-part/lwprintf/lwprintf_opts.h b/3rd-part/lwprintf/lwprintf_opts.h new file mode 100644 index 0000000..f67d9fe --- /dev/null +++ b/3rd-part/lwprintf/lwprintf_opts.h @@ -0,0 +1,44 @@ +/** + * \file lwprintf_opts_template.h + * \brief LwPRINTF configuration file + */ + +/* + * Copyright (c) 2024 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwPRINTF - Lightweight stdio manager library. + * + * Author: Tilen MAJERLE + * Version: v1.0.5 + */ +#ifndef LWPRINTF_OPTS_HDR_H +#define LWPRINTF_OPTS_HDR_H + +/* Rename this file to "lwprintf_opts.h" for your application */ + +/* + * Open "include/lwprintf/lwprintf_opt.h" and + * copy & replace here settings you want to change values + */ + +#endif /* LWPRINTF_OPTS_HDR_H */ diff --git a/BC5D-POS.ATWP b/BC5D-POS.ATWP new file mode 100644 index 0000000..f761ea6 --- /dev/null +++ b/BC5D-POS.ATWP @@ -0,0 +1,151 @@ + + + + AT32F425 + AT32F425C8T7 + LQFP48 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0;0;0 + 0;0;0 + 0;0;0 + 0;0;0 + 0;0;0 + 0;0;0 + 0;0;0 + 1;0;0 + 1;0;0 + 0;0;0 + 1;0;0 + + + 0 + 16.000000 + 0 + 0 + 0 + 6 + 1 + 96 + 8 + 1 + 1 + 1 + 1 + 2.0 + 1 + 0 + 0 + 1 + 4 + + + + + + + + + + + + + + + + + + + + + + + + BC5D-POS + C:/Users/ForgotDoge/Desktop/BC2024/firmware + MDK_V5 + true + 0x200 + 0x400 + false + V2.1.1 + + diff --git a/BC5D-POS.code-workspace b/BC5D-POS.code-workspace new file mode 100644 index 0000000..0829fea --- /dev/null +++ b/BC5D-POS.code-workspace @@ -0,0 +1,38 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "files.autoGuessEncoding": true, + "C_Cpp.default.configurationProvider": "cl.eide", + "C_Cpp.errorSquiggles": "disabled", + "files.associations": { + ".eideignore": "ignore", + "*.a51": "a51", + "*.h": "c", + "*.c": "c", + "*.hxx": "cpp", + "*.hpp": "cpp", + "*.c++": "cpp", + "*.cpp": "cpp", + "*.cxx": "cpp", + "*.cc": "cpp" + }, + "[yaml]": { + "editor.insertSpaces": true, + "editor.tabSize": 4, + "editor.autoIndent": "advanced" + }, + "workbench.colorCustomizations": { + "activityBar.background": "#14117C", + "titleBar.activeBackground": "#1D18AE", + "titleBar.activeForeground": "#FAFAFE" + }, + "EIDE.OpenOCD.ExePath": "D:/Program Files (x86)/at32_OpenOCD_V2.0.2/bin/openocd.exe", + "cortex-debug.variableUseNaturalFormat": true + }, + "extensions": { + } +} \ No newline at end of file diff --git a/app/by_can.c b/app/by_can.c new file mode 100644 index 0000000..3f18435 --- /dev/null +++ b/app/by_can.c @@ -0,0 +1,39 @@ +#include "by_can.h" + +#include +#include +#include "by_utils.h" +#include "by_debug.h" + +by_error_status by_can_send_stdd(uint32_t id, const uint8_t *data, uint8_t len, uint16_t timeout) +{ + + assert(id < 0x7FF); + + if (len > 8) { + len = 8; + } + + uint8_t transmit_mailbox; + can_tx_message_type tx_message_struct; + tx_message_struct.standard_id = id; /* 设置发送数据帧的 ID=0x400 */ + tx_message_struct.extended_id = 0; /* 不设置 */ + tx_message_struct.id_type = CAN_ID_STANDARD; /* 发送数据帧类型(标准/扩展):标准数据帧 */ + tx_message_struct.frame_type = CAN_TFT_DATA; /* 发送帧类型(远程/数据):数据帧 */ + tx_message_struct.dlc = len; /* 发送数据长度(0~8):8 */ + memcpy(tx_message_struct.data, data, len); /* 复制发送数据 */ + transmit_mailbox = can_message_transmit(CAN1, &tx_message_struct); /* 将以上待发送报文写入发送邮箱并请求发送 */ + + /* 等待该邮箱发送成功—对应邮箱发送成功标志置起 */ + while (can_transmit_status_get(CAN1, (can_tx_mailbox_num_type)transmit_mailbox) != CAN_TX_STATUS_SUCCESSFUL) { + // LOGD("CAN#SEND: timeout=%d", timeout); + if (0 == timeout--) { + LOGW("CAN#TIMEOUT: ID=0x%x", id); + + return BY_ERROR; + } + delay_us(10); + } + + return BY_SUCCESS; +} diff --git a/app/by_can.h b/app/by_can.h new file mode 100644 index 0000000..ae03c9c --- /dev/null +++ b/app/by_can.h @@ -0,0 +1,9 @@ +#ifndef _BY_CAN_H__ +#define _BY_CAN_H__ + +#include "at32f425.h" +#include "by_utils.h" + +by_error_status by_can_send_stdd(uint32_t id, const uint8_t *data, uint8_t len, uint16_t timeout); + +#endif \ No newline at end of file diff --git a/app/by_motion.c b/app/by_motion.c new file mode 100644 index 0000000..d66040d --- /dev/null +++ b/app/by_motion.c @@ -0,0 +1,261 @@ +#include "by_motion.h" + +#include "pid.h" +#include "by_utils.h" +#include "by_debug.h" + +#define DRV_ENABLE() gpio_bits_set(GPIOA, GPIO_PINS_12) +#define DRV_DISABLE() gpio_bits_reset(GPIOA, GPIO_PINS_12) + +#define MU (2.854f) // speed = \mu * speed_in_pulse + +by_motor_param param_m1; +by_motor_param param_m2; +PID_TypeDef pid_m1; +PID_TypeDef pid_m2; +uint8_t motion_enable_flag; +uint8_t motion_busy_flag; +uint8_t motion_reset_flag; +int16_t time_via; +float position_abs; + +void by_motion_set_pwm_m1(int32_t pwm_duty) +{ + pwm_duty = clip_s32(pwm_duty, -900, 900); // 不可以拉满哦 + + if (pwm_duty < 0) { + tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_3, -pwm_duty); + tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_4, 0); + } else { + tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_3, 0); + tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_4, pwm_duty); + } +} + +// void by_motion_set_pwm_m2(int32_t pwm_duty) +// { +// pwm_duty = clip_s32(pwm_duty, -900, 900); // 不可以拉满哦 + +// if (pwm_duty < 0) { +// tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_3, -pwm_duty); +// tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_4, 0); +// } else { +// tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_3, 0); +// tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_4, pwm_duty); +// } +// } + +int16_t by_motion_get_speed_m1(void) +{ +#define alpha (0.1f) + static float last_speed = 0.0f; + param_m1.real_speed = alpha * last_speed + (1.0f - alpha) * (float)(+1 * (int16_t)tmr_counter_value_get(TMR3)); + last_speed = param_m1.real_speed; + tmr_counter_value_set(TMR3, 0); + return (int16_t)param_m1.real_speed; +#undef alpha +} + +// int16_t by_motion_get_speed_m2(void) +// { +// #define alpha (0.1f) +// static float last_speed = 0.0f; +// param_m2.real_speed = alpha * last_speed + (1.0f - alpha) * (float)(-1 * (int16_t)tmr_counter_value_get(TMR3)); +// last_speed = param_m2.real_speed; +// tmr_counter_value_set(TMR3, 0); +// return (int16_t)param_m2.real_speed; +// #undef alpha +// } + +void by_motion_set_speed_m1(int16_t speed) +{ + param_m1.target_speed = speed; +} + +// void by_motion_set_speed_m2(int16_t speed) +// { +// param_m2.target_speed = speed; +// } + +void by_motion_set_distance(float distance, int16_t speed) +{ + // TODO 验证距离是否超限 + if (motion_busy_flag) { + return; + } + + if (speed < 0) { + speed = -speed; + } + + position_abs += distance; + + if (distance < 0.0f) { + by_motion_set_speed_m1(-1 * speed); + distance = -distance; + } else { + by_motion_set_speed_m1(speed); + } + + motion_busy_flag = 1; + time_via = (int16_t)(distance * 50.0f / ((float)speed * MU)); // 控制频率为 50Hz,控制值单位为 s + // lwprintf("time_via = %d\r\n", time_via); + LOGD("position_abs = %f\r\n", position_abs); +} + +void by_motion_set_distance2(float distance, int16_t speed) +{ + // TODO 验证距离是否超限 + if (motion_busy_flag) { + return; + } + + if (speed < 0) { + speed = -speed; + } + + if (distance < 0.0f) { + distance = -distance; + } + + distance = distance - position_abs; + position_abs += distance; + + if (5.0 >= position_abs) { + position_abs = 0; + by_motion_set_speed_m1(-10); + motion_busy_flag = 1; + motion_reset_flag = 1; + LOGD("RESET position_abs = %f\r\n", position_abs); + return; + } + + if (distance < 0.0f) { + distance = -distance; + by_motion_set_speed_m1(-1 * speed); + } else { + by_motion_set_speed_m1(speed); + } + + motion_busy_flag = 1; + time_via = (int16_t)(distance * 50.0f / ((float)speed * MU)); // 控制频率为 50Hz,控制值单位为 s + LOGD("position_abs = %f\r\n", position_abs); + // lwprintf("time_via = %d\r\n", time_via); +} + +void by_motion_init(void) +{ + motion_enable_flag = 0; + motion_busy_flag = 0; + time_via = 0; + position_abs = 0.0f; // TODO 待添加复位操作 + + by_motion_set_pwm_m1(0); + // by_motion_set_pwm_m2(0); + + /* set default parameters */ + param_m1.Kp = BY_MOTION_DEFAULT_KP_M1; + param_m1.Ki = BY_MOTION_DEFAULT_KI_M1; + param_m1.Kd = BY_MOTION_DEFAULT_KD_M1; + // param_m2.Kp = BY_MOTION_DEFAULT_KP_M2; + // param_m2.Ki = BY_MOTION_DEFAULT_KI_M2; + // param_m2.Kd = BY_MOTION_DEFAULT_KD_M2; + + /* load parameters form ee */ + // TODO + + PID(&pid_m1, ¶m_m1.real_speed, ¶m_m1.out_pwm, ¶m_m1.target_speed, param_m1.Kp, param_m1.Ki, param_m1.Kd, _PID_P_ON_E, _PID_CD_DIRECT); + PID_SetMode(&pid_m1, _PID_MODE_AUTOMATIC); + PID_SetSampleTime(&pid_m1, 20); + PID_SetOutputLimits(&pid_m1, -900, 900); + + // PID(&pid_m2, ¶m_m2.real_speed, ¶m_m2.out_pwm, ¶m_m2.target_speed, param_m2.Kp, param_m2.Ki, param_m2.Kd, _PID_P_ON_E, _PID_CD_DIRECT); + // PID_SetMode(&pid_m2, _PID_MODE_AUTOMATIC); + // PID_SetSampleTime(&pid_m2, 10); + // PID_SetOutputLimits(&pid_m2, -400, 400); + + motion_enable_flag = 1; + DRV_ENABLE(); + + // 上电回零 + by_motion_set_speed_m1(-20); + while (SET == gpio_input_data_bit_read(GPIOB, GPIO_PINS_4)) { + lwprintf("%f, %f, %f\r\n", param_m1.real_speed, param_m1.target_speed, param_m1.out_pwm); + // 等待复位 + } + by_motion_set_speed_m1(0); + by_motion_set_distance2(100, 20); +} + +void by_motion_run(void) +{ + if (motion_enable_flag) { + by_motion_get_speed_m1(); + // by_motion_get_speed_m2(); + + PID_Compute(&pid_m1); + // PID_Compute(&pid_m2); + + by_motion_set_pwm_m1((int32_t)param_m1.out_pwm); + // by_motion_set_pwm_m2((int32_t)param_m2.out_pwm); + } +} + +void by_motion_can_handle(uint16_t stdd_id, const uint8_t *data, uint8_t len) +{ + + if (0x08 == stdd_id) { + uint8_t mode = data[0]; + int16_t speed = (int16_t)data[1]; + // float distance = (float)(data[2] | (data[3] << 8) | (data[4] << 16) | (data[5] << 24)); + float distance; + memcpy(&distance, &data[2], 4); + if (0 == mode) { + by_motion_set_distance2(distance, speed); + } else if (1 == mode) { + by_motion_set_distance(distance, speed); + } + } + + // #define BC2D_MODEL1 + + // if (0x01 == stdd_id) { + // #if defined(BC2D_MODEL1) + // int16_t speed_m1_temp = (int16_t)(data[0] | (data[1] << 8)); + // int16_t speed_m2_temp = (int16_t)(data[2] | (data[3] << 8)); + // by_motion_set_speed_m1(speed_m1_temp); + // by_motion_set_speed_m2(speed_m2_temp); + // #elif defined(BC2D_MODEL2) + // int16_t speed_m1_temp = (int16_t)(data[4] | (data[5] << 8)); + // int16_t speed_m2_temp = (int16_t)(data[6] | (data[7] << 8)); + // by_motion_set_speed_m1(speed_m1_temp); + // by_motion_set_speed_m2(speed_m2_temp); + // #endif + // } + + LOGD("m1:%f,%f,%f", param_m1.real_speed, param_m1.target_speed, param_m1.out_pwm); + LOGD("m2:%f,%f,%f", param_m2.real_speed, param_m2.target_speed, param_m2.out_pwm); +} + +void by_motion_tmr_handle(void) +{ + if (!motion_busy_flag) { + return; + } + + if (motion_reset_flag) { + if (!gpio_input_data_bit_read(GPIOB, GPIO_PINS_4)) { + motion_reset_flag = 0; + motion_busy_flag = 0; + by_motion_set_speed_m1(0); + } + return; + } + + if (time_via > 0) { + time_via--; + } else { + by_motion_set_speed_m1(0); + motion_busy_flag = 0; + } +} \ No newline at end of file diff --git a/app/by_motion.h b/app/by_motion.h new file mode 100644 index 0000000..08d081a --- /dev/null +++ b/app/by_motion.h @@ -0,0 +1,36 @@ +#ifndef _BY_MOTION_H__ +#define _BY_MOTION_H__ + +#include "at32f425.h" + +typedef struct by_motor_param { + float Kp; + float Ki; + float Kd; + float real_speed; + float target_speed; + float out_pwm; +} by_motor_param; + +#define BY_MOTION_DEFAULT_KP_M1 (5.0f) +#define BY_MOTION_DEFAULT_KI_M1 (600.0f) +#define BY_MOTION_DEFAULT_KD_M1 (0.0f) +#define BY_MOTION_DEFAULT_KP_M2 (5.0f) +#define BY_MOTION_DEFAULT_KI_M2 (100.0f) +#define BY_MOTION_DEFAULT_KD_M2 (0.0f) + +extern void by_motion_init(void); +extern void by_motion_run(void); +extern void by_motion_set_pwm_m1(int32_t pwm_duty); +extern void by_motion_set_pwm_m2(int32_t pwm_duty); +extern int16_t by_motion_get_speed_m1(void); +extern int16_t by_motion_get_speed_m2(void); +extern void by_motion_set_speed_m1(int16_t speed); +extern void by_motion_set_speed_m2(int16_t speed); +extern void by_motion_can_handle(uint16_t stdd_id, const uint8_t *data, uint8_t len); +extern void by_motion_tmr_handle(void); + +extern by_motor_param param_m1; +extern by_motor_param param_m2; + +#endif diff --git a/app/by_utils.c b/app/by_utils.c new file mode 100644 index 0000000..7e89e69 --- /dev/null +++ b/app/by_utils.c @@ -0,0 +1,7 @@ +#include "by_utils.h" + +inline int32_t clip_s32(int32_t x, int32_t low, int32_t up) +{ + return (x > up ? up : x < low ? low + : x); +} diff --git a/app/by_utils.h b/app/by_utils.h new file mode 100644 index 0000000..68985f8 --- /dev/null +++ b/app/by_utils.h @@ -0,0 +1,23 @@ +#ifndef _BY_UTILS_H__ +#define _BY_UTILS_H__ + +#include "at32f425.h" + +typedef enum { + BY_ERROR = 0, + BY_SUCCESS = !BY_ERROR +} by_error_status; + +typedef enum { + T_U8 = 0, + T_U16, + T_U32, + T_S8, + T_S16, + T_S32, + T_F32 +} by_data_type; + +int32_t clip_s32(int32_t x, int32_t low, int32_t up); + +#endif \ No newline at end of file diff --git a/libraries/cmsis/cm4/core_support/arm_common_tables.h b/libraries/cmsis/cm4/core_support/arm_common_tables.h new file mode 100644 index 0000000..721b18d --- /dev/null +++ b/libraries/cmsis/cm4/core_support/arm_common_tables.h @@ -0,0 +1,517 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_common_tables.h + * Description: Extern declaration for common tables + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + /* Double Precision Float CFFT twiddles */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREV_1024) + extern const uint16_t armBitRevTable[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_16) + extern const uint64_t twiddleCoefF64_16[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_32) + extern const uint64_t twiddleCoefF64_32[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_64) + extern const uint64_t twiddleCoefF64_64[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_128) + extern const uint64_t twiddleCoefF64_128[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_256) + extern const uint64_t twiddleCoefF64_256[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_512) + extern const uint64_t twiddleCoefF64_512[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_1024) + extern const uint64_t twiddleCoefF64_1024[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_2048) + extern const uint64_t twiddleCoefF64_2048[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F64_4096) + extern const uint64_t twiddleCoefF64_4096[8192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) + extern const float32_t twiddleCoef_16[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_32) + extern const float32_t twiddleCoef_32[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) + extern const float32_t twiddleCoef_64[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_128) + extern const float32_t twiddleCoef_128[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) + extern const float32_t twiddleCoef_256[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_512) + extern const float32_t twiddleCoef_512[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) + extern const float32_t twiddleCoef_1024[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048) + extern const float32_t twiddleCoef_2048[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) + extern const float32_t twiddleCoef_4096[8192]; + #define twiddleCoef twiddleCoef_4096 + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) + extern const q31_t twiddleCoef_16_q31[24]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32) + extern const q31_t twiddleCoef_32_q31[48]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) + extern const q31_t twiddleCoef_64_q31[96]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128) + extern const q31_t twiddleCoef_128_q31[192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) + extern const q31_t twiddleCoef_256_q31[384]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512) + extern const q31_t twiddleCoef_512_q31[768]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) + extern const q31_t twiddleCoef_1024_q31[1536]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048) + extern const q31_t twiddleCoef_2048_q31[3072]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) + extern const q31_t twiddleCoef_4096_q31[6144]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) + extern const q15_t twiddleCoef_16_q15[24]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32) + extern const q15_t twiddleCoef_32_q15[48]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) + extern const q15_t twiddleCoef_64_q15[96]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128) + extern const q15_t twiddleCoef_128_q15[192]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) + extern const q15_t twiddleCoef_256_q15[384]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512) + extern const q15_t twiddleCoef_512_q15[768]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) + extern const q15_t twiddleCoef_1024_q15[1536]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048) + extern const q15_t twiddleCoef_2048_q15[3072]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) + extern const q15_t twiddleCoef_4096_q15[6144]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + /* Double Precision Float RFFT twiddles */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_32) + extern const uint64_t twiddleCoefF64_rfft_32[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_64) + extern const uint64_t twiddleCoefF64_rfft_64[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_128) + extern const uint64_t twiddleCoefF64_rfft_128[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_256) + extern const uint64_t twiddleCoefF64_rfft_256[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_512) + extern const uint64_t twiddleCoefF64_rfft_512[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_1024) + extern const uint64_t twiddleCoefF64_rfft_1024[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_2048) + extern const uint64_t twiddleCoefF64_rfft_2048[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F64_4096) + extern const uint64_t twiddleCoefF64_rfft_4096[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_32) + extern const float32_t twiddleCoef_rfft_32[32]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_64) + extern const float32_t twiddleCoef_rfft_64[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_128) + extern const float32_t twiddleCoef_rfft_128[128]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_256) + extern const float32_t twiddleCoef_rfft_256[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_512) + extern const float32_t twiddleCoef_rfft_512[512]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_1024) + extern const float32_t twiddleCoef_rfft_1024[1024]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_2048) + extern const float32_t twiddleCoef_rfft_2048[2048]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_RFFT_F32_4096) + extern const float32_t twiddleCoef_rfft_4096[4096]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + /* Double precision floating-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_16) + #define ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH ((uint16_t)12) + extern const uint16_t armBitRevIndexTableF64_16[ARMBITREVINDEXTABLEF64_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_32) + #define ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH ((uint16_t)24) + extern const uint16_t armBitRevIndexTableF64_32[ARMBITREVINDEXTABLEF64_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_64) + #define ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTableF64_64[ARMBITREVINDEXTABLEF64_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_128) + #define ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH ((uint16_t)112) + extern const uint16_t armBitRevIndexTableF64_128[ARMBITREVINDEXTABLEF64_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_256) + #define ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH ((uint16_t)240) + extern const uint16_t armBitRevIndexTableF64_256[ARMBITREVINDEXTABLEF64_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_512) + #define ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH ((uint16_t)480) + extern const uint16_t armBitRevIndexTableF64_512[ARMBITREVINDEXTABLEF64_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_1024) + #define ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH ((uint16_t)992) + extern const uint16_t armBitRevIndexTableF64_1024[ARMBITREVINDEXTABLEF64_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_2048) + #define ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH ((uint16_t)1984) + extern const uint16_t armBitRevIndexTableF64_2048[ARMBITREVINDEXTABLEF64_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT64_4096) + #define ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTableF64_4096[ARMBITREVINDEXTABLEF64_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + /* floating-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_16) + #define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) + extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_32) + #define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) + extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_64) + #define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_128) + #define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) + extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_256) + #define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) + extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_512) + #define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) + extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_1024) + #define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) + extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_2048) + #define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) + extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FLT_4096) + #define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + + /* fixed-point bit reversal tables */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_16) + #define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) + extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_32) + #define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) + extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_64) + #define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) + extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_128) + #define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) + extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_256) + #define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) + extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_512) + #define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) + extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_1024) + #define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) + extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_2048) + #define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) + extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_BITREVIDX_FXT_4096) + #define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_F32) + extern const float32_t realCoefA[8192]; + extern const float32_t realCoefB[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q31) + extern const q31_t realCoefAQ31[8192]; + extern const q31_t realCoefBQ31[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_REALCOEF_Q15) + extern const q15_t realCoefAQ15[8192]; + extern const q15_t realCoefBQ15[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_128) + extern const float32_t Weights_128[256]; + extern const float32_t cos_factors_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_512) + extern const float32_t Weights_512[1024]; + extern const float32_t cos_factors_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_2048) + extern const float32_t Weights_2048[4096]; + extern const float32_t cos_factors_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_F32_8192) + extern const float32_t Weights_8192[16384]; + extern const float32_t cos_factors_8192[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_128) + extern const q15_t WeightsQ15_128[256]; + extern const q15_t cos_factorsQ15_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_512) + extern const q15_t WeightsQ15_512[1024]; + extern const q15_t cos_factorsQ15_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_2048) + extern const q15_t WeightsQ15_2048[4096]; + extern const q15_t cos_factorsQ15_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q15_8192) + extern const q15_t WeightsQ15_8192[16384]; + extern const q15_t cos_factorsQ15_8192[8192]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_128) + extern const q31_t WeightsQ31_128[256]; + extern const q31_t cos_factorsQ31_128[128]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_512) + extern const q31_t WeightsQ31_512[1024]; + extern const q31_t cos_factorsQ31_512[512]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_2048) + extern const q31_t WeightsQ31_2048[4096]; + extern const q31_t cos_factorsQ31_2048[2048]; + #endif + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_DCT4_Q31_8192) + extern const q31_t WeightsQ31_8192[16384]; + extern const q31_t cos_factorsQ31_8192[8192]; + #endif + +#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_TABLES) */ + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_ALLOW_TABLES) + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q15) + extern const q15_t armRecipTableQ15[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_RECIP_Q31) + extern const q31_t armRecipTableQ31[64]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + /* Tables for Fast Math Sine and Cosine */ + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_F32) + extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q31) + extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_SIN_Q15) + extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + + #if defined(ARM_MATH_MVEI) + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q31_MVE) + extern const q31_t sqrtTable_Q31[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + #endif + + #if defined(ARM_MATH_MVEI) + #if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q15_MVE) + extern const q15_t sqrtTable_Q15[256]; + #endif /* !defined(ARM_DSP_CONFIG_TABLES) defined(ARM_ALL_FAST_TABLES) */ + #endif + +#endif /* if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FAST_TABLES) */ + +#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) + extern const float32_t exp_tab[8]; + extern const float32_t __logf_lut_f32[8]; +#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) */ + +#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) +extern const unsigned char hwLUT[256]; +#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */ + +#endif /* ARM_COMMON_TABLES_H */ + diff --git a/libraries/cmsis/cm4/core_support/arm_const_structs.h b/libraries/cmsis/cm4/core_support/arm_const_structs.h new file mode 100644 index 0000000..83984c4 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/arm_const_structs.h @@ -0,0 +1,76 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_const_structs.h + * Description: Constant structs that are initialized for user convenience. + * For example, some can be given as arguments to the arm_cfft_f32() function. + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len16; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len32; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len64; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len128; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len256; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len512; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len1024; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len2048; + extern const arm_cfft_instance_f64 arm_cfft_sR_f64_len4096; + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/libraries/cmsis/cm4/core_support/arm_helium_utils.h b/libraries/cmsis/cm4/core_support/arm_helium_utils.h new file mode 100644 index 0000000..8568857 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/arm_helium_utils.h @@ -0,0 +1,348 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_helium_utils.h + * Description: Utility functions for Helium development + * + * $Date: 09. September 2019 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_UTILS_HELIUM_H_ +#define _ARM_UTILS_HELIUM_H_ + +/*************************************** + +Definitions available for MVEF and MVEI + +***************************************/ +#if defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) || defined(ARM_MATH_MVEI) + +#define INACTIVELANE 0 /* inactive lane content */ + + +#endif /* defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) || defined(ARM_MATH_MVEI) */ + +/*************************************** + +Definitions available for MVEF only + +***************************************/ +#if defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) + +__STATIC_FORCEINLINE float32_t vecAddAcrossF32Mve(float32x4_t in) +{ + float32_t acc; + + acc = vgetq_lane(in, 0) + vgetq_lane(in, 1) + + vgetq_lane(in, 2) + vgetq_lane(in, 3); + + return acc; +} + +/* newton initial guess */ +#define INVSQRT_MAGIC_F32 0x5f3759df + +#define INVSQRT_NEWTON_MVE_F32(invSqrt, xHalf, xStart)\ +{ \ + float32x4_t tmp; \ + \ + /* tmp = xhalf * x * x */ \ + tmp = vmulq(xStart, xStart); \ + tmp = vmulq(tmp, xHalf); \ + /* (1.5f - xhalf * x * x) */ \ + tmp = vsubq(vdupq_n_f32(1.5f), tmp); \ + /* x = x*(1.5f-xhalf*x*x); */ \ + invSqrt = vmulq(tmp, xStart); \ +} +#endif /* defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) */ + +/*************************************** + +Definitions available for MVEI only + +***************************************/ +#if defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEI) + + +#include "arm_common_tables.h" + +/* Following functions are used to transpose matrix in f32 and q31 cases */ +__STATIC_INLINE arm_status arm_mat_trans_32bit_2x2_mve( + uint32_t * pDataSrc, + uint32_t * pDataDest) +{ + static const uint32x4_t vecOffs = { 0, 2, 1, 3 }; + /* + * + * | 0 1 | => | 0 2 | + * | 2 3 | | 1 3 | + * + */ + uint32x4_t vecIn = vldrwq_u32((uint32_t const *)pDataSrc); + vstrwq_scatter_shifted_offset_u32(pDataDest, vecOffs, vecIn); + + return (ARM_MATH_SUCCESS); +} + +__STATIC_INLINE arm_status arm_mat_trans_32bit_3x3_mve( + uint32_t * pDataSrc, + uint32_t * pDataDest) +{ + const uint32x4_t vecOffs1 = { 0, 3, 6, 1}; + const uint32x4_t vecOffs2 = { 4, 7, 2, 5}; + /* + * + * | 0 1 2 | | 0 3 6 | 4 x 32 flattened version | 0 3 6 1 | + * | 3 4 5 | => | 1 4 7 | => | 4 7 2 5 | + * | 6 7 8 | | 2 5 8 | (row major) | 8 . . . | + * + */ + uint32x4_t vecIn1 = vldrwq_u32((uint32_t const *) pDataSrc); + uint32x4_t vecIn2 = vldrwq_u32((uint32_t const *) &pDataSrc[4]); + + vstrwq_scatter_shifted_offset_u32(pDataDest, vecOffs1, vecIn1); + vstrwq_scatter_shifted_offset_u32(pDataDest, vecOffs2, vecIn2); + + pDataDest[8] = pDataSrc[8]; + + return (ARM_MATH_SUCCESS); +} + +__STATIC_INLINE arm_status arm_mat_trans_32bit_4x4_mve(uint32_t * pDataSrc, uint32_t * pDataDest) +{ + /* + * 4x4 Matrix transposition + * is 4 x de-interleave operation + * + * 0 1 2 3 0 4 8 12 + * 4 5 6 7 1 5 9 13 + * 8 9 10 11 2 6 10 14 + * 12 13 14 15 3 7 11 15 + */ + + uint32x4x4_t vecIn; + + vecIn = vld4q((uint32_t const *) pDataSrc); + vstrwq(pDataDest, vecIn.val[0]); + pDataDest += 4; + vstrwq(pDataDest, vecIn.val[1]); + pDataDest += 4; + vstrwq(pDataDest, vecIn.val[2]); + pDataDest += 4; + vstrwq(pDataDest, vecIn.val[3]); + + return (ARM_MATH_SUCCESS); +} + + +__STATIC_INLINE arm_status arm_mat_trans_32bit_generic_mve( + uint16_t srcRows, + uint16_t srcCols, + uint32_t * pDataSrc, + uint32_t * pDataDest) +{ + uint32x4_t vecOffs; + uint32_t i; + uint32_t blkCnt; + uint32_t const *pDataC; + uint32_t *pDataDestR; + uint32x4_t vecIn; + + vecOffs = vidupq_u32((uint32_t)0, 1); + vecOffs = vecOffs * srcCols; + + i = srcCols; + do + { + pDataC = (uint32_t const *) pDataSrc; + pDataDestR = pDataDest; + + blkCnt = srcRows >> 2; + while (blkCnt > 0U) + { + vecIn = vldrwq_gather_shifted_offset_u32(pDataC, vecOffs); + vstrwq(pDataDestR, vecIn); + pDataDestR += 4; + pDataC = pDataC + srcCols * 4; + /* + * Decrement the blockSize loop counter + */ + blkCnt--; + } + + /* + * tail + */ + blkCnt = srcRows & 3; + if (blkCnt > 0U) + { + mve_pred16_t p0 = vctp32q(blkCnt); + vecIn = vldrwq_gather_shifted_offset_u32(pDataC, vecOffs); + vstrwq_p(pDataDestR, vecIn, p0); + } + + pDataSrc += 1; + pDataDest += srcRows; + } + while (--i); + + return (ARM_MATH_SUCCESS); +} + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q31_MVE) +__STATIC_INLINE q31x4_t FAST_VSQRT_Q31(q31x4_t vecIn) +{ + q63x2_t vecTmpLL; + q31x4_t vecTmp0, vecTmp1; + q31_t scale; + q63_t tmp64; + q31x4_t vecNrm, vecDst, vecIdx, vecSignBits; + + + vecSignBits = vclsq(vecIn); + vecSignBits = vbicq(vecSignBits, 1); + /* + * in = in << no_of_sign_bits; + */ + vecNrm = vshlq(vecIn, vecSignBits); + /* + * index = in >> 24; + */ + vecIdx = vecNrm >> 24; + vecIdx = vecIdx << 1; + + vecTmp0 = vldrwq_gather_shifted_offset_s32(sqrtTable_Q31, vecIdx); + + vecIdx = vecIdx + 1; + + vecTmp1 = vldrwq_gather_shifted_offset_s32(sqrtTable_Q31, vecIdx); + + vecTmp1 = vqrdmulhq(vecTmp1, vecNrm); + vecTmp0 = vecTmp0 - vecTmp1; + vecTmp1 = vqrdmulhq(vecTmp0, vecTmp0); + vecTmp1 = vqrdmulhq(vecNrm, vecTmp1); + vecTmp1 = vdupq_n_s32(0x18000000) - vecTmp1; + vecTmp0 = vqrdmulhq(vecTmp0, vecTmp1); + vecTmpLL = vmullbq_int(vecNrm, vecTmp0); + + /* + * scale elements 0, 2 + */ + scale = 26 + (vecSignBits[0] >> 1); + tmp64 = asrl(vecTmpLL[0], scale); + vecDst[0] = (q31_t) tmp64; + + scale = 26 + (vecSignBits[2] >> 1); + tmp64 = asrl(vecTmpLL[1], scale); + vecDst[2] = (q31_t) tmp64; + + vecTmpLL = vmulltq_int(vecNrm, vecTmp0); + + /* + * scale elements 1, 3 + */ + scale = 26 + (vecSignBits[1] >> 1); + tmp64 = asrl(vecTmpLL[0], scale); + vecDst[1] = (q31_t) tmp64; + + scale = 26 + (vecSignBits[3] >> 1); + tmp64 = asrl(vecTmpLL[1], scale); + vecDst[3] = (q31_t) tmp64; + /* + * set negative values to 0 + */ + vecDst = vdupq_m(vecDst, 0, vcmpltq_n_s32(vecIn, 0)); + + return vecDst; +} +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FAST_TABLES) || defined(ARM_TABLE_FAST_SQRT_Q15_MVE) +__STATIC_INLINE q15x8_t FAST_VSQRT_Q15(q15x8_t vecIn) +{ + q31x4_t vecTmpLev, vecTmpLodd, vecSignL; + q15x8_t vecTmp0, vecTmp1; + q15x8_t vecNrm, vecDst, vecIdx, vecSignBits; + + vecDst = vuninitializedq_s16(); + + vecSignBits = vclsq(vecIn); + vecSignBits = vbicq(vecSignBits, 1); + /* + * in = in << no_of_sign_bits; + */ + vecNrm = vshlq(vecIn, vecSignBits); + + vecIdx = vecNrm >> 8; + vecIdx = vecIdx << 1; + + vecTmp0 = vldrhq_gather_shifted_offset_s16(sqrtTable_Q15, vecIdx); + + vecIdx = vecIdx + 1; + + vecTmp1 = vldrhq_gather_shifted_offset_s16(sqrtTable_Q15, vecIdx); + + vecTmp1 = vqrdmulhq(vecTmp1, vecNrm); + vecTmp0 = vecTmp0 - vecTmp1; + vecTmp1 = vqrdmulhq(vecTmp0, vecTmp0); + vecTmp1 = vqrdmulhq(vecNrm, vecTmp1); + vecTmp1 = vdupq_n_s16(0x1800) - vecTmp1; + vecTmp0 = vqrdmulhq(vecTmp0, vecTmp1); + + vecSignBits = vecSignBits >> 1; + + vecTmpLev = vmullbq_int(vecNrm, vecTmp0); + vecTmpLodd = vmulltq_int(vecNrm, vecTmp0); + + vecTmp0 = vecSignBits + 10; + /* + * negate sign to apply register based vshl + */ + vecTmp0 = -vecTmp0; + + /* + * shift even elements + */ + vecSignL = vmovlbq(vecTmp0); + vecTmpLev = vshlq(vecTmpLev, vecSignL); + /* + * shift odd elements + */ + vecSignL = vmovltq(vecTmp0); + vecTmpLodd = vshlq(vecTmpLodd, vecSignL); + /* + * merge and narrow odd and even parts + */ + vecDst = vmovnbq_s32(vecDst, vecTmpLev); + vecDst = vmovntq_s32(vecDst, vecTmpLodd); + /* + * set negative values to 0 + */ + vecDst = vdupq_m(vecDst, 0, vcmpltq_n_s16(vecIn, 0)); + + return vecDst; +} +#endif + +#endif /* defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEI) */ + +#endif diff --git a/libraries/cmsis/cm4/core_support/arm_math.h b/libraries/cmsis/cm4/core_support/arm_math.h new file mode 100644 index 0000000..2483e6e --- /dev/null +++ b/libraries/cmsis/cm4/core_support/arm_math.h @@ -0,0 +1,8970 @@ +/****************************************************************************** + * @file arm_math.h + * @brief Public header file for CMSIS DSP Library + * @version V1.7.0 + * @date 18. March 2019 + ******************************************************************************/ +/* + * Copyright (c) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M and Cortex-A processor + * based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filtering functions + * - Matrix functions + * - Transform functions + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * - Support Vector Machine functions (SVM) + * - Bayes classifier functions + * - Distance functions + * + * The library has generally separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * + * Here is the list of pre-built libraries : + * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) + * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) + * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) + * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) + * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) + * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) + * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) + * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) + * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) + * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) + * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) + * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) + * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) + * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) + * - arm_ARMv8MBLl_math.lib (Armv8-M Baseline, Little endian) + * - arm_ARMv8MMLl_math.lib (Armv8-M Mainline, Little endian) + * - arm_ARMv8MMLlfsp_math.lib (Armv8-M Mainline, Little endian, Single Precision Floating Point Unit) + * - arm_ARMv8MMLld_math.lib (Armv8-M Mainline, Little endian, DSP instructions) + * - arm_ARMv8MMLldfsp_math.lib (Armv8-M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library is now tested on Fast Models building with cmake. + * Core M0, M7, A5 are tested. + * + * + * + * Building the Library + * ------------ + * + * The library installer contains a project file to rebuild libraries on MDK toolchain in the CMSIS\\DSP\\Projects\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional preprocessor macros detailed above. + * + * There is also a work in progress cmake build. The README file is giving more details. + * + * Preprocessor Macros + * ------------ + * + * Each library project have different preprocessor macros. + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_LOOPUNROLL: + * + * Define macro ARM_MATH_LOOPUNROLL to enable manual loop unrolling in DSP functions + * + * - ARM_MATH_NEON: + * + * Define macro ARM_MATH_NEON to enable Neon versions of the DSP functions. + * It is not enabled by default when Neon is available because performances are + * dependent on the compiler and target architecture. + * + * - ARM_MATH_NEON_EXPERIMENTAL: + * + * Define macro ARM_MATH_NEON_EXPERIMENTAL to enable experimental Neon versions of + * of some DSP functions. Experimental Neon versions currently do not have better + * performances than the scalar versions. + * + * - ARM_MATH_HELIUM: + * + * It implies the flags ARM_MATH_MVEF and ARM_MATH_MVEI and ARM_MATH_FLOAT16. + * + * - ARM_MATH_MVEF: + * + * Select Helium versions of the f32 algorithms. + * It implies ARM_MATH_FLOAT16 and ARM_MATH_MVEI. + * + * - ARM_MATH_MVEI: + * + * Select Helium versions of the int and fixed point algorithms. + * + * - ARM_MATH_FLOAT16: + * + * Float16 implementations of some algorithms (Requires MVE extension). + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |---------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP\\DSP_Lib_TestSuite | DSP_Lib test suite | + * |\b CMSIS\\DSP\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP\\Include | DSP_Lib include files | + * |\b CMSIS\\DSP\\Lib | DSP_Lib binaries | + * |\b CMSIS\\DSP\\Projects | Projects to rebuild DSP_Lib binaries | + * |\b CMSIS\\DSP\\Source | DSP_Lib source files | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to \ref arm_mat_init_f32(), \ref arm_mat_init_q31() and \ref arm_mat_init_q15() + * for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ + +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ + +/** + * @defgroup groupSVM SVM Functions + * This set of functions is implementing SVM classification on 2 classes. + * The training must be done from scikit-learn. The parameters can be easily + * generated from the scikit-learn object. Some examples are given in + * DSP/Testing/PatternGeneration/SVM.py + * + * If more than 2 classes are needed, the functions in this folder + * will have to be used, as building blocks, to do multi-class classification. + * + * No multi-class classification is provided in this SVM folder. + * + */ + + +/** + * @defgroup groupBayes Bayesian estimators + * + * Implement the naive gaussian Bayes estimator. + * The training must be done from scikit-learn. + * + * The parameters can be easily + * generated from the scikit-learn object. Some examples are given in + * DSP/Testing/PatternGeneration/Bayes.py + */ + +/** + * @defgroup groupDistance Distance functions + * + * Distance functions for use with clustering algorithms. + * There are distance functions for float vectors and boolean vectors. + * + */ + + +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" + #pragma GCC diagnostic ignored "-Wunused-parameter" + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#elif defined ( _MSC_VER ) + +#else + #error Unknown compiler +#endif + + +/* Included for instrinsics definitions */ +#if defined (_MSC_VER ) +#include +#define __STATIC_FORCEINLINE static __forceinline +#define __STATIC_INLINE static __inline +#define __ALIGNED(x) __declspec(align(x)) + +#elif defined (__GNUC_PYTHON__) +#include +#define __ALIGNED(x) __attribute__((aligned(x))) +#define __STATIC_FORCEINLINE static __attribute__((inline)) +#define __STATIC_INLINE static __attribute__((inline)) +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wattributes" + +#else +#include "cmsis_compiler.h" +#endif + + + +#include +#include +#include +#include + + +#define F64_MAX ((float64_t)DBL_MAX) +#define F32_MAX ((float32_t)FLT_MAX) + +#if defined(ARM_MATH_FLOAT16) +#define F16_MAX ((float16_t)FLT_MAX) +#endif + +#define F64_MIN (-DBL_MAX) +#define F32_MIN (-FLT_MAX) + +#if defined(ARM_MATH_FLOAT16) +#define F16_MIN (-(float16_t)FLT_MAX) +#endif + +#define F64_ABSMAX ((float64_t)DBL_MAX) +#define F32_ABSMAX ((float32_t)FLT_MAX) + +#if defined(ARM_MATH_FLOAT16) +#define F16_ABSMAX ((float16_t)FLT_MAX) +#endif + +#define F64_ABSMIN ((float64_t)0.0) +#define F32_ABSMIN ((float32_t)0.0) + +#if defined(ARM_MATH_FLOAT16) +#define F16_ABSMIN ((float16_t)0.0) +#endif + +#define Q31_MAX ((q31_t)(0x7FFFFFFFL)) +#define Q15_MAX ((q15_t)(0x7FFF)) +#define Q7_MAX ((q7_t)(0x7F)) +#define Q31_MIN ((q31_t)(0x80000000L)) +#define Q15_MIN ((q15_t)(0x8000)) +#define Q7_MIN ((q7_t)(0x80)) + +#define Q31_ABSMAX ((q31_t)(0x7FFFFFFFL)) +#define Q15_ABSMAX ((q15_t)(0x7FFF)) +#define Q7_ABSMAX ((q7_t)(0x7F)) +#define Q31_ABSMIN ((q31_t)0) +#define Q15_ABSMIN ((q15_t)0) +#define Q7_ABSMIN ((q7_t)0) + +/* evaluate ARM DSP feature */ +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + #define ARM_MATH_DSP 1 +#endif + +#if defined(ARM_MATH_NEON) +#include +#endif + +#if defined (ARM_MATH_HELIUM) + #define ARM_MATH_MVEF + #define ARM_MATH_FLOAT16 +#endif + +#if defined (ARM_MATH_MVEF) + #define ARM_MATH_MVEI + #define ARM_MATH_FLOAT16 +#endif + +#if defined (ARM_MATH_HELIUM) || defined(ARM_MATH_MVEF) || defined(ARM_MATH_MVEI) +#include +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 ((q31_t)(0x100)) +#define DELTA_Q15 ((q15_t)0x5) +#define INDEX_MASK 0x0000003F +#ifndef PI + #define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macros for complex numbers + */ + + /* Dimension C vector space */ + #define CMPLX_DIM 2 + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Input matrix is singular and cannot be inverted */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief vector types + */ +#if defined(ARM_MATH_NEON) || defined (ARM_MATH_MVEI) + /** + * @brief 64-bit fractional 128-bit vector data type in 1.63 format + */ + typedef int64x2_t q63x2_t; + + /** + * @brief 32-bit fractional 128-bit vector data type in 1.31 format. + */ + typedef int32x4_t q31x4_t; + + /** + * @brief 16-bit fractional 128-bit vector data type with 16-bit alignement in 1.15 format. + */ + typedef __ALIGNED(2) int16x8_t q15x8_t; + + /** + * @brief 8-bit fractional 128-bit vector data type with 8-bit alignement in 1.7 format. + */ + typedef __ALIGNED(1) int8x16_t q7x16_t; + + /** + * @brief 32-bit fractional 128-bit vector pair data type in 1.31 format. + */ + typedef int32x4x2_t q31x4x2_t; + + /** + * @brief 32-bit fractional 128-bit vector quadruplet data type in 1.31 format. + */ + typedef int32x4x4_t q31x4x4_t; + + /** + * @brief 16-bit fractional 128-bit vector pair data type in 1.15 format. + */ + typedef int16x8x2_t q15x8x2_t; + + /** + * @brief 16-bit fractional 128-bit vector quadruplet data type in 1.15 format. + */ + typedef int16x8x4_t q15x8x4_t; + + /** + * @brief 8-bit fractional 128-bit vector pair data type in 1.7 format. + */ + typedef int8x16x2_t q7x16x2_t; + + /** + * @brief 8-bit fractional 128-bit vector quadruplet data type in 1.7 format. + */ + typedef int8x16x4_t q7x16x4_t; + + /** + * @brief 32-bit fractional data type in 9.23 format. + */ + typedef int32_t q23_t; + + /** + * @brief 32-bit fractional 128-bit vector data type in 9.23 format. + */ + typedef int32x4_t q23x4_t; + + /** + * @brief 64-bit status 128-bit vector data type. + */ + typedef int64x2_t status64x2_t; + + /** + * @brief 32-bit status 128-bit vector data type. + */ + typedef int32x4_t status32x4_t; + + /** + * @brief 16-bit status 128-bit vector data type. + */ + typedef int16x8_t status16x8_t; + + /** + * @brief 8-bit status 128-bit vector data type. + */ + typedef int8x16_t status8x16_t; + + +#endif + +#if defined(ARM_MATH_NEON) || defined(ARM_MATH_MVEF) /* floating point vector*/ + /** + * @brief 32-bit floating-point 128-bit vector type + */ + typedef float32x4_t f32x4_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit floating-point 128-bit vector data type + */ + typedef __ALIGNED(2) float16x8_t f16x8_t; +#endif + + /** + * @brief 32-bit floating-point 128-bit vector pair data type + */ + typedef float32x4x2_t f32x4x2_t; + + /** + * @brief 32-bit floating-point 128-bit vector quadruplet data type + */ + typedef float32x4x4_t f32x4x4_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit floating-point 128-bit vector pair data type + */ + typedef float16x8x2_t f16x8x2_t; + + /** + * @brief 16-bit floating-point 128-bit vector quadruplet data type + */ + typedef float16x8x4_t f16x8x4_t; +#endif + + /** + * @brief 32-bit ubiquitous 128-bit vector data type + */ + typedef union _any32x4_t + { + float32x4_t f; + int32x4_t i; + } any32x4_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit ubiquitous 128-bit vector data type + */ + typedef union _any16x8_t + { + float16x8_t f; + int16x8_t i; + } any16x8_t; +#endif + +#endif + +#if defined(ARM_MATH_NEON) + /** + * @brief 32-bit fractional 64-bit vector data type in 1.31 format. + */ + typedef int32x2_t q31x2_t; + + /** + * @brief 16-bit fractional 64-bit vector data type in 1.15 format. + */ + typedef __ALIGNED(2) int16x4_t q15x4_t; + + /** + * @brief 8-bit fractional 64-bit vector data type in 1.7 format. + */ + typedef __ALIGNED(1) int8x8_t q7x8_t; + + /** + * @brief 32-bit float 64-bit vector data type. + */ + typedef float32x2_t f32x2_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit float 64-bit vector data type. + */ + typedef __ALIGNED(2) float16x4_t f16x4_t; +#endif + + /** + * @brief 32-bit floating-point 128-bit vector triplet data type + */ + typedef float32x4x3_t f32x4x3_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit floating-point 128-bit vector triplet data type + */ + typedef float16x8x3_t f16x8x3_t; +#endif + + /** + * @brief 32-bit fractional 128-bit vector triplet data type in 1.31 format + */ + typedef int32x4x3_t q31x4x3_t; + + /** + * @brief 16-bit fractional 128-bit vector triplet data type in 1.15 format + */ + typedef int16x8x3_t q15x8x3_t; + + /** + * @brief 8-bit fractional 128-bit vector triplet data type in 1.7 format + */ + typedef int8x16x3_t q7x16x3_t; + + /** + * @brief 32-bit floating-point 64-bit vector pair data type + */ + typedef float32x2x2_t f32x2x2_t; + + /** + * @brief 32-bit floating-point 64-bit vector triplet data type + */ + typedef float32x2x3_t f32x2x3_t; + + /** + * @brief 32-bit floating-point 64-bit vector quadruplet data type + */ + typedef float32x2x4_t f32x2x4_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit floating-point 64-bit vector pair data type + */ + typedef float16x4x2_t f16x4x2_t; + + /** + * @brief 16-bit floating-point 64-bit vector triplet data type + */ + typedef float16x4x3_t f16x4x3_t; + + /** + * @brief 16-bit floating-point 64-bit vector quadruplet data type + */ + typedef float16x4x4_t f16x4x4_t; +#endif + + /** + * @brief 32-bit fractional 64-bit vector pair data type in 1.31 format + */ + typedef int32x2x2_t q31x2x2_t; + + /** + * @brief 32-bit fractional 64-bit vector triplet data type in 1.31 format + */ + typedef int32x2x3_t q31x2x3_t; + + /** + * @brief 32-bit fractional 64-bit vector quadruplet data type in 1.31 format + */ + typedef int32x4x3_t q31x2x4_t; + + /** + * @brief 16-bit fractional 64-bit vector pair data type in 1.15 format + */ + typedef int16x4x2_t q15x4x2_t; + + /** + * @brief 16-bit fractional 64-bit vector triplet data type in 1.15 format + */ + typedef int16x4x2_t q15x4x3_t; + + /** + * @brief 16-bit fractional 64-bit vector quadruplet data type in 1.15 format + */ + typedef int16x4x3_t q15x4x4_t; + + /** + * @brief 8-bit fractional 64-bit vector pair data type in 1.7 format + */ + typedef int8x8x2_t q7x8x2_t; + + /** + * @brief 8-bit fractional 64-bit vector triplet data type in 1.7 format + */ + typedef int8x8x3_t q7x8x3_t; + + /** + * @brief 8-bit fractional 64-bit vector quadruplet data type in 1.7 format + */ + typedef int8x8x4_t q7x8x4_t; + + /** + * @brief 32-bit ubiquitous 64-bit vector data type + */ + typedef union _any32x2_t + { + float32x2_t f; + int32x2_t i; + } any32x2_t; + +#if defined(ARM_MATH_FLOAT16) + /** + * @brief 16-bit ubiquitous 64-bit vector data type + */ + typedef union _any16x4_t + { + float16x4_t f; + int16x4_t i; + } any16x4_t; +#endif + + /** + * @brief 32-bit status 64-bit vector data type. + */ + typedef int32x4_t status32x2_t; + + /** + * @brief 16-bit status 64-bit vector data type. + */ + typedef int16x8_t status16x4_t; + + /** + * @brief 8-bit status 64-bit vector data type. + */ + typedef int8x16_t status8x8_t; + +#endif + + + +/** + @brief definition to read/write two 16 bit values. + @deprecated + */ +#if defined ( __CC_ARM ) + #define __SIMD32_TYPE int32_t __packed +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define __SIMD32_TYPE int32_t +#elif defined ( __GNUC__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __ICCARM__ ) + #define __SIMD32_TYPE int32_t __packed +#elif defined ( __TI_ARM__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __CSMC__ ) + #define __SIMD32_TYPE int32_t +#elif defined ( __TASKING__ ) + #define __SIMD32_TYPE __un(aligned) int32_t +#elif defined(_MSC_VER ) + #define __SIMD32_TYPE int32_t +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ( (__SIMD32_TYPE * ) (addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE * ) (addr)) +#define __SIMD64(addr) (*( int64_t **) & (addr)) + +#define STEP(x) (x) <= 0 ? 0 : 1 +#define SQ(x) ((x) * (x)) + +/* SIMD replacement */ + + +/** + @brief Read 2 Q15 from Q15 pointer. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2 ( + q15_t * pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, pQ15, 4); +#else + val = (pQ15[1] << 16) | (pQ15[0] & 0x0FFFF) ; +#endif + + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_ia ( + q15_t ** pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ15, 4); +#else + val = ((*pQ15)[1] << 16) | ((*pQ15)[0] & 0x0FFFF); +#endif + + *pQ15 += 2; + return (val); +} + +/** + @brief Read 2 Q15 from Q15 pointer and decrement pointer afterwards. + @param[in] pQ15 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q15x2_da ( + q15_t ** pQ15) +{ + q31_t val; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ15, 4); +#else + val = ((*pQ15)[1] << 16) | ((*pQ15)[0] & 0x0FFFF); +#endif + + *pQ15 -= 2; + return (val); +} + +/** + @brief Write 2 Q15 to Q15 pointer and increment pointer afterwards. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2_ia ( + q15_t ** pQ15, + q31_t value) +{ + q31_t val = value; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (*pQ15, &val, 4); +#else + (*pQ15)[0] = (val & 0x0FFFF); + (*pQ15)[1] = (val >> 16) & 0x0FFFF; +#endif + + *pQ15 += 2; +} + +/** + @brief Write 2 Q15 to Q15 pointer. + @param[in] pQ15 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q15x2 ( + q15_t * pQ15, + q31_t value) +{ + q31_t val = value; + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (pQ15, &val, 4); +#else + pQ15[0] = val & 0x0FFFF; + pQ15[1] = val >> 16; +#endif +} + + +/** + @brief Read 4 Q7 from Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_ia ( + q7_t ** pQ7) +{ + q31_t val; + + +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ7, 4); +#else + val =(((*pQ7)[3] & 0x0FF) << 24) | (((*pQ7)[2] & 0x0FF) << 16) | (((*pQ7)[1] & 0x0FF) << 8) | ((*pQ7)[0] & 0x0FF); +#endif + + *pQ7 += 4; + + return (val); +} + +/** + @brief Read 4 Q7 from Q7 pointer and decrement pointer afterwards. + @param[in] pQ7 points to input value + @return Q31 value + */ +__STATIC_FORCEINLINE q31_t read_q7x4_da ( + q7_t ** pQ7) +{ + q31_t val; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (&val, *pQ7, 4); +#else + val = ((((*pQ7)[3]) & 0x0FF) << 24) | ((((*pQ7)[2]) & 0x0FF) << 16) | ((((*pQ7)[1]) & 0x0FF) << 8) | ((*pQ7)[0] & 0x0FF); +#endif + *pQ7 -= 4; + + return (val); +} + +/** + @brief Write 4 Q7 to Q7 pointer and increment pointer afterwards. + @param[in] pQ7 points to input value + @param[in] value Q31 value + @return none + */ +__STATIC_FORCEINLINE void write_q7x4_ia ( + q7_t ** pQ7, + q31_t value) +{ + q31_t val = value; +#ifdef __ARM_FEATURE_UNALIGNED + memcpy (*pQ7, &val, 4); +#else + (*pQ7)[0] = val & 0x0FF; + (*pQ7)[1] = (val >> 8) & 0x0FF; + (*pQ7)[2] = (val >> 16) & 0x0FF; + (*pQ7)[3] = (val >> 24) & 0x0FF; + +#endif + *pQ7 += 4; +} + +/* + +Normally those kind of definitions are in a compiler file +in Core or Core_A. + +But for MSVC compiler it is a bit special. The goal is very specific +to CMSIS-DSP and only to allow the use of this library from other +systems like Python or Matlab. + +MSVC is not going to be used to cross-compile to ARM. So, having a MSVC +compiler file in Core or Core_A would not make sense. + +*/ +#if defined ( _MSC_VER ) || defined(__GNUC_PYTHON__) + __STATIC_FORCEINLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#ifndef ARM_MATH_DSP + /** + * @brief definition to pack two 16 bit values. + */ + #define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) + #define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) +#endif + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + #define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + #define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + __STATIC_FORCEINLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + __STATIC_FORCEINLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + __STATIC_FORCEINLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + __STATIC_FORCEINLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + __STATIC_FORCEINLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y) ) ); + } + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + __STATIC_FORCEINLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + const q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if (in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1U); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + __STATIC_FORCEINLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + const q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if (in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + +/** + * @brief Integer exponentiation + * @param[in] x value + * @param[in] nb integer exponent >= 1 + * @return x^nb + * + */ +__STATIC_INLINE float32_t arm_exponent_f32(float32_t x, int32_t nb) +{ + float32_t r = x; + nb --; + while(nb > 0) + { + r = r * x; + nb--; + } + return(r); +} + +/** + * @brief 64-bit to 32-bit unsigned normalization + * @param[in] in is input unsigned long long value + * @param[out] normalized is the 32-bit normalized value + * @param[out] norm is norm scale + */ +__STATIC_INLINE void arm_norm_64_to_32u(uint64_t in, int32_t * normalized, int32_t *norm) +{ + int32_t n1; + int32_t hi = (int32_t) (in >> 32); + int32_t lo = (int32_t) ((in << 32) >> 32); + + n1 = __CLZ(hi) - 32; + if (!n1) + { + /* + * input fits in 32-bit + */ + n1 = __CLZ(lo); + if (!n1) + { + /* + * MSB set, need to scale down by 1 + */ + *norm = -1; + *normalized = (((uint32_t) lo) >> 1); + } else + { + if (n1 == 32) + { + /* + * input is zero + */ + *norm = 0; + *normalized = 0; + } else + { + /* + * 32-bit normalization + */ + *norm = n1 - 1; + *normalized = lo << *norm; + } + } + } else + { + /* + * input fits in 64-bit + */ + n1 = 1 - n1; + *norm = -n1; + /* + * 64 bit normalization + */ + *normalized = (((uint32_t) lo) >> n1) | (hi << (32 - n1)); + } +} + +__STATIC_INLINE q31_t arm_div_q63_to_q31(q63_t num, q31_t den) +{ + q31_t result; + uint64_t absNum; + int32_t normalized; + int32_t norm; + + /* + * if sum fits in 32bits + * avoid costly 64-bit division + */ + absNum = num > 0 ? num : -num; + arm_norm_64_to_32u(absNum, &normalized, &norm); + if (norm > 0) + /* + * 32-bit division + */ + result = (q31_t) num / den; + else + /* + * 64-bit division + */ + result = (q31_t) (num / den); + + return result; +} + + +/* + * @brief C custom defined intrinsic functions + */ +#if !defined (ARM_MATH_DSP) + + /* + * @brief C custom defined QADD8 + */ + __STATIC_FORCEINLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 + */ + __STATIC_FORCEINLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 + */ + __STATIC_FORCEINLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 + */ + __STATIC_FORCEINLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 + */ + __STATIC_FORCEINLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 + */ + __STATIC_FORCEINLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX + */ + __STATIC_FORCEINLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX + */ + __STATIC_FORCEINLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX + */ + __STATIC_FORCEINLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX + */ + __STATIC_FORCEINLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX + */ + __STATIC_FORCEINLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX + */ + __STATIC_FORCEINLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD + */ + __STATIC_FORCEINLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB + */ + __STATIC_FORCEINLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD + */ + __STATIC_FORCEINLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX + */ + __STATIC_FORCEINLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX + */ + __STATIC_FORCEINLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD + */ + __STATIC_FORCEINLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX + */ + __STATIC_FORCEINLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD + */ + __STATIC_FORCEINLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD + */ + __STATIC_FORCEINLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 + */ + __STATIC_FORCEINLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + + /* + * @brief C custom defined SMMLA + */ + __STATIC_FORCEINLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) + { + return (sum + (int32_t) (((int64_t) x * y) >> 32)); + } + +#endif /* !defined (ARM_MATH_DSP) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q15 FIR filter (fast version). + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns either + * ARM_MATH_SUCCESS if initialization was successful or + * ARM_MATH_ARGUMENT_ERROR if numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q31 FIR filter (fast version). + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + /** + * @brief Instance structure for the modified Biquad coefs required by vectorized code. + */ + typedef struct + { + float32_t coeffs[8][4]; /**< Points to the array of modified coefficients. The array is of length 32. There is one per stage */ + } arm_biquad_mod_coef_f32; +#endif + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + const q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pCoeffsMod points to the modified filter coefficients (only MVE version). + * @param[in] pState points to the state buffer. + */ +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + void arm_biquad_cascade_df1_mve_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + arm_biquad_mod_coef_f32 * pCoeffsMod, + float32_t * pState); +#endif + + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise AND of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_and_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise OR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_or_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u16( + const uint16_t * pSrc, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u32( + const uint32_t * pSrc, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise NOT of a fixed-point vector. + * @param[in] pSrc points to input vector + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_not_u8( + const uint8_t * pSrc, + uint8_t * pDst, + uint32_t blockSize); + +/** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u16( + const uint16_t * pSrcA, + const uint16_t * pSrcB, + uint16_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u32( + const uint32_t * pSrcA, + const uint32_t * pSrcB, + uint32_t * pDst, + uint32_t blockSize); + + /** + * @brief Compute the logical bitwise XOR of two fixed-point vectors. + * @param[in] pSrcA points to input vector A + * @param[in] pSrcB points to input vector B + * @param[out] pDst points to output vector + * @param[in] blockSize number of samples in each vector + * @return none + */ + void arm_xor_u8( + const uint8_t * pSrcA, + const uint8_t * pSrcB, + uint8_t * pDst, + uint32_t blockSize); + + /** + * @brief Struct for specifying sorting algorithm + */ + typedef enum + { + ARM_SORT_BITONIC = 0, + /**< Bitonic sort */ + ARM_SORT_BUBBLE = 1, + /**< Bubble sort */ + ARM_SORT_HEAP = 2, + /**< Heap sort */ + ARM_SORT_INSERTION = 3, + /**< Insertion sort */ + ARM_SORT_QUICK = 4, + /**< Quick sort */ + ARM_SORT_SELECTION = 5 + /**< Selection sort */ + } arm_sort_alg; + + /** + * @brief Struct for specifying sorting algorithm + */ + typedef enum + { + ARM_SORT_DESCENDING = 0, + /**< Descending order (9 to 0) */ + ARM_SORT_ASCENDING = 1 + /**< Ascending order (0 to 9) */ + } arm_sort_dir; + + /** + * @brief Instance structure for the sorting algorithms. + */ + typedef struct + { + arm_sort_alg alg; /**< Sorting algorithm selected */ + arm_sort_dir dir; /**< Sorting order (direction) */ + } arm_sort_instance_f32; + + /** + * @param[in] S points to an instance of the sorting structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_sort_f32( + const arm_sort_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @param[in,out] S points to an instance of the sorting structure. + * @param[in] alg Selected algorithm. + * @param[in] dir Sorting order. + */ + void arm_sort_init_f32( + arm_sort_instance_f32 * S, + arm_sort_alg alg, + arm_sort_dir dir); + + /** + * @brief Instance structure for the sorting algorithms. + */ + typedef struct + { + arm_sort_dir dir; /**< Sorting order (direction) */ + float32_t * buffer; /**< Working buffer */ + } arm_merge_sort_instance_f32; + + /** + * @param[in] S points to an instance of the sorting structure. + * @param[in,out] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_merge_sort_f32( + const arm_merge_sort_instance_f32 * S, + float32_t *pSrc, + float32_t *pDst, + uint32_t blockSize); + + /** + * @param[in,out] S points to an instance of the sorting structure. + * @param[in] dir Sorting order. + * @param[in] buffer Working buffer. + */ + void arm_merge_sort_init_f32( + arm_merge_sort_instance_f32 * S, + arm_sort_dir dir, + float32_t * buffer); + + /** + * @brief Struct for specifying cubic spline type + */ + typedef enum + { + ARM_SPLINE_NATURAL = 0, /**< Natural spline */ + ARM_SPLINE_PARABOLIC_RUNOUT = 1 /**< Parabolic runout spline */ + } arm_spline_type; + + /** + * @brief Instance structure for the floating-point cubic spline interpolation. + */ + typedef struct + { + arm_spline_type type; /**< Type (boundary conditions) */ + const float32_t * x; /**< x values */ + const float32_t * y; /**< y values */ + uint32_t n_x; /**< Number of known data points */ + float32_t * coeffs; /**< Coefficients buffer (b,c, and d) */ + } arm_spline_instance_f32; + + /** + * @brief Processing function for the floating-point cubic spline interpolation. + * @param[in] S points to an instance of the floating-point spline structure. + * @param[in] xq points to the x values ot the interpolated data points. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples of output data. + */ + void arm_spline_f32( + arm_spline_instance_f32 * S, + const float32_t * xq, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point cubic spline interpolation. + * @param[in,out] S points to an instance of the floating-point spline structure. + * @param[in] type type of cubic spline interpolation (boundary conditions) + * @param[in] x points to the x values of the known data points. + * @param[in] y points to the y values of the known data points. + * @param[in] n number of known data points. + * @param[in] coeffs coefficients array for b, c, and d + * @param[in] tempBuffer buffer array for internal computations + */ + void arm_spline_init_f32( + arm_spline_instance_f32 * S, + arm_spline_type type, + const float32_t * x, + const float32_t * y, + uint32_t n, + float32_t * coeffs, + float32_t * tempBuffer); + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ +arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ +void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#if !defined (ARM_MATH_DSP) + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEI) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const q15_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const q15_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const q15_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_q15; + +arm_status arm_cfft_init_q15( + arm_cfft_instance_q15 * S, + uint16_t fftLen); + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEI) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const q31_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const q31_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const q31_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_q31; + +arm_status arm_cfft_init_q31( + arm_cfft_instance_q31 * S, + uint16_t fftLen); + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + const uint32_t *rearranged_twiddle_tab_stride1_arr; /**< Per stage reordered twiddle pointer (offset 1) */ \ + const uint32_t *rearranged_twiddle_tab_stride2_arr; /**< Per stage reordered twiddle pointer (offset 2) */ \ + const uint32_t *rearranged_twiddle_tab_stride3_arr; /**< Per stage reordered twiddle pointer (offset 3) */ \ + const float32_t *rearranged_twiddle_stride1; /**< reordered twiddle offset 1 storage */ \ + const float32_t *rearranged_twiddle_stride2; /**< reordered twiddle offset 2 storage */ \ + const float32_t *rearranged_twiddle_stride3; +#endif + } arm_cfft_instance_f32; + + + arm_status arm_cfft_init_f32( + arm_cfft_instance_f32 * S, + uint16_t fftLen); + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + + /** + * @brief Instance structure for the Double Precision Floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float64_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f64; + + void arm_cfft_f64( + const arm_cfft_instance_f64 * S, + float64_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ +#if defined(ARM_MATH_MVEI) + arm_cfft_instance_q15 cfftInst; +#else + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ +#endif + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ +#if defined(ARM_MATH_MVEI) + arm_cfft_instance_q31 cfftInst; +#else + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ +#endif + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + const float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + const float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the Double Precision Floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f64 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + const float64_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f64 ; + +arm_status arm_rfft_fast_init_f64 ( + arm_rfft_fast_instance_f64 * S, + uint16_t fftLen); + + +void arm_rfft_fast_f64( + arm_rfft_fast_instance_f64 * S, + float64_t * p, float64_t * pOut, + uint8_t ifftFlag); + + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + const float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + + + void arm_rfft_fast_f32( + const arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + const float32_t *pTwiddle; /**< points to the twiddle factor table. */ + const float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + const q31_t *pTwiddle; /**< points to the twiddle factor table. */ + const q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + const q15_t *pTwiddle; /**< points to the twiddle factor table. */ + const q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + const float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + const q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + const q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + const q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + const q7_t * pSrcA, + const q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + const q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + const q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + const q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + const float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + const q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + const q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + const q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + const q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + +/** + @brief Instance structure for floating-point FIR decimator. + */ +typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + +/** + @brief Processing function for floating-point FIR decimator. + @param[in] S points to an instance of the floating-point FIR decimator structure + @param[in] pSrc points to the block of input data + @param[out] pDst points to the block of output data + @param[in] blockSize number of samples to process + */ +void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + +/** + @brief Initialization function for the floating-point FIR decimator. + @param[in,out] S points to an instance of the floating-point FIR decimator structure + @param[in] numTaps number of coefficients in the filter + @param[in] M decimation factor + @param[in] pCoeffs points to the filter coefficients + @param[in] pState points to the state buffer + @param[in] blockSize number of input samples to process per call + @return execution status + - \ref ARM_MATH_SUCCESS : Operation successful + - \ref ARM_MATH_LENGTH_ERROR : blockSize is not a multiple of M + */ +arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + const arm_fir_decimate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + const q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + const float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + const float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + const float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + +#if defined(ARM_MATH_NEON) +void arm_biquad_cascade_df2T_compute_coefs_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs); +#endif + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + const float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + const q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + const q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + const float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + const float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + const q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + const q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + const q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + const float32_t * pSrcA, + uint32_t srcALen, + const float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + +/** + @brief Correlation of Q15 sequences + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. +*/ +void arm_correlate_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + +/** + @brief Correlation of Q15 sequences. + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + */ +void arm_correlate_fast_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + +/** + @brief Correlation of Q15 sequences (fast version). + @param[in] pSrcA points to the first input sequence. + @param[in] srcALen length of the first input sequence. + @param[in] pSrcB points to the second input sequence. + @param[in] srcBLen length of the second input sequence. + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ +void arm_correlate_fast_opt_q15( + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + +/** + @brief Correlation of Q31 sequences (fast version). + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ +void arm_correlate_fast_q31( + const q31_t * pSrcA, + uint32_t srcALen, + const q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + const q7_t * pSrcA, + uint32_t srcALen, + const q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + const q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + const float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + const float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + const q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + const q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + const q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + const q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + const q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + const q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd
+   * 
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return processed output sample. + */ + __STATIC_FORCEINLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + +/** + @brief Process function for the Q31 PID Control. + @param[in,out] S points to an instance of the Q31 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using an internal 64-bit accumulator. + The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + Thus, if the accumulator result overflows it wraps around rather than clip. + In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ +__STATIC_FORCEINLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31U); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + +/** + @brief Process function for the Q15 PID Control. + @param[in,out] S points to an instance of the Q15 PID Control structure + @param[in] in input sample to process + @return processed output sample. + + \par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ +__STATIC_FORCEINLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#if defined (ARM_MATH_DSP) + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)read_q15x2 (S->state), (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((q31_t)(acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @return none + */ + __STATIC_FORCEINLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + +/** + @brief Clarke transform for Q31 version + @param[in] Ia input three-phase coordinate a + @param[in] Ib input three-phase coordinate b + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * @return none + */ + __STATIC_FORCEINLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + +/** + @brief Inverse Clarke transform for Q31 version + @param[in] Ialpha input two-phase orthogonal vector axis alpha + @param[in] Ibeta input two-phase orthogonal vector axis beta + @param[out] pIa points to output three-phase coordinate a + @param[out] pIb points to output three-phase coordinate b + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + * + * The function implements the forward Park transform. + * + */ + __STATIC_FORCEINLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + +/** + @brief Park transform for Q31 version + @param[in] Ialpha input two-phase vector coordinate alpha + @param[in] Ibeta input two-phase vector coordinate beta + @param[out] pId points to output rotor reference frame d + @param[out] pIq points to output rotor reference frame q + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + \par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none + */ + __STATIC_FORCEINLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + +/** + @brief Inverse Park transform for Q31 version + @param[in] Id input coordinate of rotor reference frame d + @param[in] Iq input coordinate of rotor reference frame q + @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + @param[out] pIbeta points to output two-phase orthogonal vector axis beta + @param[in] sinVal sine value of rotation angle theta + @param[in] cosVal cosine value of rotation angle theta + @return none + + @par Scaling and Overflow Behavior + The function is implemented using an internal 32-bit accumulator. + The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + There is saturation on the addition, hence there is no risk of overflow. + */ +__STATIC_FORCEINLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + __STATIC_FORCEINLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if ((uint32_t)i >= (S->nValues - 1)) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + __STATIC_FORCEINLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1U); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + __STATIC_FORCEINLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + __STATIC_FORCEINLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + +/** + @brief Floating-point vector of log values. + @param[in] pSrc points to the input vector + @param[out] pDst points to the output vector + @param[in] blockSize number of samples in each vector + @return none + */ + void arm_vlog_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + +/** + @brief Floating-point vector of exp values. + @param[in] pSrc points to the input vector + @param[out] pDst points to the output vector + @param[in] blockSize number of samples in each vector + @return none + */ + void arm_vexp_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + +/** + @brief Floating-point square root function. + @param[in] in input value + @param[out] pOut square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +__STATIC_FORCEINLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if (in >= 0.0f) + { +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + *pOut = __sqrtf(in); + #else + *pOut = sqrtf(in); + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); + #else + *pOut = sqrtf(in); + #endif + +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + +/** + @brief Q31 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF + @param[out] pOut points to square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + +/** + @brief Q15 square root function. + @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF + @param[out] pOut points to square root of input value + @return execution status + - \ref ARM_MATH_SUCCESS : input value is positive + - \ref ARM_MATH_ARGUMENT_ERROR : input value is negative; *pOut is set to 0 + */ +arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @brief Vector Floating-point square root function. + * @param[in] pIn input vector. + * @param[out] pOut vector of square roots of input elements. + * @param[in] len length of input vector. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + void arm_vsqrt_f32( + float32_t * pIn, + float32_t * pOut, + uint16_t len); + + void arm_vsqrt_q31( + q31_t * pIn, + q31_t * pOut, + uint16_t len); + + void arm_vsqrt_q15( + q15_t * pIn, + q15_t * pOut, + uint16_t len); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t rOffset; + int32_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset; + q15_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + __STATIC_FORCEINLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + __STATIC_FORCEINLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset; + q7_t* dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = dst_base + dst_length; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + const q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + const q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + const q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + const float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + const q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + const q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + const q15_t * pSrcCmplx, + const q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + const q31_t * pSrcCmplx, + const q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + const float32_t * pSrcCmplx, + const float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + const q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + const q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + const q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + const float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + /** + @brief Maximum value of a floating-point vector. + @param[in] pSrc points to the input vector + @param[in] blockSize number of samples in input vector + @param[out] pResult maximum value returned here + @return none + */ + void arm_max_no_idx_f32( + const float32_t *pSrc, + uint32_t blockSize, + float32_t *pResult); + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + const q15_t * pSrcA, + const q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + const q31_t * pSrcA, + const q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + const float32_t * pSrcA, + const float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + const float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + const float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + const float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + const q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + const q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + const q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + const q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + const q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + const q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + const q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + const q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + const q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + +/** + * @brief Struct for specifying SVM Kernel + */ +typedef enum +{ + ARM_ML_KERNEL_LINEAR = 0, + /**< Linear kernel */ + ARM_ML_KERNEL_POLYNOMIAL = 1, + /**< Polynomial kernel */ + ARM_ML_KERNEL_RBF = 2, + /**< Radial Basis Function kernel */ + ARM_ML_KERNEL_SIGMOID = 3 + /**< Sigmoid kernel */ +} arm_ml_kernel_type; + + +/** + * @brief Instance structure for linear SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ +} arm_svm_linear_instance_f32; + + +/** + * @brief Instance structure for polynomial SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + int32_t degree; /**< Polynomial degree */ + float32_t coef0; /**< Polynomial constant */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_polynomial_instance_f32; + +/** + * @brief Instance structure for rbf SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_rbf_instance_f32; + +/** + * @brief Instance structure for sigmoid SVM prediction function. + */ +typedef struct +{ + uint32_t nbOfSupportVectors; /**< Number of support vectors */ + uint32_t vectorDimension; /**< Dimension of vector space */ + float32_t intercept; /**< Intercept */ + const float32_t *dualCoefficients; /**< Dual coefficients */ + const float32_t *supportVectors; /**< Support vectors */ + const int32_t *classes; /**< The two SVM classes */ + float32_t coef0; /**< Independant constant */ + float32_t gamma; /**< Gamma factor */ +} arm_svm_sigmoid_instance_f32; + +/** + * @brief SVM linear instance init function + * @param[in] S Parameters for SVM functions + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @return none. + * + */ + + +void arm_svm_linear_init_f32(arm_svm_linear_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes); + +/** + * @brief SVM linear prediction + * @param[in] S Pointer to an instance of the linear SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ + +void arm_svm_linear_predict_f32(const arm_svm_linear_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief SVM polynomial instance init function + * @param[in] S points to an instance of the polynomial SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] degree Polynomial degree + * @param[in] coef0 coeff0 (scikit-learn terminology) + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + + +void arm_svm_polynomial_init_f32(arm_svm_polynomial_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + int32_t degree, + float32_t coef0, + float32_t gamma + ); + +/** + * @brief SVM polynomial prediction + * @param[in] S Pointer to an instance of the polynomial SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ +void arm_svm_polynomial_predict_f32(const arm_svm_polynomial_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + +/** + * @brief SVM radial basis function instance init function + * @param[in] S points to an instance of the polynomial SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + +void arm_svm_rbf_init_f32(arm_svm_rbf_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + float32_t gamma + ); + +/** + * @brief SVM rbf prediction + * @param[in] S Pointer to an instance of the rbf SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult decision value + * @return none. + * + */ +void arm_svm_rbf_predict_f32(const arm_svm_rbf_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + +/** + * @brief SVM sigmoid instance init function + * @param[in] S points to an instance of the rbf SVM structure. + * @param[in] nbOfSupportVectors Number of support vectors + * @param[in] vectorDimension Dimension of vector space + * @param[in] intercept Intercept + * @param[in] dualCoefficients Array of dual coefficients + * @param[in] supportVectors Array of support vectors + * @param[in] classes Array of 2 classes ID + * @param[in] coef0 coeff0 (scikit-learn terminology) + * @param[in] gamma gamma (scikit-learn terminology) + * @return none. + * + */ + +void arm_svm_sigmoid_init_f32(arm_svm_sigmoid_instance_f32 *S, + uint32_t nbOfSupportVectors, + uint32_t vectorDimension, + float32_t intercept, + const float32_t *dualCoefficients, + const float32_t *supportVectors, + const int32_t *classes, + float32_t coef0, + float32_t gamma + ); + +/** + * @brief SVM sigmoid prediction + * @param[in] S Pointer to an instance of the rbf SVM structure. + * @param[in] in Pointer to input vector + * @param[out] pResult Decision value + * @return none. + * + */ +void arm_svm_sigmoid_predict_f32(const arm_svm_sigmoid_instance_f32 *S, + const float32_t * in, + int32_t * pResult); + + + +/** + * @brief Instance structure for Naive Gaussian Bayesian estimator. + */ +typedef struct +{ + uint32_t vectorDimension; /**< Dimension of vector space */ + uint32_t numberOfClasses; /**< Number of different classes */ + const float32_t *theta; /**< Mean values for the Gaussians */ + const float32_t *sigma; /**< Variances for the Gaussians */ + const float32_t *classPriors; /**< Class prior probabilities */ + float32_t epsilon; /**< Additive value to variances */ +} arm_gaussian_naive_bayes_instance_f32; + +/** + * @brief Naive Gaussian Bayesian Estimator + * + * @param[in] S points to a naive bayes instance structure + * @param[in] in points to the elements of the input vector. + * @param[in] pBuffer points to a buffer of length numberOfClasses + * @return The predicted class + * + */ + + +uint32_t arm_gaussian_naive_bayes_predict_f32(const arm_gaussian_naive_bayes_instance_f32 *S, + const float32_t * in, + float32_t *pBuffer); + +/** + * @brief Computation of the LogSumExp + * + * In probabilistic computations, the dynamic of the probability values can be very + * wide because they come from gaussian functions. + * To avoid underflow and overflow issues, the values are represented by their log. + * In this representation, multiplying the original exp values is easy : their logs are added. + * But adding the original exp values is requiring some special handling and it is the + * goal of the LogSumExp function. + * + * If the values are x1...xn, the function is computing: + * + * ln(exp(x1) + ... + exp(xn)) and the computation is done in such a way that + * rounding issues are minimised. + * + * The max xm of the values is extracted and the function is computing: + * xm + ln(exp(x1 - xm) + ... + exp(xn - xm)) + * + * @param[in] *in Pointer to an array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return LogSumExp + * + */ + + +float32_t arm_logsumexp_f32(const float32_t *in, uint32_t blockSize); + +/** + * @brief Dot product with log arithmetic + * + * Vectors are containing the log of the samples + * + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[in] pTmpBuffer temporary buffer of length blockSize + * @return The log of the dot product . + * + */ + + +float32_t arm_logsumexp_dot_prod_f32(const float32_t * pSrcA, + const float32_t * pSrcB, + uint32_t blockSize, + float32_t *pTmpBuffer); + +/** + * @brief Entropy + * + * @param[in] pSrcA Array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return Entropy -Sum(p ln p) + * + */ + + +float32_t arm_entropy_f32(const float32_t * pSrcA,uint32_t blockSize); + + +/** + * @brief Entropy + * + * @param[in] pSrcA Array of input values. + * @param[in] blockSize Number of samples in the input array. + * @return Entropy -Sum(p ln p) + * + */ + + +float64_t arm_entropy_f64(const float64_t * pSrcA, uint32_t blockSize); + + +/** + * @brief Kullback-Leibler + * + * @param[in] pSrcA Pointer to an array of input values for probability distribution A. + * @param[in] pSrcB Pointer to an array of input values for probability distribution B. + * @param[in] blockSize Number of samples in the input array. + * @return Kullback-Leibler Divergence D(A || B) + * + */ +float32_t arm_kullback_leibler_f32(const float32_t * pSrcA + ,const float32_t * pSrcB + ,uint32_t blockSize); + + +/** + * @brief Kullback-Leibler + * + * @param[in] pSrcA Pointer to an array of input values for probability distribution A. + * @param[in] pSrcB Pointer to an array of input values for probability distribution B. + * @param[in] blockSize Number of samples in the input array. + * @return Kullback-Leibler Divergence D(A || B) + * + */ +float64_t arm_kullback_leibler_f64(const float64_t * pSrcA, + const float64_t * pSrcB, + uint32_t blockSize); + + +/** + * @brief Weighted sum + * + * + * @param[in] *in Array of input values. + * @param[in] *weigths Weights + * @param[in] blockSize Number of samples in the input array. + * @return Weighted sum + * + */ +float32_t arm_weighted_sum_f32(const float32_t *in + , const float32_t *weigths + , uint32_t blockSize); + + +/** + * @brief Barycenter + * + * + * @param[in] in List of vectors + * @param[in] weights Weights of the vectors + * @param[out] out Barycenter + * @param[in] nbVectors Number of vectors + * @param[in] vecDim Dimension of space (vector dimension) + * @return None + * + */ +void arm_barycenter_f32(const float32_t *in + , const float32_t *weights + , float32_t *out + , uint32_t nbVectors + , uint32_t vecDim); + +/** + * @brief Euclidean distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_euclidean_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Bray-Curtis distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_braycurtis_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Canberra distance between two vectors + * + * This function may divide by zero when samples pA[i] and pB[i] are both zero. + * The result of the computation will be correct. So the division per zero may be + * ignored. + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_canberra_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + + +/** + * @brief Chebyshev distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_chebyshev_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + + +/** + * @brief Cityblock (Manhattan) distance between two vectors + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_cityblock_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Correlation distance between two vectors + * + * The input vectors are modified in place ! + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ +float32_t arm_correlation_distance_f32(float32_t *pA,float32_t *pB, uint32_t blockSize); + +/** + * @brief Cosine distance between two vectors + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_cosine_distance_f32(const float32_t *pA,const float32_t *pB, uint32_t blockSize); + +/** + * @brief Jensen-Shannon distance between two vectors + * + * This function is assuming that elements of second vector are > 0 + * and 0 only when the corresponding element of first vector is 0. + * Otherwise the result of the computation does not make sense + * and for speed reasons, the cases returning NaN or Infinity are not + * managed. + * + * When the function is computing x log (x / y) with x 0 and y 0, + * it will compute the right value (0) but a division per zero will occur + * and shoudl be ignored in client code. + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] blockSize vector length + * @return distance + * + */ + +float32_t arm_jensenshannon_distance_f32(const float32_t *pA,const float32_t *pB,uint32_t blockSize); + +/** + * @brief Minkowski distance between two vectors + * + * @param[in] pA First vector + * @param[in] pB Second vector + * @param[in] n Norm order (>= 2) + * @param[in] blockSize vector length + * @return distance + * + */ + + + +float32_t arm_minkowski_distance_f32(const float32_t *pA,const float32_t *pB, int32_t order, uint32_t blockSize); + +/** + * @brief Dice distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] order Distance order + * @param[in] blockSize Number of samples + * @return distance + * + */ + + +float32_t arm_dice_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Hamming distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_hamming_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Jaccard distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_jaccard_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Kulsinski distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_kulsinski_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Roger Stanimoto distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_rogerstanimoto_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Russell-Rao distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_russellrao_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Sokal-Michener distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_sokalmichener_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Sokal-Sneath distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_sokalsneath_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + +/** + * @brief Yule distance between two vectors + * + * @param[in] pA First vector of packed booleans + * @param[in] pB Second vector of packed booleans + * @param[in] numberOfBools Number of booleans + * @return distance + * + */ + +float32_t arm_yule_distance(const uint32_t *pA, const uint32_t *pB, uint32_t numberOfBools); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + /** + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (xIndex < 0 || xIndex > (S->numCols - 2) || yIndex < 0 || yIndex > (S->numRows - 2)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex ) + (yIndex ) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex ) + (yIndex+1) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0x0FFFFF - xfract)) >> 4U); + acc = ((q63_t) out * (0x0FFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0x0FFFFF - yfract)) >> 4U); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0x0FFFFF - xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + __STATIC_FORCEINLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numCols - 2) || cI < 0 || cI > (S->numRows - 2)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __GNUC__ ) + #define LOW_OPTIMIZATION_ENTER \ + __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __ICCARM__ ) + /* Enter low optimization region - place directly above function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined ( __ARM_ARCH_7EM__ ) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TI_ARM__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __CSMC__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TASKING__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( _MSC_VER ) || defined(__GNUC_PYTHON__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT +#endif + + + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic pop + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#elif defined ( _MSC_VER ) + +#else + #error Unknown compiler +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/libraries/cmsis/cm4/core_support/arm_mve_tables.h b/libraries/cmsis/cm4/core_support/arm_mve_tables.h new file mode 100644 index 0000000..c07f988 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/arm_mve_tables.h @@ -0,0 +1,235 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_mve_tables.h + * Description: common tables like fft twiddle factors, Bitreverse, reciprocal etc + * used for MVE implementation only + * + * $Date: 08. January 2020 + * $Revision: V1.7.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2020 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #ifndef _ARM_MVE_TABLES_H + #define _ARM_MVE_TABLES_H + + #include "arm_math.h" + + + + + + +#if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_16) || defined(ARM_TABLE_TWIDDLECOEF_F32_32) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_16_f32[2]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_16_f32[2]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_16_f32[2]; +extern float32_t rearranged_twiddle_stride1_16_f32[8]; +extern float32_t rearranged_twiddle_stride2_16_f32[8]; +extern float32_t rearranged_twiddle_stride3_16_f32[8]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_64) || defined(ARM_TABLE_TWIDDLECOEF_F32_128) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_64_f32[3]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_64_f32[3]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_64_f32[3]; +extern float32_t rearranged_twiddle_stride1_64_f32[40]; +extern float32_t rearranged_twiddle_stride2_64_f32[40]; +extern float32_t rearranged_twiddle_stride3_64_f32[40]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_256) || defined(ARM_TABLE_TWIDDLECOEF_F32_512) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_256_f32[4]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_256_f32[4]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_256_f32[4]; +extern float32_t rearranged_twiddle_stride1_256_f32[168]; +extern float32_t rearranged_twiddle_stride2_256_f32[168]; +extern float32_t rearranged_twiddle_stride3_256_f32[168]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_1024) || defined(ARM_TABLE_TWIDDLECOEF_F32_2048) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_f32[5]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_f32[5]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_f32[5]; +extern float32_t rearranged_twiddle_stride1_1024_f32[680]; +extern float32_t rearranged_twiddle_stride2_1024_f32[680]; +extern float32_t rearranged_twiddle_stride3_1024_f32[680]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_F32_4096) || defined(ARM_TABLE_TWIDDLECOEF_F32_8192) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_f32[6]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_f32[6]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_f32[6]; +extern float32_t rearranged_twiddle_stride1_4096_f32[2728]; +extern float32_t rearranged_twiddle_stride2_4096_f32[2728]; +extern float32_t rearranged_twiddle_stride3_4096_f32[2728]; +#endif + + +#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */ + +#endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */ + + + +#if defined(ARM_MATH_MVEI) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_16) || defined(ARM_TABLE_TWIDDLECOEF_Q31_32) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_16_q31[2]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_16_q31[2]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_16_q31[2]; +extern q31_t rearranged_twiddle_stride1_16_q31[8]; +extern q31_t rearranged_twiddle_stride2_16_q31[8]; +extern q31_t rearranged_twiddle_stride3_16_q31[8]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_64) || defined(ARM_TABLE_TWIDDLECOEF_Q31_128) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_64_q31[3]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_64_q31[3]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_64_q31[3]; +extern q31_t rearranged_twiddle_stride1_64_q31[40]; +extern q31_t rearranged_twiddle_stride2_64_q31[40]; +extern q31_t rearranged_twiddle_stride3_64_q31[40]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_256) || defined(ARM_TABLE_TWIDDLECOEF_Q31_512) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_256_q31[4]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_256_q31[4]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_256_q31[4]; +extern q31_t rearranged_twiddle_stride1_256_q31[168]; +extern q31_t rearranged_twiddle_stride2_256_q31[168]; +extern q31_t rearranged_twiddle_stride3_256_q31[168]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_1024) || defined(ARM_TABLE_TWIDDLECOEF_Q31_2048) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_q31[5]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_q31[5]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_q31[5]; +extern q31_t rearranged_twiddle_stride1_1024_q31[680]; +extern q31_t rearranged_twiddle_stride2_1024_q31[680]; +extern q31_t rearranged_twiddle_stride3_1024_q31[680]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q31_4096) || defined(ARM_TABLE_TWIDDLECOEF_Q31_8192) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_q31[6]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_q31[6]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_q31[6]; +extern q31_t rearranged_twiddle_stride1_4096_q31[2728]; +extern q31_t rearranged_twiddle_stride2_4096_q31[2728]; +extern q31_t rearranged_twiddle_stride3_4096_q31[2728]; +#endif + + +#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */ + +#endif /* defined(ARM_MATH_MVEI) */ + + + +#if defined(ARM_MATH_MVEI) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_16) || defined(ARM_TABLE_TWIDDLECOEF_Q15_32) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_16_q15[2]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_16_q15[2]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_16_q15[2]; +extern q15_t rearranged_twiddle_stride1_16_q15[8]; +extern q15_t rearranged_twiddle_stride2_16_q15[8]; +extern q15_t rearranged_twiddle_stride3_16_q15[8]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_64) || defined(ARM_TABLE_TWIDDLECOEF_Q15_128) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_64_q15[3]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_64_q15[3]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_64_q15[3]; +extern q15_t rearranged_twiddle_stride1_64_q15[40]; +extern q15_t rearranged_twiddle_stride2_64_q15[40]; +extern q15_t rearranged_twiddle_stride3_64_q15[40]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_256) || defined(ARM_TABLE_TWIDDLECOEF_Q15_512) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_256_q15[4]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_256_q15[4]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_256_q15[4]; +extern q15_t rearranged_twiddle_stride1_256_q15[168]; +extern q15_t rearranged_twiddle_stride2_256_q15[168]; +extern q15_t rearranged_twiddle_stride3_256_q15[168]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_1024) || defined(ARM_TABLE_TWIDDLECOEF_Q15_2048) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_1024_q15[5]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_1024_q15[5]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_1024_q15[5]; +extern q15_t rearranged_twiddle_stride1_1024_q15[680]; +extern q15_t rearranged_twiddle_stride2_1024_q15[680]; +extern q15_t rearranged_twiddle_stride3_1024_q15[680]; +#endif + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_ALL_FFT_TABLES) || defined(ARM_TABLE_TWIDDLECOEF_Q15_4096) || defined(ARM_TABLE_TWIDDLECOEF_Q15_8192) + +extern uint32_t rearranged_twiddle_tab_stride1_arr_4096_q15[6]; +extern uint32_t rearranged_twiddle_tab_stride2_arr_4096_q15[6]; +extern uint32_t rearranged_twiddle_tab_stride3_arr_4096_q15[6]; +extern q15_t rearranged_twiddle_stride1_4096_q15[2728]; +extern q15_t rearranged_twiddle_stride2_4096_q15[2728]; +extern q15_t rearranged_twiddle_stride3_4096_q15[2728]; +#endif + + +#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */ + +#endif /* defined(ARM_MATH_MVEI) */ + + + +#if defined(ARM_MATH_MVEI) + +#if !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) + + +#endif /* !defined(ARM_DSP_CONFIG_TABLES) || defined(ARM_FFT_ALLOW_TABLES) */ + +#endif /* defined(ARM_MATH_MVEI) */ + + + +#endif /*_ARM_MVE_TABLES_H*/ + diff --git a/libraries/cmsis/cm4/core_support/arm_vec_math.h b/libraries/cmsis/cm4/core_support/arm_vec_math.h new file mode 100644 index 0000000..0ce9464 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/arm_vec_math.h @@ -0,0 +1,372 @@ +/****************************************************************************** + * @file arm_vec_math.h + * @brief Public header file for CMSIS DSP Library + * @version V1.7.0 + * @date 15. October 2019 + ******************************************************************************/ +/* + * Copyright (c) 2010-2019 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_VEC_MATH_H +#define _ARM_VEC_MATH_H + +#include "arm_math.h" +#include "arm_common_tables.h" +#include "arm_helium_utils.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE) + +#define INV_NEWTON_INIT_F32 0x7EF127EA + +static const float32_t __logf_rng_f32=0.693147180f; + + +/* fast inverse approximation (3x newton) */ +__STATIC_INLINE f32x4_t vrecip_medprec_f32( + f32x4_t x) +{ + q31x4_t m; + f32x4_t b; + any32x4_t xinv; + f32x4_t ax = vabsq(x); + + xinv.f = ax; + m = 0x3F800000 - (xinv.i & 0x7F800000); + xinv.i = xinv.i + m; + xinv.f = 1.41176471f - 0.47058824f * xinv.f; + xinv.i = xinv.i + m; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + xinv.f = vdupq_m(xinv.f, INFINITY, vcmpeqq(x, 0.0f)); + /* + * restore sign + */ + xinv.f = vnegq_m(xinv.f, xinv.f, vcmpltq(x, 0.0f)); + + return xinv.f; +} + +/* fast inverse approximation (4x newton) */ +__STATIC_INLINE f32x4_t vrecip_hiprec_f32( + f32x4_t x) +{ + q31x4_t m; + f32x4_t b; + any32x4_t xinv; + f32x4_t ax = vabsq(x); + + xinv.f = ax; + + m = 0x3F800000 - (xinv.i & 0x7F800000); + xinv.i = xinv.i + m; + xinv.f = 1.41176471f - 0.47058824f * xinv.f; + xinv.i = xinv.i + m; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + b = 2.0f - xinv.f * ax; + xinv.f = xinv.f * b; + + xinv.f = vdupq_m(xinv.f, INFINITY, vcmpeqq(x, 0.0f)); + /* + * restore sign + */ + xinv.f = vnegq_m(xinv.f, xinv.f, vcmpltq(x, 0.0f)); + + return xinv.f; +} + +__STATIC_INLINE f32x4_t vdiv_f32( + f32x4_t num, f32x4_t den) +{ + return vmulq(num, vrecip_hiprec_f32(den)); +} + +/** + @brief Single-precision taylor dev. + @param[in] x f32 quad vector input + @param[in] coeffs f32 quad vector coeffs + @return destination f32 quad vector + */ + +__STATIC_INLINE f32x4_t vtaylor_polyq_f32( + f32x4_t x, + const float32_t * coeffs) +{ + f32x4_t A = vfmasq(vdupq_n_f32(coeffs[4]), x, coeffs[0]); + f32x4_t B = vfmasq(vdupq_n_f32(coeffs[6]), x, coeffs[2]); + f32x4_t C = vfmasq(vdupq_n_f32(coeffs[5]), x, coeffs[1]); + f32x4_t D = vfmasq(vdupq_n_f32(coeffs[7]), x, coeffs[3]); + f32x4_t x2 = vmulq(x, x); + f32x4_t x4 = vmulq(x2, x2); + f32x4_t res = vfmaq(vfmaq_f32(A, B, x2), vfmaq_f32(C, D, x2), x4); + + return res; +} + +__STATIC_INLINE f32x4_t vmant_exp_f32( + f32x4_t x, + int32x4_t * e) +{ + any32x4_t r; + int32x4_t n; + + r.f = x; + n = r.i >> 23; + n = n - 127; + r.i = r.i - (n << 23); + + *e = n; + return r.f; +} + + +__STATIC_INLINE f32x4_t vlogq_f32(f32x4_t vecIn) +{ + q31x4_t vecExpUnBiased; + f32x4_t vecTmpFlt0, vecTmpFlt1; + f32x4_t vecAcc0, vecAcc1, vecAcc2, vecAcc3; + f32x4_t vecExpUnBiasedFlt; + + /* + * extract exponent + */ + vecTmpFlt1 = vmant_exp_f32(vecIn, &vecExpUnBiased); + + vecTmpFlt0 = vecTmpFlt1 * vecTmpFlt1; + /* + * a = (__logf_lut_f32[4] * r.f) + (__logf_lut_f32[0]); + */ + vecAcc0 = vdupq_n_f32(__logf_lut_f32[0]); + vecAcc0 = vfmaq(vecAcc0, vecTmpFlt1, __logf_lut_f32[4]); + /* + * b = (__logf_lut_f32[6] * r.f) + (__logf_lut_f32[2]); + */ + vecAcc1 = vdupq_n_f32(__logf_lut_f32[2]); + vecAcc1 = vfmaq(vecAcc1, vecTmpFlt1, __logf_lut_f32[6]); + /* + * c = (__logf_lut_f32[5] * r.f) + (__logf_lut_f32[1]); + */ + vecAcc2 = vdupq_n_f32(__logf_lut_f32[1]); + vecAcc2 = vfmaq(vecAcc2, vecTmpFlt1, __logf_lut_f32[5]); + /* + * d = (__logf_lut_f32[7] * r.f) + (__logf_lut_f32[3]); + */ + vecAcc3 = vdupq_n_f32(__logf_lut_f32[3]); + vecAcc3 = vfmaq(vecAcc3, vecTmpFlt1, __logf_lut_f32[7]); + /* + * a = a + b * xx; + */ + vecAcc0 = vfmaq(vecAcc0, vecAcc1, vecTmpFlt0); + /* + * c = c + d * xx; + */ + vecAcc2 = vfmaq(vecAcc2, vecAcc3, vecTmpFlt0); + /* + * xx = xx * xx; + */ + vecTmpFlt0 = vecTmpFlt0 * vecTmpFlt0; + vecExpUnBiasedFlt = vcvtq_f32_s32(vecExpUnBiased); + /* + * r.f = a + c * xx; + */ + vecAcc0 = vfmaq(vecAcc0, vecAcc2, vecTmpFlt0); + /* + * add exponent + * r.f = r.f + ((float32_t) m) * __logf_rng_f32; + */ + vecAcc0 = vfmaq(vecAcc0, vecExpUnBiasedFlt, __logf_rng_f32); + // set log0 down to -inf + vecAcc0 = vdupq_m(vecAcc0, -INFINITY, vcmpeqq(vecIn, 0.0f)); + return vecAcc0; +} + +__STATIC_INLINE f32x4_t vexpq_f32( + f32x4_t x) +{ + // Perform range reduction [-log(2),log(2)] + int32x4_t m = vcvtq_s32_f32(vmulq_n_f32(x, 1.4426950408f)); + f32x4_t val = vfmsq_f32(x, vcvtq_f32_s32(m), vdupq_n_f32(0.6931471805f)); + + // Polynomial Approximation + f32x4_t poly = vtaylor_polyq_f32(val, exp_tab); + + // Reconstruct + poly = (f32x4_t) (vqaddq_s32((q31x4_t) (poly), vqshlq_n_s32(m, 23))); + + poly = vdupq_m(poly, 0.0f, vcmpltq_n_s32(m, -126)); + return poly; +} + +__STATIC_INLINE f32x4_t arm_vec_exponent_f32(f32x4_t x, int32_t nb) +{ + f32x4_t r = x; + nb--; + while (nb > 0) { + r = vmulq(r, x); + nb--; + } + return (r); +} + +__STATIC_INLINE f32x4_t vrecip_f32(f32x4_t vecIn) +{ + f32x4_t vecSx, vecW, vecTmp; + any32x4_t v; + + vecSx = vabsq(vecIn); + + v.f = vecIn; + v.i = vsubq(vdupq_n_s32(INV_NEWTON_INIT_F32), v.i); + + vecW = vmulq(vecSx, v.f); + + // v.f = v.f * (8 + w * (-28 + w * (56 + w * (-70 + w *(56 + w * (-28 + w * (8 - w))))))); + vecTmp = vsubq(vdupq_n_f32(8.0f), vecW); + vecTmp = vfmasq(vecW, vecTmp, -28.0f); + vecTmp = vfmasq(vecW, vecTmp, 56.0f); + vecTmp = vfmasq(vecW, vecTmp, -70.0f); + vecTmp = vfmasq(vecW, vecTmp, 56.0f); + vecTmp = vfmasq(vecW, vecTmp, -28.0f); + vecTmp = vfmasq(vecW, vecTmp, 8.0f); + v.f = vmulq(v.f, vecTmp); + + v.f = vdupq_m(v.f, INFINITY, vcmpeqq(vecIn, 0.0f)); + /* + * restore sign + */ + v.f = vnegq_m(v.f, v.f, vcmpltq(vecIn, 0.0f)); + return v.f; +} + +__STATIC_INLINE f32x4_t vtanhq_f32( + f32x4_t val) +{ + f32x4_t x = + vminnmq_f32(vmaxnmq_f32(val, vdupq_n_f32(-10.f)), vdupq_n_f32(10.0f)); + f32x4_t exp2x = vexpq_f32(vmulq_n_f32(x, 2.f)); + f32x4_t num = vsubq_n_f32(exp2x, 1.f); + f32x4_t den = vaddq_n_f32(exp2x, 1.f); + f32x4_t tanh = vmulq_f32(num, vrecip_f32(den)); + return tanh; +} + +__STATIC_INLINE f32x4_t vpowq_f32( + f32x4_t val, + f32x4_t n) +{ + return vexpq_f32(vmulq_f32(n, vlogq_f32(val))); +} + +#endif /* (defined(ARM_MATH_MVEF) || defined(ARM_MATH_HELIUM)) && !defined(ARM_MATH_AUTOVECTORIZE)*/ + +#if (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) +#endif /* (defined(ARM_MATH_MVEI) || defined(ARM_MATH_HELIUM)) */ + +#if (defined(ARM_MATH_NEON) || defined(ARM_MATH_NEON_EXPERIMENTAL)) && !defined(ARM_MATH_AUTOVECTORIZE) + +#include "NEMath.h" +/** + * @brief Vectorized integer exponentiation + * @param[in] x value + * @param[in] nb integer exponent >= 1 + * @return x^nb + * + */ +__STATIC_INLINE float32x4_t arm_vec_exponent_f32(float32x4_t x, int32_t nb) +{ + float32x4_t r = x; + nb --; + while(nb > 0) + { + r = vmulq_f32(r , x); + nb--; + } + return(r); +} + + +__STATIC_INLINE float32x4_t __arm_vec_sqrt_f32_neon(float32x4_t x) +{ + float32x4_t x1 = vmaxq_f32(x, vdupq_n_f32(FLT_MIN)); + float32x4_t e = vrsqrteq_f32(x1); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(x1, e), e), e); + return vmulq_f32(x, e); +} + +__STATIC_INLINE int16x8_t __arm_vec_sqrt_q15_neon(int16x8_t vec) +{ + float32x4_t tempF; + int32x4_t tempHI,tempLO; + + tempLO = vmovl_s16(vget_low_s16(vec)); + tempF = vcvtq_n_f32_s32(tempLO,15); + tempF = __arm_vec_sqrt_f32_neon(tempF); + tempLO = vcvtq_n_s32_f32(tempF,15); + + tempHI = vmovl_s16(vget_high_s16(vec)); + tempF = vcvtq_n_f32_s32(tempHI,15); + tempF = __arm_vec_sqrt_f32_neon(tempF); + tempHI = vcvtq_n_s32_f32(tempF,15); + + return(vcombine_s16(vqmovn_s32(tempLO),vqmovn_s32(tempHI))); +} + +__STATIC_INLINE int32x4_t __arm_vec_sqrt_q31_neon(int32x4_t vec) +{ + float32x4_t temp; + + temp = vcvtq_n_f32_s32(vec,31); + temp = __arm_vec_sqrt_f32_neon(temp); + return(vcvtq_n_s32_f32(temp,31)); +} + +#endif /* (defined(ARM_MATH_NEON) || defined(ARM_MATH_NEON_EXPERIMENTAL)) && !defined(ARM_MATH_AUTOVECTORIZE) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_VEC_MATH_H */ + +/** + * + * End of file. + */ diff --git a/libraries/cmsis/cm4/core_support/cmsis_armcc.h b/libraries/cmsis/cm4/core_support/cmsis_armcc.h new file mode 100644 index 0000000..9570d36 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/cmsis_armcc.h @@ -0,0 +1,885 @@ +/****************************************************************************** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.2.1 + * @date 26. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + /* __ARM_ARCH_8_1M_MAIN__ not applicable */ + +/* CMSIS compiler control DSP macros */ +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __ARM_FEATURE_DSP 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __memory_changed() +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/libraries/cmsis/cm4/core_support/cmsis_armclang.h b/libraries/cmsis/cm4/core_support/cmsis_armclang.h new file mode 100644 index 0000000..b466ba4 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/cmsis_armclang.h @@ -0,0 +1,1467 @@ +/****************************************************************************** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.3.1 + * @date 26. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) ) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) + +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) || \ + (defined (__ARM_ARCH_8_1M_MAIN__) && (__ARM_ARCH_8_1M_MAIN__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +#define __SADD8 __builtin_arm_sadd8 +#define __QADD8 __builtin_arm_qadd8 +#define __SHADD8 __builtin_arm_shadd8 +#define __UADD8 __builtin_arm_uadd8 +#define __UQADD8 __builtin_arm_uqadd8 +#define __UHADD8 __builtin_arm_uhadd8 +#define __SSUB8 __builtin_arm_ssub8 +#define __QSUB8 __builtin_arm_qsub8 +#define __SHSUB8 __builtin_arm_shsub8 +#define __USUB8 __builtin_arm_usub8 +#define __UQSUB8 __builtin_arm_uqsub8 +#define __UHSUB8 __builtin_arm_uhsub8 +#define __SADD16 __builtin_arm_sadd16 +#define __QADD16 __builtin_arm_qadd16 +#define __SHADD16 __builtin_arm_shadd16 +#define __UADD16 __builtin_arm_uadd16 +#define __UQADD16 __builtin_arm_uqadd16 +#define __UHADD16 __builtin_arm_uhadd16 +#define __SSUB16 __builtin_arm_ssub16 +#define __QSUB16 __builtin_arm_qsub16 +#define __SHSUB16 __builtin_arm_shsub16 +#define __USUB16 __builtin_arm_usub16 +#define __UQSUB16 __builtin_arm_uqsub16 +#define __UHSUB16 __builtin_arm_uhsub16 +#define __SASX __builtin_arm_sasx +#define __QASX __builtin_arm_qasx +#define __SHASX __builtin_arm_shasx +#define __UASX __builtin_arm_uasx +#define __UQASX __builtin_arm_uqasx +#define __UHASX __builtin_arm_uhasx +#define __SSAX __builtin_arm_ssax +#define __QSAX __builtin_arm_qsax +#define __SHSAX __builtin_arm_shsax +#define __USAX __builtin_arm_usax +#define __UQSAX __builtin_arm_uqsax +#define __UHSAX __builtin_arm_uhsax +#define __USAD8 __builtin_arm_usad8 +#define __USADA8 __builtin_arm_usada8 +#define __SSAT16 __builtin_arm_ssat16 +#define __USAT16 __builtin_arm_usat16 +#define __UXTB16 __builtin_arm_uxtb16 +#define __UXTAB16 __builtin_arm_uxtab16 +#define __SXTB16 __builtin_arm_sxtb16 +#define __SXTAB16 __builtin_arm_sxtab16 +#define __SMUAD __builtin_arm_smuad +#define __SMUADX __builtin_arm_smuadx +#define __SMLAD __builtin_arm_smlad +#define __SMLADX __builtin_arm_smladx +#define __SMLALD __builtin_arm_smlald +#define __SMLALDX __builtin_arm_smlaldx +#define __SMUSD __builtin_arm_smusd +#define __SMUSDX __builtin_arm_smusdx +#define __SMLSD __builtin_arm_smlsd +#define __SMLSDX __builtin_arm_smlsdx +#define __SMLSLD __builtin_arm_smlsld +#define __SMLSLDX __builtin_arm_smlsldx +#define __SEL __builtin_arm_sel +#define __QADD __builtin_arm_qadd +#define __QSUB __builtin_arm_qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/libraries/cmsis/cm4/core_support/cmsis_armclang_ltm.h b/libraries/cmsis/cm4/core_support/cmsis_armclang_ltm.h new file mode 100644 index 0000000..e0c5b94 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/cmsis_armclang_ltm.h @@ -0,0 +1,1893 @@ +/****************************************************************************** + * @file cmsis_armclang_ltm.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V1.3.0 + * @date 26. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2018-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START +#define __PROGRAM_START __main +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP Image$$ARM_LIB_STACK$$ZI$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT Image$$ARM_LIB_STACK$$ZI$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section("RESET"))) +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF) + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM Compiler 6.10 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/libraries/cmsis/cm4/core_support/cmsis_compiler.h b/libraries/cmsis/cm4/core_support/cmsis_compiler.h new file mode 100644 index 0000000..8d3ab97 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/cmsis_compiler.h @@ -0,0 +1,283 @@ +/****************************************************************************** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #define __RESTRICT __restrict + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + #ifndef __COMPILER_BARRIER + #warning No compiler specific solution for __COMPILER_BARRIER. __COMPILER_BARRIER is ignored. + #define __COMPILER_BARRIER() (void)0 + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/libraries/cmsis/cm4/core_support/cmsis_gcc.h b/libraries/cmsis/cm4/core_support/cmsis_gcc.h new file mode 100644 index 0000000..683ce0f --- /dev/null +++ b/libraries/cmsis/cm4/core_support/cmsis_gcc.h @@ -0,0 +1,2177 @@ +/****************************************************************************** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.3.0 + * @date 26. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +/* ######################### Startup and Lowlevel Init ######################## */ + +#ifndef __PROGRAM_START + +/** + \brief Initializes data and bss sections + \details This default implementations initialized all data and additional bss + sections relying on .copy.table and .zero.table specified properly + in the used linker script. + + */ +__STATIC_FORCEINLINE __NO_RETURN void __cmsis_start(void) +{ + extern void _start(void) __NO_RETURN; + + typedef struct { + uint32_t const* src; + uint32_t* dest; + uint32_t wlen; + } __copy_table_t; + + typedef struct { + uint32_t* dest; + uint32_t wlen; + } __zero_table_t; + + extern const __copy_table_t __copy_table_start__; + extern const __copy_table_t __copy_table_end__; + extern const __zero_table_t __zero_table_start__; + extern const __zero_table_t __zero_table_end__; + + for (__copy_table_t const* pTable = &__copy_table_start__; pTable < &__copy_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = pTable->src[i]; + } + } + + for (__zero_table_t const* pTable = &__zero_table_start__; pTable < &__zero_table_end__; ++pTable) { + for(uint32_t i=0u; iwlen; ++i) { + pTable->dest[i] = 0u; + } + } + + _start(); +} + +#define __PROGRAM_START __cmsis_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP __StackTop +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT __StackLimit +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __Vectors +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE __attribute__((used, section(".vectors"))) +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi":::"memory") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe":::"memory") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1, ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1, ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) : "memory" ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1, ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +#define __USAT16(ARG1, ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM volatile ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) : "cc" ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16_RORn(uint32_t op1, uint32_t rotate) +{ + uint32_t result; + + __ASM ("sxtb16 %0, %1, ROR %2" : "=r" (result) : "r" (op1), "i" (rotate) ); + + return result; +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/libraries/cmsis/cm4/core_support/cmsis_iccarm.h b/libraries/cmsis/cm4/core_support/cmsis_iccarm.h new file mode 100644 index 0000000..890ba20 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/cmsis_iccarm.h @@ -0,0 +1,968 @@ +/****************************************************************************** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.2.0 + * @date 28. January 2020 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2019 IAR Systems +// Copyright (c) 2017-2019 Arm Limited. All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __COMPILER_BARRIER + #define __COMPILER_BARRIER() __ASM volatile("":::"memory") +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #if __ICCARM_V8 + #define __RESTRICT __restrict + #else + /* Needs IAR language extensions */ + #define __RESTRICT restrict + #endif +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + +#ifndef __PROGRAM_START +#define __PROGRAM_START __iar_program_start +#endif + +#ifndef __INITIAL_SP +#define __INITIAL_SP CSTACK$$Limit +#endif + +#ifndef __STACK_LIMIT +#define __STACK_LIMIT CSTACK$$Base +#endif + +#ifndef __VECTOR_TABLE +#define __VECTOR_TABLE __vector_table +#endif + +#ifndef __VECTOR_TABLE_ATTRIBUTE +#define __VECTOR_TABLE_ATTRIBUTE @".intvec" +#endif + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM volatile("RRX %0, %1" : "=r"(result) : "r" (value)); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM volatile ("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM volatile ("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM volatile ("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM volatile ("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM volatile ("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM volatile ("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#define __SXTB16_RORn(ARG1, ARG2) __SXTB16(__ROR(ARG1, ARG2)) + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/libraries/cmsis/cm4/core_support/cmsis_version.h b/libraries/cmsis/cm4/core_support/cmsis_version.h new file mode 100644 index 0000000..c999178 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/cmsis_version.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.4 + * @date 23. July 2019 + ******************************************************************************/ +/* + * Copyright (c) 2009-2019 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 4U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/libraries/cmsis/cm4/core_support/core_cm4.h b/libraries/cmsis/cm4/core_support/core_cm4.h new file mode 100644 index 0000000..6a50d5e --- /dev/null +++ b/libraries/cmsis/cm4/core_support/core_cm4.h @@ -0,0 +1,2129 @@ +/************************************************************************** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.1.1 + * @date 27. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_FP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 1U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RESERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[32U]; + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x1UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x1UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x1UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x1UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +#define FPU_MVFR2_VFP_Misc_Pos 4U /*!< MVFR2: VFP Misc bits Position */ +#define FPU_MVFR2_VFP_Misc_Msk (0xFUL << FPU_MVFR2_VFP_Misc_Pos) /*!< MVFR2: VFP Misc bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + __COMPILER_BARRIER(); + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __COMPILER_BARRIER(); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + /* ARM Application Note 321 states that the M4 does not require the architectural barrier */ +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/libraries/cmsis/cm4/core_support/mpu_armv7.h b/libraries/cmsis/cm4/core_support/mpu_armv7.h new file mode 100644 index 0000000..442fc21 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/mpu_armv7.h @@ -0,0 +1,275 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.1.1 + * @date 10. February 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (((MPU_RASR_ENABLE_Msk)))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if shareable) or 010b (if non-shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) >> 1U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + ARM_MPU_OrderedMemcpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/libraries/cmsis/cm4/core_support/mpu_armv8.h b/libraries/cmsis/cm4/core_support/mpu_armv8.h new file mode 100644 index 0000000..3a197fb --- /dev/null +++ b/libraries/cmsis/cm4/core_support/mpu_armv8.h @@ -0,0 +1,352 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M and Armv8.1-M MPU + * @version V5.1.2 + * @date 10. February 2020 + ******************************************************************************/ +/* + * Copyright (c) 2017-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + ((((NT) & 1U) << 3U) | (((WB) & 1U) << 2U) | (((RA) & 1U) << 1U) | ((WA) & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) ((((O) & 0xFU) << 4U) | ((((O) & 0xFU) != 0U) ? ((I) & 0xFU) : (((I) & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) ((((RO) & 1U) << 1U) | ((NP) & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + (((BASE) & MPU_RBAR_BASE_Msk) | \ + (((SH) << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + (((XN) << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + (((LIMIT) & MPU_RLAR_LIMIT_Msk) | \ + (((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#if defined(MPU_RLAR_PXN_Pos) + +/** \brief Region Limit Address Register with PXN value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param PXN Privileged execute never. Defines whether code can be executed from this privileged region. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \ + (((LIMIT) & MPU_RLAR_LIMIT_Msk) | \ + (((PXN) << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \ + (((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +#endif + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DMB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DMB(); + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif + __DSB(); + __ISB(); +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DMB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; + __DSB(); + __ISB(); +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/libraries/cmsis/cm4/core_support/pmu_armv8.h b/libraries/cmsis/cm4/core_support/pmu_armv8.h new file mode 100644 index 0000000..23b37d9 --- /dev/null +++ b/libraries/cmsis/cm4/core_support/pmu_armv8.h @@ -0,0 +1,337 @@ +/****************************************************************************** + * @file pmu_armv8.h + * @brief CMSIS PMU API for Armv8.1-M PMU + * @version V1.0.0 + * @date 24. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_PMU_ARMV8_H +#define ARM_PMU_ARMV8_H + +/** + * \brief PMU Events + * \note See the Armv8.1-M Architecture Reference Manual for full details on these PMU events. + * */ + +#define ARM_PMU_SW_INCR 0x0000 /*!< Software update to the PMU_SWINC register, architecturally executed and condition code check pass */ +#define ARM_PMU_L1I_CACHE_REFILL 0x0001 /*!< L1 I-Cache refill */ +#define ARM_PMU_L1D_CACHE_REFILL 0x0003 /*!< L1 D-Cache refill */ +#define ARM_PMU_L1D_CACHE 0x0004 /*!< L1 D-Cache access */ +#define ARM_PMU_LD_RETIRED 0x0006 /*!< Memory-reading instruction architecturally executed and condition code check pass */ +#define ARM_PMU_ST_RETIRED 0x0007 /*!< Memory-writing instruction architecturally executed and condition code check pass */ +#define ARM_PMU_INST_RETIRED 0x0008 /*!< Instruction architecturally executed */ +#define ARM_PMU_EXC_TAKEN 0x0009 /*!< Exception entry */ +#define ARM_PMU_EXC_RETURN 0x000A /*!< Exception return instruction architecturally executed and the condition code check pass */ +#define ARM_PMU_PC_WRITE_RETIRED 0x000C /*!< Software change to the Program Counter (PC). Instruction is architecturally executed and condition code check pass */ +#define ARM_PMU_BR_IMMED_RETIRED 0x000D /*!< Immediate branch architecturally executed */ +#define ARM_PMU_BR_RETURN_RETIRED 0x000E /*!< Function return instruction architecturally executed and the condition code check pass */ +#define ARM_PMU_UNALIGNED_LDST_RETIRED 0x000F /*!< Unaligned memory memory-reading or memory-writing instruction architecturally executed and condition code check pass */ +#define ARM_PMU_BR_MIS_PRED 0x0010 /*!< Mispredicted or not predicted branch speculatively executed */ +#define ARM_PMU_CPU_CYCLES 0x0011 /*!< Cycle */ +#define ARM_PMU_BR_PRED 0x0012 /*!< Predictable branch speculatively executed */ +#define ARM_PMU_MEM_ACCESS 0x0013 /*!< Data memory access */ +#define ARM_PMU_L1I_CACHE 0x0014 /*!< Level 1 instruction cache access */ +#define ARM_PMU_L1D_CACHE_WB 0x0015 /*!< Level 1 data cache write-back */ +#define ARM_PMU_L2D_CACHE 0x0016 /*!< Level 2 data cache access */ +#define ARM_PMU_L2D_CACHE_REFILL 0x0017 /*!< Level 2 data cache refill */ +#define ARM_PMU_L2D_CACHE_WB 0x0018 /*!< Level 2 data cache write-back */ +#define ARM_PMU_BUS_ACCESS 0x0019 /*!< Bus access */ +#define ARM_PMU_MEMORY_ERROR 0x001A /*!< Local memory error */ +#define ARM_PMU_INST_SPEC 0x001B /*!< Instruction speculatively executed */ +#define ARM_PMU_BUS_CYCLES 0x001D /*!< Bus cycles */ +#define ARM_PMU_CHAIN 0x001E /*!< For an odd numbered counter, increment when an overflow occurs on the preceding even-numbered counter on the same PE */ +#define ARM_PMU_L1D_CACHE_ALLOCATE 0x001F /*!< Level 1 data cache allocation without refill */ +#define ARM_PMU_L2D_CACHE_ALLOCATE 0x0020 /*!< Level 2 data cache allocation without refill */ +#define ARM_PMU_BR_RETIRED 0x0021 /*!< Branch instruction architecturally executed */ +#define ARM_PMU_BR_MIS_PRED_RETIRED 0x0022 /*!< Mispredicted branch instruction architecturally executed */ +#define ARM_PMU_STALL_FRONTEND 0x0023 /*!< No operation issued because of the frontend */ +#define ARM_PMU_STALL_BACKEND 0x0024 /*!< No operation issued because of the backend */ +#define ARM_PMU_L2I_CACHE 0x0027 /*!< Level 2 instruction cache access */ +#define ARM_PMU_L2I_CACHE_REFILL 0x0028 /*!< Level 2 instruction cache refill */ +#define ARM_PMU_L3D_CACHE_ALLOCATE 0x0029 /*!< Level 3 data cache allocation without refill */ +#define ARM_PMU_L3D_CACHE_REFILL 0x002A /*!< Level 3 data cache refill */ +#define ARM_PMU_L3D_CACHE 0x002B /*!< Level 3 data cache access */ +#define ARM_PMU_L3D_CACHE_WB 0x002C /*!< Level 3 data cache write-back */ +#define ARM_PMU_LL_CACHE_RD 0x0036 /*!< Last level data cache read */ +#define ARM_PMU_LL_CACHE_MISS_RD 0x0037 /*!< Last level data cache read miss */ +#define ARM_PMU_L1D_CACHE_MISS_RD 0x0039 /*!< Level 1 data cache read miss */ +#define ARM_PMU_OP_COMPLETE 0x003A /*!< Operation retired */ +#define ARM_PMU_OP_SPEC 0x003B /*!< Operation speculatively executed */ +#define ARM_PMU_STALL 0x003C /*!< Stall cycle for instruction or operation not sent for execution */ +#define ARM_PMU_STALL_OP_BACKEND 0x003D /*!< Stall cycle for instruction or operation not sent for execution due to pipeline backend */ +#define ARM_PMU_STALL_OP_FRONTEND 0x003E /*!< Stall cycle for instruction or operation not sent for execution due to pipeline frontend */ +#define ARM_PMU_STALL_OP 0x003F /*!< Instruction or operation slots not occupied each cycle */ +#define ARM_PMU_L1D_CACHE_RD 0x0040 /*!< Level 1 data cache read */ +#define ARM_PMU_LE_RETIRED 0x0100 /*!< Loop end instruction executed */ +#define ARM_PMU_LE_SPEC 0x0101 /*!< Loop end instruction speculatively executed */ +#define ARM_PMU_BF_RETIRED 0x0104 /*!< Branch future instruction architecturally executed and condition code check pass */ +#define ARM_PMU_BF_SPEC 0x0105 /*!< Branch future instruction speculatively executed and condition code check pass */ +#define ARM_PMU_LE_CANCEL 0x0108 /*!< Loop end instruction not taken */ +#define ARM_PMU_BF_CANCEL 0x0109 /*!< Branch future instruction not taken */ +#define ARM_PMU_SE_CALL_S 0x0114 /*!< Call to secure function, resulting in Security state change */ +#define ARM_PMU_SE_CALL_NS 0x0115 /*!< Call to non-secure function, resulting in Security state change */ +#define ARM_PMU_DWT_CMPMATCH0 0x0118 /*!< DWT comparator 0 match */ +#define ARM_PMU_DWT_CMPMATCH1 0x0119 /*!< DWT comparator 1 match */ +#define ARM_PMU_DWT_CMPMATCH2 0x011A /*!< DWT comparator 2 match */ +#define ARM_PMU_DWT_CMPMATCH3 0x011B /*!< DWT comparator 3 match */ +#define ARM_PMU_MVE_INST_RETIRED 0x0200 /*!< MVE instruction architecturally executed */ +#define ARM_PMU_MVE_INST_SPEC 0x0201 /*!< MVE instruction speculatively executed */ +#define ARM_PMU_MVE_FP_RETIRED 0x0204 /*!< MVE floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_SPEC 0x0205 /*!< MVE floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_HP_RETIRED 0x0208 /*!< MVE half-precision floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_HP_SPEC 0x0209 /*!< MVE half-precision floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_SP_RETIRED 0x020C /*!< MVE single-precision floating-point instruction architecturally executed */ +#define ARM_PMU_MVE_FP_SP_SPEC 0x020D /*!< MVE single-precision floating-point instruction speculatively executed */ +#define ARM_PMU_MVE_FP_MAC_RETIRED 0x0214 /*!< MVE floating-point multiply or multiply-accumulate instruction architecturally executed */ +#define ARM_PMU_MVE_FP_MAC_SPEC 0x0215 /*!< MVE floating-point multiply or multiply-accumulate instruction speculatively executed */ +#define ARM_PMU_MVE_INT_RETIRED 0x0224 /*!< MVE integer instruction architecturally executed */ +#define ARM_PMU_MVE_INT_SPEC 0x0225 /*!< MVE integer instruction speculatively executed */ +#define ARM_PMU_MVE_INT_MAC_RETIRED 0x0228 /*!< MVE multiply or multiply-accumulate instruction architecturally executed */ +#define ARM_PMU_MVE_INT_MAC_SPEC 0x0229 /*!< MVE multiply or multiply-accumulate instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_RETIRED 0x0238 /*!< MVE load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_SPEC 0x0239 /*!< MVE load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_RETIRED 0x023C /*!< MVE load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_SPEC 0x023D /*!< MVE load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_RETIRED 0x0240 /*!< MVE store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_SPEC 0x0241 /*!< MVE store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_CONTIG_RETIRED 0x0244 /*!< MVE contiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_CONTIG_SPEC 0x0245 /*!< MVE contiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_CONTIG_RETIRED 0x0248 /*!< MVE contiguous load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_CONTIG_SPEC 0x0249 /*!< MVE contiguous load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_CONTIG_RETIRED 0x024C /*!< MVE contiguous store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_CONTIG_SPEC 0x024D /*!< MVE contiguous store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_NONCONTIG_RETIRED 0x0250 /*!< MVE non-contiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_NONCONTIG_SPEC 0x0251 /*!< MVE non-contiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_NONCONTIG_RETIRED 0x0254 /*!< MVE non-contiguous load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_NONCONTIG_SPEC 0x0255 /*!< MVE non-contiguous load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_NONCONTIG_RETIRED 0x0258 /*!< MVE non-contiguous store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_NONCONTIG_SPEC 0x0259 /*!< MVE non-contiguous store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_MULTI_RETIRED 0x025C /*!< MVE memory instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_LDST_MULTI_SPEC 0x025D /*!< MVE memory instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_LD_MULTI_RETIRED 0x0260 /*!< MVE memory load instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_LD_MULTI_SPEC 0x0261 /*!< MVE memory load instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_ST_MULTI_RETIRED 0x0261 /*!< MVE memory store instruction targeting multiple registers architecturally executed */ +#define ARM_PMU_MVE_ST_MULTI_SPEC 0x0265 /*!< MVE memory store instruction targeting multiple registers speculatively executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_RETIRED 0x028C /*!< MVE unaligned memory load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_SPEC 0x028D /*!< MVE unaligned memory load or store instruction speculatively executed */ +#define ARM_PMU_MVE_LD_UNALIGNED_RETIRED 0x0290 /*!< MVE unaligned load instruction architecturally executed */ +#define ARM_PMU_MVE_LD_UNALIGNED_SPEC 0x0291 /*!< MVE unaligned load instruction speculatively executed */ +#define ARM_PMU_MVE_ST_UNALIGNED_RETIRED 0x0294 /*!< MVE unaligned store instruction architecturally executed */ +#define ARM_PMU_MVE_ST_UNALIGNED_SPEC 0x0295 /*!< MVE unaligned store instruction speculatively executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_RETIRED 0x0298 /*!< MVE unaligned noncontiguous load or store instruction architecturally executed */ +#define ARM_PMU_MVE_LDST_UNALIGNED_NONCONTIG_SPEC 0x0299 /*!< MVE unaligned noncontiguous load or store instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_RETIRED 0x02A0 /*!< MVE vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_SPEC 0x02A1 /*!< MVE vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_FP_RETIRED 0x02A4 /*!< MVE floating-point vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_FP_SPEC 0x02A5 /*!< MVE floating-point vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_VREDUCE_INT_RETIRED 0x02A8 /*!< MVE integer vector reduction instruction architecturally executed */ +#define ARM_PMU_MVE_VREDUCE_INT_SPEC 0x02A9 /*!< MVE integer vector reduction instruction speculatively executed */ +#define ARM_PMU_MVE_PRED 0x02B8 /*!< Cycles where one or more predicated beats architecturally executed */ +#define ARM_PMU_MVE_STALL 0x02CC /*!< Stall cycles caused by an MVE instruction */ +#define ARM_PMU_MVE_STALL_RESOURCE 0x02CD /*!< Stall cycles caused by an MVE instruction because of resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_MEM 0x02CE /*!< Stall cycles caused by an MVE instruction because of memory resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_FP 0x02CF /*!< Stall cycles caused by an MVE instruction because of floating-point resource conflicts */ +#define ARM_PMU_MVE_STALL_RESOURCE_INT 0x02D0 /*!< Stall cycles caused by an MVE instruction because of integer resource conflicts */ +#define ARM_PMU_MVE_STALL_BREAK 0x02D3 /*!< Stall cycles caused by an MVE chain break */ +#define ARM_PMU_MVE_STALL_DEPENDENCY 0x02D4 /*!< Stall cycles caused by MVE register dependency */ +#define ARM_PMU_ITCM_ACCESS 0x4007 /*!< Instruction TCM access */ +#define ARM_PMU_DTCM_ACCESS 0x4008 /*!< Data TCM access */ +#define ARM_PMU_TRCEXTOUT0 0x4010 /*!< ETM external output 0 */ +#define ARM_PMU_TRCEXTOUT1 0x4011 /*!< ETM external output 1 */ +#define ARM_PMU_TRCEXTOUT2 0x4012 /*!< ETM external output 2 */ +#define ARM_PMU_TRCEXTOUT3 0x4013 /*!< ETM external output 3 */ +#define ARM_PMU_CTI_TRIGOUT4 0x4018 /*!< Cross-trigger Interface output trigger 4 */ +#define ARM_PMU_CTI_TRIGOUT5 0x4019 /*!< Cross-trigger Interface output trigger 5 */ +#define ARM_PMU_CTI_TRIGOUT6 0x401A /*!< Cross-trigger Interface output trigger 6 */ +#define ARM_PMU_CTI_TRIGOUT7 0x401B /*!< Cross-trigger Interface output trigger 7 */ + +/** \brief PMU Functions */ + +__STATIC_INLINE void ARM_PMU_Enable(void); +__STATIC_INLINE void ARM_PMU_Disable(void); + +__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type); + +__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void); +__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void); + +__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask); +__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask); + +__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void); +__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num); + +__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void); +__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask); + +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask); +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask); + +__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask); + +/** + \brief Enable the PMU +*/ +__STATIC_INLINE void ARM_PMU_Enable(void) +{ + PMU->CTRL |= PMU_CTRL_ENABLE_Msk; +} + +/** + \brief Disable the PMU +*/ +__STATIC_INLINE void ARM_PMU_Disable(void) +{ + PMU->CTRL &= ~PMU_CTRL_ENABLE_Msk; +} + +/** + \brief Set event to count for PMU eventer counter + \param [in] num Event counter (0-30) to configure + \param [in] type Event to count +*/ +__STATIC_INLINE void ARM_PMU_Set_EVTYPER(uint32_t num, uint32_t type) +{ + PMU->EVTYPER[num] = type; +} + +/** + \brief Reset cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CYCCNT_Reset(void) +{ + PMU->CTRL |= PMU_CTRL_CYCCNT_RESET_Msk; +} + +/** + \brief Reset all event counters +*/ +__STATIC_INLINE void ARM_PMU_EVCNTR_ALL_Reset(void) +{ + PMU->CTRL |= PMU_CTRL_EVENTCNT_RESET_Msk; +} + +/** + \brief Enable counters + \param [in] mask Counters to enable + \note Enables one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Enable(uint32_t mask) +{ + PMU->CNTENSET = mask; +} + +/** + \brief Disable counters + \param [in] mask Counters to enable + \note Disables one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Disable(uint32_t mask) +{ + PMU->CNTENCLR = mask; +} + +/** + \brief Read cycle counter + \return Cycle count +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_CCNTR(void) +{ + return PMU->CCNTR; +} + +/** + \brief Read event counter + \param [in] num Event counter (0-30) to read + \return Event count +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_EVCNTR(uint32_t num) +{ + return PMU->EVCNTR[num]; +} + +/** + \brief Read counter overflow status + \return Counter overflow status bits for the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE uint32_t ARM_PMU_Get_CNTR_OVS(void) +{ + return PMU->OVSSET; +} + +/** + \brief Clear counter overflow status + \param [in] mask Counter overflow status bits to clear + \note Clears overflow status bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_OVS(uint32_t mask) +{ + PMU->OVSCLR = mask; +} + +/** + \brief Enable counter overflow interrupt request + \param [in] mask Counter overflow interrupt request bits to set + \note Sets overflow interrupt request bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Enable(uint32_t mask) +{ + PMU->INTENSET = mask; +} + +/** + \brief Disable counter overflow interrupt request + \param [in] mask Counter overflow interrupt request bits to clear + \note Clears overflow interrupt request bits for one or more of the following: + - event counters (0-30) + - cycle counter +*/ +__STATIC_INLINE void ARM_PMU_Set_CNTR_IRQ_Disable(uint32_t mask) +{ + PMU->INTENCLR = mask; +} + +/** + \brief Software increment event counter + \param [in] mask Counters to increment + \note Software increment bits for one or more event counters (0-30) +*/ +__STATIC_INLINE void ARM_PMU_CNTR_Increment(uint32_t mask) +{ + PMU->SWINC = mask; +} + +#endif diff --git a/libraries/cmsis/cm4/device_support/at32f425.h b/libraries/cmsis/cm4/device_support/at32f425.h new file mode 100644 index 0000000..e761992 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/at32f425.h @@ -0,0 +1,393 @@ +/** + ************************************************************************** + * @file at32f425.h + * @brief at32f425 header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#ifndef __AT32F425_H +#define __AT32F425_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__CC_ARM) + #pragma anon_unions +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup AT32F425 + * @{ + */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * tip: to avoid modifying this file each time you need to switch between these + * devices, you can define the device in your toolchain compiler preprocessor. + */ + +#if !defined (AT32F425R8T7) && !defined (AT32F425R8T7_7) && !defined (AT32F425C8T7) && \ + !defined (AT32F425C8U7) && !defined (AT32F425K8T7) && !defined (AT32F425K8U7_4) && \ + !defined (AT32F425F8P7) && !defined (AT32F425G8U7) && !defined (AT32F425R6T7) && \ + !defined (AT32F425R6T7_7) && !defined (AT32F425C6T7) && !defined (AT32F425C6U7) && \ + !defined (AT32F425K6T7) && !defined (AT32F425K6U7_4) && !defined (AT32F425F6P7) && \ + !defined (AT32F425G6U7) + + #error "Please select first the target device used in your application (in at32f425.h file)" +#endif + +#if defined (AT32F425R8T7) || defined (AT32F425R8T7_7) || defined (AT32F425C8T7) || \ + defined (AT32F425C8U7) || defined (AT32F425K8T7) || defined (AT32F425K8U7_4) || \ + defined (AT32F425F8P7) || defined (AT32F425G8U7) || defined (AT32F425R6T7) || \ + defined (AT32F425R6T7_7) || defined (AT32F425C6T7) || defined (AT32F425C6U7) || \ + defined (AT32F425K6T7) || defined (AT32F425K6U7_4) || defined (AT32F425F6P7) || \ + defined (AT32F425G6U7) + + #define AT32F425xx +#endif + +/** + * define with package + */ +#if defined (AT32F425R8T7) || defined (AT32F425R8T7_7) || defined (AT32F425R6T7) || \ + defined (AT32F425R6T7_7) + + #define AT32F425Rx +#endif + +#if defined (AT32F425C8T7) || defined (AT32F425C8U7) || defined (AT32F425C6T7) || \ + defined (AT32F425C6U7) + + #define AT32F425Cx +#endif + +#if defined (AT32F425K8T7) || defined (AT32F425K8U7_4) || defined (AT32F425K6T7) || \ + defined (AT32F425K6U7_4) + + #define AT32F425Kx +#endif + +#if defined (AT32F425G8U7) || defined (AT32F425G6U7) + + #define AT32F425Gx +#endif + +#if defined (AT32F425F8P7) || defined (AT32F425F6P7) + + #define AT32F425Fx +#endif + +/** + * define with memory density + */ +#if defined (AT32F425R6T7) || defined (AT32F425R6T7_7) || defined (AT32F425C6T7) || \ + defined (AT32F425C6U7) || defined (AT32F425K6T7) || defined (AT32F425K6U7_4) || \ + defined (AT32F425F6P7) || defined (AT32F425G6U7) + + #define AT32F425x6 +#endif + +#if defined (AT32F425R8T7) || defined (AT32F425R8T7_7) || defined (AT32F425C8T7) || \ + defined (AT32F425C8U7) || defined (AT32F425K8T7) || defined (AT32F425K8U7_4) || \ + defined (AT32F425F8P7) || defined (AT32F425G8U7) + + #define AT32F425x8 +#endif + +#ifndef USE_STDPERIPH_DRIVER +/** + * @brief comment the line below if you will not use the peripherals drivers. + * in this case, these drivers will not be included and the application code will + * be based on direct access to peripherals registers + */ + #ifdef _RTE_ + #include "RTE_Components.h" + #ifdef RTE_DEVICE_STDPERIPH_FRAMEWORK + #define USE_STDPERIPH_DRIVER + #endif + #endif +#endif + +/** + * @brief at32f425 standard peripheral library version number + */ +#define __AT32F425_LIBRARY_VERSION_MAJOR (0x02) /*!< [31:24] major version */ +#define __AT32F425_LIBRARY_VERSION_MIDDLE (0x01) /*!< [23:16] middle version */ +#define __AT32F425_LIBRARY_VERSION_MINOR (0x01) /*!< [15:8] minor version */ +#define __AT32F425_LIBRARY_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __AT32F425_LIBRARY_VERSION ((__AT32F425_LIBRARY_VERSION_MAJOR << 24) | \ + (__AT32F425_LIBRARY_VERSION_MIDDLE << 16) | \ + (__AT32F425_LIBRARY_VERSION_MINOR << 8) | \ + (__AT32F425_LIBRARY_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief configuration of the cortex-m4 processor and core peripherals + */ +#define __CM4_REV 0x0001U /*!< core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< mpu present */ +#define __NVIC_PRIO_BITS 4 /*!< at32 uses 4 bits for the priority levels */ +#define __Vendor_SysTickConfig 0 /*!< set to 1 if different systick config is used */ +#define __FPU_PRESENT 0U /*!< fpu present */ + +/** + * @brief at32f425 interrupt number definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum IRQn +{ + /****** cortex-m4 processor exceptions numbers ***************************************************/ + Reset_IRQn = -15, /*!< 1 reset vector, invoked on power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */ + HardFault_IRQn = -13, /*!< 3 hard fault, all classes of fault */ + MemoryManagement_IRQn = -12, /*!< 4 cortex-m4 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 cortex-m4 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 cortex-m4 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 cortex-m4 sv call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 cortex-m4 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 cortex-m4 pend sv interrupt */ + SysTick_IRQn = -1, /*!< 15 cortex-m4 system tick interrupt */ + + /****** at32 specific interrupt numbers *********************************************************/ + WWDT_IRQn = 0, /*!< window watchdog timer interrupt */ + PVM_IRQn = 1, /*!< pvm through exint line detection interrupt */ + ERTC_IRQn = 2, /*!< ertc global interrupt */ + FLASH_IRQn = 3, /*!< flash global interrupt */ + CRM_IRQn = 4, /*!< crm global interrupt */ + EXINT1_0_IRQn = 5, /*!< external line1~0 interrupt */ + EXINT3_2_IRQn = 6, /*!< external line3~2 interrupt */ + EXINT15_4_IRQn = 7, /*!< external line15~4 interrupt */ + + ACC_IRQn = 8, /*!< acc interrupt */ + DMA1_Channel1_IRQn = 9, /*!< dma1 channel 1 global interrupt */ + DMA1_Channel3_2_IRQn = 10, /*!< dma1 channel 3~2 global interrupt */ + DMA1_Channel7_4_IRQn = 11, /*!< dma1 channel 7~4 global interrupt */ + ADC1_IRQn = 12, /*!< adc1 global interrupt */ + TMR1_BRK_OVF_TRG_HALL_IRQn = 13, /*!< tmr1 brake overflow trigger and hall interrupt */ + TMR1_CH_IRQn = 14, /*!< tmr1 channel interrupt */ + TMR2_GLOBAL_IRQn = 15, /*!< tmr2 channel interrupt */ + TMR3_GLOBAL_IRQn = 16, /*!< tmr3 global interrupt */ + TMR6_GLOBAL_IRQn = 17, /*!< tmr6 global interrupt */ + TMR7_GLOBAL_IRQn = 18, /*!< tmr7 channel interrupt */ + TMR14_GLOBAL_IRQn = 19, /*!< tmr14 global interrupt */ + TMR15_GLOBAL_IRQn = 20, /*!< tmr15 global interrupt */ + TMR16_GLOBAL_IRQn = 21, /*!< tmr16 global interrupt */ + TMR17_GLOBAL_IRQn = 22, /*!< tmr17 global interrupt */ + I2C1_EVT_IRQn = 23, /*!< i2c1 event interrupt */ + I2C2_EVT_IRQn = 24, /*!< i2c2 event interrupt */ + SPI1_IRQn = 25, /*!< spi1 global interrupt */ + SPI2_IRQn = 26, /*!< spi2 global interrupt */ + USART1_IRQn = 27, /*!< usart1 global interrupt */ + USART2_IRQn = 28, /*!< usart2 global interrupt */ + USART4_3_IRQn = 29, /*!< usart3 & usart4 global interrupt */ + CAN1_IRQn = 30, /*!< can1 global interrupt */ + OTGFS1_IRQn = 31, /*!< otgfs1 global interrupt */ + I2C1_ERR_IRQn = 32, /*!< i2c1 error interrupt */ + SPI3_IRQn = 33, /*!< spi3 global interrupt */ + I2C2_ERR_IRQn = 34, /*!< i2c2 error interrupt */ + TMR13_GLOBAL_IRQn = 35 /*!< tmr13 global interrupt */ + +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm4.h" +#include "system_at32f425.h" +#include + +/** @addtogroup Exported_types + * @{ + */ + +typedef int32_t INT32; +typedef int16_t INT16; +typedef int8_t INT8; +typedef uint32_t UINT32; +typedef uint16_t UINT16; +typedef uint8_t UINT8; + +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef const int32_t sc32; /*!< read only */ +typedef const int16_t sc16; /*!< read only */ +typedef const int8_t sc8; /*!< read only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< read only */ +typedef __I int16_t vsc16; /*!< read only */ +typedef __I int8_t vsc8; /*!< read only */ + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< read only */ +typedef const uint16_t uc16; /*!< read only */ +typedef const uint8_t uc8; /*!< read only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< read only */ +typedef __I uint16_t vuc16; /*!< read only */ +typedef __I uint8_t vuc8; /*!< read only */ + +/** + * @brief flag status + */ +typedef enum {RESET = 0, SET = !RESET} flag_status; + +/** + * @brief confirm state + */ +typedef enum {FALSE = 0, TRUE = !FALSE} confirm_state; + +/** + * @brief error status + */ +typedef enum {ERROR = 0, SUCCESS = !ERROR} error_status; + +/** + * @} + */ + +/** @addtogroup Exported_macro + * @{ + */ + +#define REG8(addr) *(volatile uint8_t *)(addr) +#define REG16(addr) *(volatile uint16_t *)(addr) +#define REG32(addr) *(volatile uint32_t *)(addr) + +#define MAKE_VALUE(reg_offset, bit_num) (uint32_t)(((reg_offset) << 16) | (bit_num & 0x1F)) + +#define PERIPH_REG(periph_base, value) REG32((periph_base + (value >> 16))) +#define PERIPH_REG_BIT(value) (0x1U << (value & 0x1F)) + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ + +#define FLASH_BASE ((uint32_t)0x08000000) +#define USD_BASE ((uint32_t)0x1FFFF800) +#define SRAM_BASE ((uint32_t)0x20000000) +#define PERIPH_BASE ((uint32_t)0x40000000) +#define DEBUG_BASE ((uint32_t)0xE0042000) + +#define APB1PERIPH_BASE (PERIPH_BASE + 0x00000) +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH1_BASE (PERIPH_BASE + 0x20000) +#define AHBPERIPH2_BASE (PERIPH_BASE + 0x8000000) + +/* apb1 bus base address */ +#define TMR2_BASE (APB1PERIPH_BASE + 0x0000) +#define TMR3_BASE (APB1PERIPH_BASE + 0x0400) +#define TMR6_BASE (APB1PERIPH_BASE + 0x1000) +#define TMR7_BASE (APB1PERIPH_BASE + 0x1400) +#define TMR13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TMR14_BASE (APB1PERIPH_BASE + 0x2000) +#define ERTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDT_BASE (APB1PERIPH_BASE + 0x2C00) +#define WDT_BASE (APB1PERIPH_BASE + 0x3000) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define USART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define ACC_BASE (APB1PERIPH_BASE + 0x6C00) +#define PWC_BASE (APB1PERIPH_BASE + 0x7000) +/* apb2 bus base address */ +#define SCFG_BASE (APB2PERIPH_BASE + 0x0000) +#define EXINT_BASE (APB2PERIPH_BASE + 0x0400) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2400) +#define TMR1_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define USART1_BASE (APB2PERIPH_BASE + 0x3800) +#define TMR15_BASE (APB2PERIPH_BASE + 0x4000) +#define TMR16_BASE (APB2PERIPH_BASE + 0x4400) +#define TMR17_BASE (APB2PERIPH_BASE + 0x4800) +/* ahb bus base address */ +#define DMA1_BASE (AHBPERIPH1_BASE + 0x0000) +#define DMA1_CHANNEL1_BASE (AHBPERIPH1_BASE + 0x0008) +#define DMA1_CHANNEL2_BASE (AHBPERIPH1_BASE + 0x001C) +#define DMA1_CHANNEL3_BASE (AHBPERIPH1_BASE + 0x0030) +#define DMA1_CHANNEL4_BASE (AHBPERIPH1_BASE + 0x0044) +#define DMA1_CHANNEL5_BASE (AHBPERIPH1_BASE + 0x0058) +#define DMA1_CHANNEL6_BASE (AHBPERIPH1_BASE + 0x006C) +#define DMA1_CHANNEL7_BASE (AHBPERIPH1_BASE + 0x0080) +#define CRM_BASE (AHBPERIPH1_BASE + 0x1000) +#define FLASH_REG_BASE (AHBPERIPH1_BASE + 0x2000) +#define CRC_BASE (AHBPERIPH1_BASE + 0x3000) +#define GPIOA_BASE (AHBPERIPH2_BASE + 0x0000) +#define GPIOB_BASE (AHBPERIPH2_BASE + 0x0400) +#define GPIOC_BASE (AHBPERIPH2_BASE + 0x0800) +#define GPIOD_BASE (AHBPERIPH2_BASE + 0x0C00) +#define GPIOF_BASE (AHBPERIPH2_BASE + 0x1400) +#define OTGFS1_BASE (PERIPH_BASE + 0x10000000) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#include "at32f425_def.h" +#include "at32f425_conf.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/cmsis/cm4/device_support/at32f425_conf_template.h b/libraries/cmsis/cm4/device_support/at32f425_conf_template.h new file mode 100644 index 0000000..f05162c --- /dev/null +++ b/libraries/cmsis/cm4/device_support/at32f425_conf_template.h @@ -0,0 +1,147 @@ +/** + ************************************************************************** + * @file at32f425_conf.h + * @brief at32f425 config header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_CONF_H +#define __AT32F425_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief in the following line adjust the value of high speed external crystal (hext) + * used in your application + * + * tip: to avoid modifying this file each time you need to use different hext, you + * can define the hext value in your toolchain compiler preprocessor. + * + */ +#if !defined HEXT_VALUE +#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed external crystal in hz */ +#endif + +/** + * @brief in the following line adjust the high speed external crystal (hext) startup + * timeout value + */ +#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */ +#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */ +#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */ + +/* module define -------------------------------------------------------------*/ +#define ACC_MODULE_ENABLED +#define CRM_MODULE_ENABLED +#define TMR_MODULE_ENABLED +#define ERTC_MODULE_ENABLED +#define GPIO_MODULE_ENABLED +#define I2C_MODULE_ENABLED +#define CAN_MODULE_ENABLED +#define USB_MODULE_ENABLED +#define USART_MODULE_ENABLED +#define PWC_MODULE_ENABLED +#define ADC_MODULE_ENABLED +#define SPI_MODULE_ENABLED +#define DMA_MODULE_ENABLED +#define DEBUG_MODULE_ENABLED +#define FLASH_MODULE_ENABLED +#define CRC_MODULE_ENABLED +#define WWDT_MODULE_ENABLED +#define WDT_MODULE_ENABLED +#define EXINT_MODULE_ENABLED +#define MISC_MODULE_ENABLED +#define SCFG_MODULE_ENABLED + +/* includes ------------------------------------------------------------------*/ +#ifdef ACC_MODULE_ENABLED +#include "at32f425_acc.h" +#endif +#ifdef CRM_MODULE_ENABLED +#include "at32f425_crm.h" +#endif +#ifdef CAN_MODULE_ENABLED +#include "at32f425_can.h" +#endif +#ifdef USB_MODULE_ENABLED +#include "at32f425_usb.h" +#endif +#ifdef TMR_MODULE_ENABLED +#include "at32f425_tmr.h" +#endif +#ifdef ERTC_MODULE_ENABLED +#include "at32f425_ertc.h" +#endif +#ifdef GPIO_MODULE_ENABLED +#include "at32f425_gpio.h" +#endif +#ifdef I2C_MODULE_ENABLED +#include "at32f425_i2c.h" +#endif +#ifdef USART_MODULE_ENABLED +#include "at32f425_usart.h" +#endif +#ifdef PWC_MODULE_ENABLED +#include "at32f425_pwc.h" +#endif +#ifdef ADC_MODULE_ENABLED +#include "at32f425_adc.h" +#endif +#ifdef SPI_MODULE_ENABLED +#include "at32f425_spi.h" +#endif +#ifdef DMA_MODULE_ENABLED +#include "at32f425_dma.h" +#endif +#ifdef DEBUG_MODULE_ENABLED +#include "at32f425_debug.h" +#endif +#ifdef FLASH_MODULE_ENABLED +#include "at32f425_flash.h" +#endif +#ifdef CRC_MODULE_ENABLED +#include "at32f425_crc.h" +#endif +#ifdef WWDT_MODULE_ENABLED +#include "at32f425_wwdt.h" +#endif +#ifdef WDT_MODULE_ENABLED +#include "at32f425_wdt.h" +#endif +#ifdef EXINT_MODULE_ENABLED +#include "at32f425_exint.h" +#endif +#ifdef MISC_MODULE_ENABLED +#include "at32f425_misc.h" +#endif +#ifdef SCFG_MODULE_ENABLED +#include "at32f425_scfg.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x4_FLASH.ld b/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x4_FLASH.ld new file mode 100644 index 0000000..dd5c31e --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x4_FLASH.ld @@ -0,0 +1,153 @@ +/* +***************************************************************************** +** +** File : AT32F425x4_FLASH.ld +** +** Abstract : Linker script for AT32F425x4 Device with +** 16KByte FLASH, 8KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** +** Environment : Arm gcc toolchain +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20002000; /* end of RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x6_FLASH.ld b/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x6_FLASH.ld new file mode 100644 index 0000000..1a7b9d1 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x6_FLASH.ld @@ -0,0 +1,153 @@ +/* +***************************************************************************** +** +** File : AT32F425x6_FLASH.ld +** +** Abstract : Linker script for AT32F425x6 Device with +** 32KByte FLASH, 20KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** +** Environment : Arm gcc toolchain +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20005000; /* end of RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld b/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld new file mode 100644 index 0000000..850d596 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/gcc/linker/AT32F425x8_FLASH.ld @@ -0,0 +1,153 @@ +/* +***************************************************************************** +** +** File : AT32F425x8_FLASH.ld +** +** Abstract : Linker script for AT32F425x8 Device with +** 64KByte FLASH, 16KByte RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** +** Environment : Arm gcc toolchain +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20005000; /* end of RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/libraries/cmsis/cm4/device_support/startup/gcc/startup_at32f425.s b/libraries/cmsis/cm4/device_support/startup/gcc/startup_at32f425.s new file mode 100644 index 0000000..38127c7 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/gcc/startup_at32f425.s @@ -0,0 +1,309 @@ +/** + ****************************************************************************** + * @file startup_at32f425.s + * @brief at32f425xx devices vector table for gcc toolchain. + * this module performs: + * - set the initial sp + * - set the initial pc == reset_handler, + * - set the vector table entries with the exceptions isr address + * - configure the clock system and the external sram to + * be used as data memory (optional, to be enabled by user) + * - branches to main in the c library (which eventually + * calls main()). + * after reset the cortex-m4 processor is in thread mode, + * priority is privileged, and the stack is set to main. + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ + +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =_sidata + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =_sdata + ldr r3, =_edata + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =_sbss + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = _ebss + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system intitialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +*******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + + /* External Interrupts */ + .word WWDT_IRQHandler /* Window Watchdog Timer */ + .word PVM_IRQHandler /* PVM through EXINT Line detect */ + .word ERTC_IRQHandler /* ERTC */ + .word FLASH_IRQHandler /* Flash */ + .word CRM_IRQHandler /* CRM */ + .word EXINT1_0_IRQHandler /* EXINT Line 1 & 0 */ + .word EXINT3_2_IRQHandler /* EXINT Line 3 & 2 */ + .word EXINT15_4_IRQHandler /* EXINT Line 15 ~ 4 */ + .word ACC_IRQHandler /* ACC */ + .word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */ + .word DMA1_Channel3_2_IRQHandler /* DMA1 Channel 3 & 2 */ + .word DMA1_Channel7_4_IRQHandler /* DMA1 Channel 7 & 4 */ + .word ADC1_IRQHandler /* ADC1 */ + .word TMR1_BRK_OVF_TRG_HALL_IRQHandler /* TMR1 brake overflow trigger and hall */ + .word TMR1_CH_IRQHandler /* TMR1 channel */ + .word TMR2_GLOBAL_IRQHandler /* TMR2 */ + .word TMR3_GLOBAL_IRQHandler /* TMR3 */ + .word TMR6_GLOBAL_IRQHandler /* TMR6 */ + .word TMR7_GLOBAL_IRQHandler /* TMR7 */ + .word TMR14_GLOBAL_IRQHandler /* TMR14 */ + .word TMR15_GLOBAL_IRQHandler /* TMR15 */ + .word TMR16_GLOBAL_IRQHandler /* TMR16 */ + .word TMR17_GLOBAL_IRQHandler /* TMR17 */ + .word I2C1_EVT_IRQHandler /* I2C1 Event */ + .word I2C2_EVT_IRQHandler /* I2C2 Event */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART4_3_IRQHandler /* USART3 & USART4 */ + .word CAN1_IRQHandler /* CAN1 */ + .word OTGFS1_IRQHandler /* OTGFS1 */ + .word I2C1_ERR_IRQHandler /* I2C1 Error */ + .word SPI3_IRQHandler /* SPI3 */ + .word I2C2_ERR_IRQHandler /* I2C2 Error */ + .word TMR13_GLOBAL_IRQHandler /* TMR13 */ +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDT_IRQHandler + .thumb_set WWDT_IRQHandler,Default_Handler + + .weak PVM_IRQHandler + .thumb_set PVM_IRQHandler,Default_Handler + + .weak ERTC_IRQHandler + .thumb_set ERTC_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak CRM_IRQHandler + .thumb_set CRM_IRQHandler,Default_Handler + + .weak EXINT1_0_IRQHandler + .thumb_set EXINT1_0_IRQHandler,Default_Handler + + .weak EXINT3_2_IRQHandler + .thumb_set EXINT3_2_IRQHandler,Default_Handler + + .weak EXINT15_4_IRQHandler + .thumb_set EXINT15_4_IRQHandler,Default_Handler + + .weak ACC_IRQHandler + .thumb_set ACC_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel3_2_IRQHandler + .thumb_set DMA1_Channel3_2_IRQHandler,Default_Handler + + .weak DMA1_Channel7_4_IRQHandler + .thumb_set DMA1_Channel7_4_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak TMR1_BRK_OVF_TRG_HALL_IRQHandler + .thumb_set TMR1_BRK_OVF_TRG_HALL_IRQHandler,Default_Handler + + .weak TMR1_CH_IRQHandler + .thumb_set TMR1_CH_IRQHandler,Default_Handler + + .weak TMR2_GLOBAL_IRQHandler + .thumb_set TMR2_GLOBAL_IRQHandler,Default_Handler + + .weak TMR3_GLOBAL_IRQHandler + .thumb_set TMR3_GLOBAL_IRQHandler,Default_Handler + + .weak TMR6_GLOBAL_IRQHandler + .thumb_set TMR6_GLOBAL_IRQHandler,Default_Handler + + .weak TMR7_GLOBAL_IRQHandler + .thumb_set TMR7_GLOBAL_IRQHandler,Default_Handler + + .weak TMR14_GLOBAL_IRQHandler + .thumb_set TMR14_GLOBAL_IRQHandler,Default_Handler + + .weak TMR15_GLOBAL_IRQHandler + .thumb_set TMR15_GLOBAL_IRQHandler,Default_Handler + + .weak TMR16_GLOBAL_IRQHandler + .thumb_set TMR16_GLOBAL_IRQHandler,Default_Handler + + .weak TMR17_GLOBAL_IRQHandler + .thumb_set TMR17_GLOBAL_IRQHandler,Default_Handler + + .weak I2C1_EVT_IRQHandler + .thumb_set I2C1_EVT_IRQHandler,Default_Handler + + .weak I2C2_EVT_IRQHandler + .thumb_set I2C2_EVT_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART4_3_IRQHandler + .thumb_set USART4_3_IRQHandler,Default_Handler + + .weak CAN1_IRQHandler + .thumb_set CAN1_IRQHandler,Default_Handler + + .weak OTGFS1_IRQHandler + .thumb_set OTGFS1_IRQHandler,Default_Handler + + .weak I2C1_ERR_IRQHandler + .thumb_set I2C1_ERR_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak I2C2_ERR_IRQHandler + .thumb_set I2C2_ERR_IRQHandler,Default_Handler + + .weak TMR13_GLOBAL_IRQHandler + .thumb_set TMR13_GLOBAL_IRQHandler,Default_Handler diff --git a/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x4.icf b/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x4.icf new file mode 100644 index 0000000..a5da654 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x4.icf @@ -0,0 +1,30 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x08003FFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x1000; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x6.icf b/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x6.icf new file mode 100644 index 0000000..f367672 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x6.icf @@ -0,0 +1,30 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x08007FFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20004FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x1000; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x8.icf b/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x8.icf new file mode 100644 index 0000000..4247768 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/iar/linker/AT32F425x8.icf @@ -0,0 +1,30 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0800FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20004FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x1000; +define symbol __ICFEDIT_size_heap__ = 0x1000; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; \ No newline at end of file diff --git a/libraries/cmsis/cm4/device_support/startup/iar/startup_at32f425.s b/libraries/cmsis/cm4/device_support/startup/iar/startup_at32f425.s new file mode 100644 index 0000000..82df3f1 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/iar/startup_at32f425.s @@ -0,0 +1,320 @@ +;************************************************************************** +;* @file startup_at32f425.s +;* @brief at32f425 startup file for IAR Systems +;************************************************************************** +; + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDT_IRQHandler ; Window Watchdog Timer + DCD PVM_IRQHandler ; PVM through EXINT Line detect + DCD ERTC_IRQHandler ; ERTC + DCD FLASH_IRQHandler ; Flash + DCD CRM_IRQHandler ; CRM + DCD EXINT1_0_IRQHandler ; EXINT Line 1 & 0 + DCD EXINT3_2_IRQHandler ; EXINT Line 3 & 2 + DCD EXINT15_4_IRQHandler ; EXINT Line 15 ~ 4 + DCD ACC_IRQHandler ; ACC + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel3_2_IRQHandler ; DMA1 Channel 3 & 2 + DCD DMA1_Channel7_4_IRQHandler ; DMA1 Channel 7 & 4 + DCD ADC1_IRQHandler ; ADC1 + DCD TMR1_BRK_OVF_TRG_HALL_IRQHandler ; TMR1 brake overflow trigger and hall + DCD TMR1_CH_IRQHandler ; TMR1 channel + DCD TMR2_GLOBAL_IRQHandler ; TMR2 + DCD TMR3_GLOBAL_IRQHandler ; TMR3 + DCD TMR6_GLOBAL_IRQHandler ; TMR6 + DCD TMR7_GLOBAL_IRQHandler ; TMR7 + DCD TMR14_GLOBAL_IRQHandler ; TMR14 + DCD TMR15_GLOBAL_IRQHandler ; TMR15 + DCD TMR16_GLOBAL_IRQHandler ; TMR16 + DCD TMR17_GLOBAL_IRQHandler ; TMR17 + DCD I2C1_EVT_IRQHandler ; I2C1 Event + DCD I2C2_EVT_IRQHandler ; I2C2 Event + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART4_3_IRQHandler ; USART3 & USART4 + DCD CAN1_IRQHandler ; CAN1 + DCD OTGFS1_IRQHandler ; OTGFS1 + DCD I2C1_ERR_IRQHandler ; I2C1 Error + DCD SPI3_IRQHandler ; SPI3 + DCD I2C2_ERR_IRQHandler ; I2C2 Error + DCD TMR13_GLOBAL_IRQHandler ; TMR13 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WWDT_IRQHandler + B WWDT_IRQHandler + + PUBWEAK PVM_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PVM_IRQHandler + B PVM_IRQHandler + + PUBWEAK ERTC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ERTC_IRQHandler + B ERTC_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK CRM_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CRM_IRQHandler + B CRM_IRQHandler + + PUBWEAK EXINT1_0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +EXINT1_0_IRQHandler + B EXINT1_0_IRQHandler + + PUBWEAK EXINT3_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +EXINT3_2_IRQHandler + B EXINT3_2_IRQHandler + + PUBWEAK EXINT15_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +EXINT15_4_IRQHandler + B EXINT15_4_IRQHandler + + PUBWEAK ACC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ACC_IRQHandler + B ACC_IRQHandler + + PUBWEAK DMA1_Channel1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +DMA1_Channel1_IRQHandler + B DMA1_Channel1_IRQHandler + + PUBWEAK DMA1_Channel3_2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +DMA1_Channel3_2_IRQHandler + B DMA1_Channel3_2_IRQHandler + + PUBWEAK DMA1_Channel7_4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +DMA1_Channel7_4_IRQHandler + B DMA1_Channel7_4_IRQHandler + + PUBWEAK ADC1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ADC1_IRQHandler + B ADC1_IRQHandler + + PUBWEAK TMR1_BRK_OVF_TRG_HALL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR1_BRK_OVF_TRG_HALL_IRQHandler + B TMR1_BRK_OVF_TRG_HALL_IRQHandler + + PUBWEAK TMR1_CH_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR1_CH_IRQHandler + B TMR1_CH_IRQHandler + + PUBWEAK TMR2_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR2_GLOBAL_IRQHandler + B TMR2_GLOBAL_IRQHandler + + PUBWEAK TMR3_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR3_GLOBAL_IRQHandler + B TMR3_GLOBAL_IRQHandler + + PUBWEAK TMR6_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR6_GLOBAL_IRQHandler + B TMR6_GLOBAL_IRQHandler + + PUBWEAK TMR7_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR7_GLOBAL_IRQHandler + B TMR7_GLOBAL_IRQHandler + + PUBWEAK TMR14_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR14_GLOBAL_IRQHandler + B TMR14_GLOBAL_IRQHandler + + PUBWEAK TMR15_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR15_GLOBAL_IRQHandler + B TMR15_GLOBAL_IRQHandler + + PUBWEAK TMR16_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR16_GLOBAL_IRQHandler + B TMR16_GLOBAL_IRQHandler + + PUBWEAK TMR17_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR17_GLOBAL_IRQHandler + B TMR17_GLOBAL_IRQHandler + + PUBWEAK I2C1_EVT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2C1_EVT_IRQHandler + B I2C1_EVT_IRQHandler + + PUBWEAK I2C2_EVT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2C2_EVT_IRQHandler + B I2C2_EVT_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK SPI2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPI2_IRQHandler + B SPI2_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK USART4_3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +USART4_3_IRQHandler + B USART4_3_IRQHandler + + PUBWEAK CAN1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CAN1_IRQHandler + B CAN1_IRQHandler + + PUBWEAK OTGFS1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +OTGFS1_IRQHandler + B OTGFS1_IRQHandler + + PUBWEAK I2C1_ERR_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2C1_ERR_IRQHandler + B I2C1_ERR_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK I2C2_ERR_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2C2_ERR_IRQHandler + B I2C2_ERR_IRQHandler + + PUBWEAK TMR13_GLOBAL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TMR13_GLOBAL_IRQHandler + B TMR13_GLOBAL_IRQHandler + + END diff --git a/libraries/cmsis/cm4/device_support/startup/mdk/startup_at32f425.s b/libraries/cmsis/cm4/device_support/startup/mdk/startup_at32f425.s new file mode 100644 index 0000000..34d4d69 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/startup/mdk/startup_at32f425.s @@ -0,0 +1,261 @@ +;************************************************************************** +;* @file startup_at32f425.s +;* @brief startup_at32f425 startup file for keil +;* <<< Use Configuration Wizard in Context Menu >>> +;************************************************************************** +; + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDT_IRQHandler ; Window Watchdog Timer + DCD PVM_IRQHandler ; PVM through EXINT Line detect + DCD ERTC_IRQHandler ; ERTC + DCD FLASH_IRQHandler ; Flash + DCD CRM_IRQHandler ; CRM + DCD EXINT1_0_IRQHandler ; EXINT Line 1 & 0 + DCD EXINT3_2_IRQHandler ; EXINT Line 3 & 2 + DCD EXINT15_4_IRQHandler ; EXINT Line 15 ~ 4 + DCD ACC_IRQHandler ; ACC + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel3_2_IRQHandler ; DMA1 Channel 3 & 2 + DCD DMA1_Channel7_4_IRQHandler ; DMA1 Channel 7 & 4 + DCD ADC1_IRQHandler ; ADC1 + DCD TMR1_BRK_OVF_TRG_HALL_IRQHandler ; TMR1 brake overflow trigger and hall + DCD TMR1_CH_IRQHandler ; TMR1 channel + DCD TMR2_GLOBAL_IRQHandler ; TMR2 + DCD TMR3_GLOBAL_IRQHandler ; TMR3 + DCD TMR6_GLOBAL_IRQHandler ; TMR6 + DCD TMR7_GLOBAL_IRQHandler ; TMR7 + DCD TMR14_GLOBAL_IRQHandler ; TMR14 + DCD TMR15_GLOBAL_IRQHandler ; TMR15 + DCD TMR16_GLOBAL_IRQHandler ; TMR16 + DCD TMR17_GLOBAL_IRQHandler ; TMR17 + DCD I2C1_EVT_IRQHandler ; I2C1 Event + DCD I2C2_EVT_IRQHandler ; I2C2 Event + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART4_3_IRQHandler ; USART3 & USART4 + DCD CAN1_IRQHandler ; CAN1 + DCD OTGFS1_IRQHandler ; OTGFS1 + DCD I2C1_ERR_IRQHandler ; I2C1 Error + DCD SPI3_IRQHandler ; SPI3 + DCD I2C2_ERR_IRQHandler ; I2C2 Error + DCD TMR13_GLOBAL_IRQHandler ; TMR13 +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + EXPORT WWDT_IRQHandler [WEAK] + EXPORT PVM_IRQHandler [WEAK] + EXPORT ERTC_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT CRM_IRQHandler [WEAK] + EXPORT EXINT1_0_IRQHandler [WEAK] + EXPORT EXINT3_2_IRQHandler [WEAK] + EXPORT EXINT15_4_IRQHandler [WEAK] + EXPORT ACC_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel3_2_IRQHandler [WEAK] + EXPORT DMA1_Channel7_4_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT TMR1_BRK_OVF_TRG_HALL_IRQHandler [WEAK] + EXPORT TMR1_CH_IRQHandler [WEAK] + EXPORT TMR2_GLOBAL_IRQHandler [WEAK] + EXPORT TMR3_GLOBAL_IRQHandler [WEAK] + EXPORT TMR6_GLOBAL_IRQHandler [WEAK] + EXPORT TMR7_GLOBAL_IRQHandler [WEAK] + EXPORT TMR14_GLOBAL_IRQHandler [WEAK] + EXPORT TMR15_GLOBAL_IRQHandler [WEAK] + EXPORT TMR16_GLOBAL_IRQHandler [WEAK] + EXPORT TMR17_GLOBAL_IRQHandler [WEAK] + EXPORT I2C1_EVT_IRQHandler [WEAK] + EXPORT I2C2_EVT_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART4_3_IRQHandler [WEAK] + EXPORT CAN1_IRQHandler [WEAK] + EXPORT OTGFS1_IRQHandler [WEAK] + EXPORT I2C1_ERR_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT I2C2_ERR_IRQHandler [WEAK] + EXPORT TMR13_GLOBAL_IRQHandler [WEAK] +WWDT_IRQHandler +PVM_IRQHandler +ERTC_IRQHandler +FLASH_IRQHandler +CRM_IRQHandler +EXINT1_0_IRQHandler +EXINT3_2_IRQHandler +EXINT15_4_IRQHandler +ACC_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel3_2_IRQHandler +DMA1_Channel7_4_IRQHandler +ADC1_IRQHandler +TMR1_BRK_OVF_TRG_HALL_IRQHandler +TMR1_CH_IRQHandler +TMR2_GLOBAL_IRQHandler +TMR3_GLOBAL_IRQHandler +TMR6_GLOBAL_IRQHandler +TMR7_GLOBAL_IRQHandler +TMR14_GLOBAL_IRQHandler +TMR15_GLOBAL_IRQHandler +TMR16_GLOBAL_IRQHandler +TMR17_GLOBAL_IRQHandler +I2C1_EVT_IRQHandler +I2C2_EVT_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART4_3_IRQHandler +CAN1_IRQHandler +OTGFS1_IRQHandler +I2C1_ERR_IRQHandler +SPI3_IRQHandler +I2C2_ERR_IRQHandler +TMR13_GLOBAL_IRQHandler + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END diff --git a/libraries/cmsis/cm4/device_support/system_at32f425.c b/libraries/cmsis/cm4/device_support/system_at32f425.c new file mode 100644 index 0000000..4963135 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/system_at32f425.c @@ -0,0 +1,215 @@ +/** + ************************************************************************** + * @file system_at32f425.c + * @brief contains all the functions for cmsis cortex-m4 system source file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup AT32F425_system + * @{ + */ + +#include "at32f425.h" + +/** @addtogroup AT32F425_system_private_defines + * @{ + */ +#define VECT_TAB_OFFSET 0x0 /*!< vector table base offset field. this value must be a multiple of 0x200. */ +/** + * @} + */ + +/** @addtogroup AT32F425_system_private_variables + * @{ + */ +unsigned int system_core_clock = HICK_VALUE; /*!< system clock frequency (core clock) */ +/** + * @} + */ + +/** @addtogroup AT32F425_system_private_functions + * @{ + */ + +/** + * @brief setup the microcontroller system + * initialize the flash interface. + * @note this function should be used only after reset. + * @param none + * @retval none + */ +void SystemInit (void) +{ + /* reset the crm clock configuration to the default reset state(for debug purpose) */ + /* set hicken bit */ + CRM->ctrl_bit.hicken = TRUE; + + /* wait hick stable */ + while(CRM->ctrl_bit.hickstbl != SET); + + /* hick used as system clock */ + CRM->cfg_bit.sclksel = CRM_SCLK_HICK; + + /* wait sclk switch status */ + while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK); + + /* reset hexten, hextbyps, cfden and pllen bits */ + CRM->ctrl &= ~(0x010D0000U); + + /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv, + clkout pllrcs, pllhextdiv, pllmult, usbdiv and pllrange bits */ + CRM->cfg = 0; + + /* reset pllfr, pllms, pllns and pllfref bits */ + CRM->pll = (0x00001F10U); + + /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */ + CRM->misc1 = 0x00100000; + + /* disable all interrupts enable and clear pending bits */ + CRM->clkint = 0x009F0000; + +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* vector table relocation in internal sram. */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* vector table relocation in internal flash. */ +#endif +} + +/** + * @brief update system_core_clock variable according to clock register values. + * the system_core_clock variable contains the core clock (hclk), it can + * be used by the user application to setup the systick timer or configure + * other parameters. + * @param none + * @retval none + */ +void system_core_clock_update(void) +{ + uint32_t pll_mult = 0, pll_mult_h = 0, pll_clock_source = 0, temp = 0, div_value = 0; + uint32_t pllrcsfreq = 0, pll_ms = 0, pll_ns = 0, pll_fr = 0; + crm_sclk_type sclk_source; + + static const uint8_t sys_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + + /* get sclk source */ + sclk_source = crm_sysclk_switch_status_get(); + + switch(sclk_source) + { + case CRM_SCLK_HICK: + if(((CRM->misc2_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET)) + system_core_clock = HICK_VALUE * 6; + else + system_core_clock = HICK_VALUE; + break; + case CRM_SCLK_HEXT: + system_core_clock = HEXT_VALUE; + break; + case CRM_SCLK_PLL: + pll_clock_source = CRM->cfg_bit.pllrcs; + if(CRM->pll_bit.pllcfgen == FALSE) + { + /* get multiplication factor */ + pll_mult = CRM->cfg_bit.pllmult_l; + pll_mult_h = CRM->cfg_bit.pllmult_h; + /* process high bits */ + if((pll_mult_h != 0U) || (pll_mult == 15U)){ + pll_mult += ((16U * pll_mult_h) + 1U); + } + else + { + pll_mult += 2U; + } + + if (pll_clock_source == 0x00) + { + /* hick divided by 2 selected as pll clock entry */ + system_core_clock = (HICK_VALUE >> 1) * pll_mult; + } + else + { + /* hext selected as pll clock entry */ + if (CRM->cfg_bit.pllhextdiv != RESET) + { + /* hext clock divided by 2 */ + system_core_clock = (HEXT_VALUE / 2) * pll_mult; + } + else + { + system_core_clock = HEXT_VALUE * pll_mult; + } + } + } + else + { + pll_ms = CRM->pll_bit.pllms; + pll_ns = CRM->pll_bit.pllns; + pll_fr = CRM->pll_bit.pllfr; + + if (pll_clock_source == 0x00) + { + /* hick divided by 2 selected as pll clock entry */ + pllrcsfreq = (HICK_VALUE >> 1); + } + else + { + /* hext selected as pll clock entry */ + if (CRM->cfg_bit.pllhextdiv != RESET) + { + /* hext clock divided by 2 */ + pllrcsfreq = (HEXT_VALUE / 2); + } + else + { + pllrcsfreq = HEXT_VALUE; + } + } + system_core_clock = (uint32_t)(((uint64_t)pllrcsfreq * pll_ns) / (pll_ms * (0x1 << pll_fr))); + } + break; + default: + system_core_clock = HICK_VALUE; + break; + } + + /* compute sclk, ahbclk frequency */ + /* get ahb division */ + temp = CRM->cfg_bit.ahbdiv; + div_value = sys_ahb_div_table[temp]; + /* ahbclk frequency */ + system_core_clock = system_core_clock >> div_value; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/libraries/cmsis/cm4/device_support/system_at32f425.h b/libraries/cmsis/cm4/device_support/system_at32f425.h new file mode 100644 index 0000000..d70b5c9 --- /dev/null +++ b/libraries/cmsis/cm4/device_support/system_at32f425.h @@ -0,0 +1,85 @@ +/** + ************************************************************************** + * @file system_at32f425.h + * @brief cmsis cortex-m4 system header file. + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#ifndef __SYSTEM_AT32F425_H +#define __SYSTEM_AT32F425_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup AT32F425_system + * @{ + */ + +/** @defgroup AT32F425_system_clock_stable_definition + * @{ + */ + +#define HEXT_STABLE_DELAY (5000u) +#define PLL_STABLE_DELAY (500u) +#define SystemCoreClock system_core_clock + +/** + * @} + */ + +/** @defgroup AT32F425_system_exported_variables + * @{ + */ + +extern unsigned int system_core_clock; /*!< system clock frequency (core clock) */ + +/** + * @} + */ + +/** @defgroup AT32F425_system_exported_functions + * @{ + */ + +extern void SystemInit(void); +extern void system_core_clock_update(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_acc.h b/libraries/drivers/inc/at32f425_acc.h new file mode 100644 index 0000000..321ba56 --- /dev/null +++ b/libraries/drivers/inc/at32f425_acc.h @@ -0,0 +1,201 @@ +/** + ************************************************************************** + * @file at32f425_acc.h + * @brief at32f425 acc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_ACC_H +#define __AT32F425_ACC_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup ACC + * @{ + */ + +/** @defgroup ACC_exported_constants + * @{ + */ + +#define ACC_CAL_HICKCAL ((uint16_t)0x0000) /*!< acc hick calibration */ +#define ACC_CAL_HICKTRIM ((uint16_t)0x0002) /*!< acc hick trim */ + +#define ACC_RSLOST_FLAG ((uint16_t)0x0002) /*!< acc reference signal lost error flag */ +#define ACC_CALRDY_FLAG ((uint16_t)0x0001) /*!< acc internal high-speed clock calibration ready error flag */ + +#define ACC_CALRDYIEN_INT ((uint16_t)0x0020) /*!< acc internal high-speed clock calibration ready interrupt enable */ +#define ACC_EIEN_INT ((uint16_t)0x0010) /*!< acc reference signal lost interrupt enable */ + +/** + * @} + */ + +/** @defgroup ACC_exported_types + * @{ + */ + +/** + * @brief type define acc register all + */ +typedef struct +{ + + /** + * @brief acc sts register, offset:0x00 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t calrdy : 1; /* [0] */ + __IO uint32_t rslost : 1; /* [1] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } sts_bit; + }; + + /** + * @brief acc ctrl1 register, offset:0x04 + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t calon : 1; /* [0] */ + __IO uint32_t entrim : 1; /* [1] */ + __IO uint32_t reserved1 : 2; /* [3:2] */ + __IO uint32_t eien : 1; /* [4] */ + __IO uint32_t calrdyien : 1; /* [5] */ + __IO uint32_t reserved2 : 2; /* [7:6] */ + __IO uint32_t step : 4; /* [11:8] */ + __IO uint32_t reserved3 : 20;/* [31:12] */ + } ctrl1_bit; + }; + + /** + * @brief acc ctrl2 register, offset:0x08 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t hickcal : 8; /* [7:0] */ + __IO uint32_t hicktrim : 6; /* [13:8] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } ctrl2_bit; + }; + + /** + * @brief acc acc_c1 register, offset:0x0C + */ + union + { + __IO uint32_t c1; + struct + { + __IO uint32_t c1 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c1_bit; + }; + + /** + * @brief acc acc_c2 register, offset:0x10 + */ + union + { + __IO uint32_t c2; + struct + { + __IO uint32_t c2 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c2_bit; + }; + + /** + * @brief acc acc_c3 register, offset:0x14 + */ + union + { + __IO uint32_t c3; + struct + { + __IO uint32_t c3 : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } c3_bit; + }; +} acc_type; + +/** + * @} + */ + +#define ACC ((acc_type *) ACC_BASE) + +/** @defgroup ACC_exported_functions + * @{ + */ + +void acc_calibration_mode_enable(uint16_t acc_trim, confirm_state new_state); +void acc_step_set(uint8_t step_value); +void acc_interrupt_enable(uint16_t acc_int, confirm_state new_state); +uint8_t acc_hicktrim_get(void); +uint8_t acc_hickcal_get(void); +void acc_write_c1(uint16_t acc_c1_value); +void acc_write_c2(uint16_t acc_c2_value); +void acc_write_c3(uint16_t acc_c3_value); +uint16_t acc_read_c1(void); +uint16_t acc_read_c2(void); +uint16_t acc_read_c3(void); +flag_status acc_flag_get(uint16_t acc_flag); +flag_status acc_interrupt_flag_get(uint16_t acc_flag); +void acc_flag_clear(uint16_t acc_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_adc.h b/libraries/drivers/inc/at32f425_adc.h new file mode 100644 index 0000000..e983e51 --- /dev/null +++ b/libraries/drivers/inc/at32f425_adc.h @@ -0,0 +1,658 @@ +/** + ************************************************************************** + * @file at32f425_adc.h + * @brief at32f425 adc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_ADC_H +#define __AT32F425_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/** @defgroup ADC_interrupts_definition + * @brief adc interrupt + * @{ + */ + +#define ADC_CCE_INT ((uint32_t)0x00000020) /*!< channels conversion end interrupt */ +#define ADC_VMOR_INT ((uint32_t)0x00000040) /*!< voltage monitoring out of range interrupt */ +#define ADC_PCCE_INT ((uint32_t)0x00000080) /*!< preempt channels conversion end interrupt */ + +/** + * @} + */ + +/** @defgroup ADC_flags_definition + * @brief adc flag + * @{ + */ + +#define ADC_VMOR_FLAG ((uint8_t)0x01) /*!< voltage monitoring out of range flag */ +#define ADC_CCE_FLAG ((uint8_t)0x02) /*!< channels conversion end flag */ +#define ADC_PCCE_FLAG ((uint8_t)0x04) /*!< preempt channels conversion end flag */ +#define ADC_PCCS_FLAG ((uint8_t)0x08) /*!< preempt channel conversion start flag */ +#define ADC_OCCS_FLAG ((uint8_t)0x10) /*!< ordinary channel conversion start flag */ + +/** + * @} + */ + +/** @defgroup ADC_exported_types + * @{ + */ + +/** + * @brief adc data align type + */ +typedef enum +{ + ADC_RIGHT_ALIGNMENT = 0x00, /*!< data right alignment */ + ADC_LEFT_ALIGNMENT = 0x01 /*!< data left alignment */ +} adc_data_align_type; + +/** + * @brief adc channel select type + */ +typedef enum +{ + ADC_CHANNEL_0 = 0x00, /*!< adc channel 0 */ + ADC_CHANNEL_1 = 0x01, /*!< adc channel 1 */ + ADC_CHANNEL_2 = 0x02, /*!< adc channel 2 */ + ADC_CHANNEL_3 = 0x03, /*!< adc channel 3 */ + ADC_CHANNEL_4 = 0x04, /*!< adc channel 4 */ + ADC_CHANNEL_5 = 0x05, /*!< adc channel 5 */ + ADC_CHANNEL_6 = 0x06, /*!< adc channel 6 */ + ADC_CHANNEL_7 = 0x07, /*!< adc channel 7 */ + ADC_CHANNEL_8 = 0x08, /*!< adc channel 8 */ + ADC_CHANNEL_9 = 0x09, /*!< adc channel 9 */ + ADC_CHANNEL_10 = 0x0A, /*!< adc channel 10 */ + ADC_CHANNEL_11 = 0x0B, /*!< adc channel 11 */ + ADC_CHANNEL_12 = 0x0C, /*!< adc channel 12 */ + ADC_CHANNEL_13 = 0x0D, /*!< adc channel 13 */ + ADC_CHANNEL_14 = 0x0E, /*!< adc channel 14 */ + ADC_CHANNEL_15 = 0x0F, /*!< adc channel 15 */ + ADC_CHANNEL_16 = 0x10, /*!< adc channel 16 */ + ADC_CHANNEL_17 = 0x11 /*!< adc channel 17 */ +} adc_channel_select_type; + +/** + * @brief adc sampletime select type + */ +typedef enum +{ + ADC_SAMPLETIME_1_5 = 0x00, /*!< adc sample time 1.5 cycle */ + ADC_SAMPLETIME_7_5 = 0x01, /*!< adc sample time 7.5 cycle */ + ADC_SAMPLETIME_13_5 = 0x02, /*!< adc sample time 13.5 cycle */ + ADC_SAMPLETIME_28_5 = 0x03, /*!< adc sample time 28.5 cycle */ + ADC_SAMPLETIME_41_5 = 0x04, /*!< adc sample time 41.5 cycle */ + ADC_SAMPLETIME_55_5 = 0x05, /*!< adc sample time 55.5 cycle */ + ADC_SAMPLETIME_71_5 = 0x06, /*!< adc sample time 71.5 cycle */ + ADC_SAMPLETIME_239_5 = 0x07 /*!< adc sample time 239.5 cycle */ +} adc_sampletime_select_type; + +/** + * @brief adc ordinary group trigger event select type + */ +typedef enum +{ + /*adc1 ordinary trigger event*/ + ADC12_ORDINARY_TRIG_TMR1TRGOUT = 0x00, /*!< timer1 trgout as trigger source of adc1 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR1CH4 = 0x01, /*!< timer1 ch4 event as trigger source of adc1 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR2TRGOUT = 0x02, /*!< timer2 trgout as trigger source of adc1 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR3TRGOUT = 0x03, /*!< timer3 trgout event as trigger source of adc1 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR15TRGOUT = 0x04, /*!< timer15 trgout event as trigger source of adc1 ordinary sequence */ + ADC12_ORDINARY_TRIG_TMR1CH1 = 0x05, /*!< timer1 ch1 event as trigger source of adc1 ordinary sequence */ + ADC12_ORDINARY_TRIG_EXINT11 = 0x06, /*!< exint line11 event as trigger source of adc1 ordinary sequence */ + ADC12_ORDINARY_TRIG_SOFTWARE = 0x07, /*!< software(OCSWTRG) control bit as trigger source of adc1 ordinary sequence */ + } adc_ordinary_trig_select_type; + +/** + * @brief adc preempt group trigger event select type + */ +typedef enum +{ + /*adc1 preempt trigger event*/ + ADC12_PREEMPT_TRIG_TMR1CH2 = 0x00, /*!< timer1 ch2 event as trigger source of adc1 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR1CH3 = 0x01, /*!< timer1 ch3 event as trigger source of adc1 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR2CH4 = 0x02, /*!< timer2 ch4 event as trigger source of adc1 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR3CH4 = 0x03, /*!< timer3 ch4 event as trigger source of adc1 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR15CH1 = 0x04, /*!< timer15 ch1 event as trigger source of adc1 preempt sequence */ + ADC12_PREEMPT_TRIG_TMR6TRGOUT = 0x05, /*!< timer6 trgout event as trigger source of adc1 preempt sequence */ + ADC12_PREEMPT_TRIG_EXINT15 = 0x06, /*!< exint line15 event as trigger source of adc1 preempt sequence */ + ADC12_PREEMPT_TRIG_SOFTWARE = 0x07, /*!< software(PCSWTRG) control bit as trigger source of adc1 preempt sequence */ +} adc_preempt_trig_select_type; + +/** + * @brief adc preempt channel type + */ +typedef enum +{ + ADC_PREEMPT_CHANNEL_1 = 0x00, /*!< adc preempt channel 1 */ + ADC_PREEMPT_CHANNEL_2 = 0x01, /*!< adc preempt channel 2 */ + ADC_PREEMPT_CHANNEL_3 = 0x02, /*!< adc preempt channel 3 */ + ADC_PREEMPT_CHANNEL_4 = 0x03 /*!< adc preempt channel 4 */ +} adc_preempt_channel_type; + +/** + * @brief adc voltage_monitoring type + */ +typedef enum +{ + ADC_VMONITOR_SINGLE_ORDINARY = 0x00800200, /*!< voltage_monitoring on a single ordinary channel */ + ADC_VMONITOR_SINGLE_PREEMPT = 0x00400200, /*!< voltage_monitoring on a single preempt channel */ + ADC_VMONITOR_SINGLE_ORDINARY_PREEMPT = 0x00C00200, /*!< voltage_monitoring on a single ordinary or preempt channel */ + ADC_VMONITOR_ALL_ORDINARY = 0x00800000, /*!< voltage_monitoring on all ordinary channel */ + ADC_VMONITOR_ALL_PREEMPT = 0x00400000, /*!< voltage_monitoring on all preempt channel */ + ADC_VMONITOR_ALL_ORDINARY_PREEMPT = 0x00C00000, /*!< voltage_monitoring on all ordinary and preempt channel */ + ADC_VMONITOR_NONE = 0x00000000 /*!< no channel guarded by the voltage_monitoring */ +} adc_voltage_monitoring_type; + +/** + * @brief adc oversample ratio type + */ +typedef enum +{ + ADC_OVERSAMPLE_RATIO_2 = 0x00, /*!< adc oversample ratio 2 */ + ADC_OVERSAMPLE_RATIO_4 = 0x01, /*!< adc oversample ratio 4 */ + ADC_OVERSAMPLE_RATIO_8 = 0x02, /*!< adc oversample ratio 8 */ + ADC_OVERSAMPLE_RATIO_16 = 0x03, /*!< adc oversample ratio 16 */ + ADC_OVERSAMPLE_RATIO_32 = 0x04, /*!< adc oversample ratio 32 */ + ADC_OVERSAMPLE_RATIO_64 = 0x05, /*!< adc oversample ratio 64 */ + ADC_OVERSAMPLE_RATIO_128 = 0x06, /*!< adc oversample ratio 128 */ + ADC_OVERSAMPLE_RATIO_256 = 0x07 /*!< adc oversample ratio 256 */ +} adc_oversample_ratio_type; + +/** + * @brief adc oversample shift type + */ +typedef enum +{ + ADC_OVERSAMPLE_SHIFT_0 = 0x00, /*!< adc oversample shift 0 */ + ADC_OVERSAMPLE_SHIFT_1 = 0x01, /*!< adc oversample shift 1 */ + ADC_OVERSAMPLE_SHIFT_2 = 0x02, /*!< adc oversample shift 2 */ + ADC_OVERSAMPLE_SHIFT_3 = 0x03, /*!< adc oversample shift 3 */ + ADC_OVERSAMPLE_SHIFT_4 = 0x04, /*!< adc oversample shift 4 */ + ADC_OVERSAMPLE_SHIFT_5 = 0x05, /*!< adc oversample shift 5 */ + ADC_OVERSAMPLE_SHIFT_6 = 0x06, /*!< adc oversample shift 6 */ + ADC_OVERSAMPLE_SHIFT_7 = 0x07, /*!< adc oversample shift 7 */ + ADC_OVERSAMPLE_SHIFT_8 = 0x08 /*!< adc oversample shift 8 */ +} adc_oversample_shift_type; + +/** + * @brief adc ordinary oversample recover type + */ +typedef enum +{ + ADC_OVERSAMPLE_CONTINUE = 0x00, /*!< continue mode:when preempt triggered,oversampling is temporary stopped and continued after preempt sequence */ + ADC_OVERSAMPLE_RESTART = 0x01 /*!< restart mode:when preempt triggered,oversampling is aborted and resumed from start after preempt sequence */ +} adc_ordinary_oversample_restart_type; + + +/** + * @brief adc base config type + */ +typedef struct +{ + confirm_state sequence_mode; /*!< adc sequence mode */ + confirm_state repeat_mode; /*!< adc repeat mode */ + adc_data_align_type data_align; /*!< adc data alignment */ + uint8_t ordinary_channel_length; /*!< adc ordinary channel sequence length*/ +} adc_base_config_type; + +/** + * @brief type define adc register all + */ +typedef struct +{ + + /** + * @brief adc sts register, offset:0x00 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t vmor : 1; /* [0] */ + __IO uint32_t cce : 1; /* [1] */ + __IO uint32_t pcce : 1; /* [2] */ + __IO uint32_t pccs : 1; /* [3] */ + __IO uint32_t occs : 1; /* [4] */ + __IO uint32_t reserved1 : 27;/* [31:5] */ + } sts_bit; + }; + + /** + * @brief adc ctrl1 register, offset:0x04 + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t vmcsel : 5; /* [4:0] */ + __IO uint32_t cceien : 1; /* [5] */ + __IO uint32_t vmorien : 1; /* [6] */ + __IO uint32_t pcceien : 1; /* [7] */ + __IO uint32_t sqen : 1; /* [8] */ + __IO uint32_t vmsgen : 1; /* [9] */ + __IO uint32_t pcautoen : 1; /* [10] */ + __IO uint32_t ocpen : 1; /* [11] */ + __IO uint32_t pcpen : 1; /* [12] */ + __IO uint32_t ocpcnt : 3; /* [15:13] */ + __IO uint32_t reserved1 : 6; /* [21:16] */ + __IO uint32_t pcvmen : 1; /* [22] */ + __IO uint32_t ocvmen : 1; /* [23] */ + __IO uint32_t reserved2 : 8; /* [31:24] */ + } ctrl1_bit; + }; + + /** + * @brief adc ctrl2 register, offset:0x08 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t adcen : 1; /* [0] */ + __IO uint32_t rpen : 1; /* [1] */ + __IO uint32_t adcal : 1; /* [2] */ + __IO uint32_t adcalinit : 1; /* [3] */ + __IO uint32_t reserved1 : 4; /* [7:4] */ + __IO uint32_t ocdmaen : 1; /* [8] */ + __IO uint32_t reserved2 : 2; /* [10:9] */ + __IO uint32_t dtalign : 1; /* [11] */ + __IO uint32_t pctesel_l : 3; /* [14:12] */ + __IO uint32_t pcten : 1; /* [15] */ + __IO uint32_t reserved3 : 1; /* [16] */ + __IO uint32_t octesel_l : 3; /* [19:17] */ + __IO uint32_t octen : 1; /* [20] */ + __IO uint32_t pcswtrg : 1; /* [21] */ + __IO uint32_t ocswtrg : 1; /* [22] */ + __IO uint32_t itsrven : 1; /* [23] */ + __IO uint32_t pctesel_h : 1; /* [24] */ + __IO uint32_t octesel_h : 1; /* [25] */ + __IO uint32_t reserved4 : 6; /* [31:26] */ + } ctrl2_bit; + }; + + /** + * @brief adc spt1 register, offset:0x0C + */ + union + { + __IO uint32_t spt1; + struct + { + __IO uint32_t cspt10 : 3; /* [2:0] */ + __IO uint32_t cspt11 : 3; /* [5:3] */ + __IO uint32_t cspt12 : 3; /* [8:6] */ + __IO uint32_t cspt13 : 3; /* [11:9] */ + __IO uint32_t cspt14 : 3; /* [14:12] */ + __IO uint32_t cspt15 : 3; /* [17:15] */ + __IO uint32_t cspt16 : 3; /* [20:18] */ + __IO uint32_t cspt17 : 3; /* [23:21] */ + __IO uint32_t reserved1 : 8;/* [31:24] */ + } spt1_bit; + }; + + /** + * @brief adc spt2 register, offset:0x10 + */ + union + { + __IO uint32_t spt2; + struct + { + __IO uint32_t cspt0 : 3;/* [2:0] */ + __IO uint32_t cspt1 : 3;/* [5:3] */ + __IO uint32_t cspt2 : 3;/* [8:6] */ + __IO uint32_t cspt3 : 3;/* [11:9] */ + __IO uint32_t cspt4 : 3;/* [14:12] */ + __IO uint32_t cspt5 : 3;/* [17:15] */ + __IO uint32_t cspt6 : 3;/* [20:18] */ + __IO uint32_t cspt7 : 3;/* [23:21] */ + __IO uint32_t cspt8 : 3;/* [26:24] */ + __IO uint32_t cspt9 : 3;/* [29:27] */ + __IO uint32_t reserved1 : 2;/* [31:30] */ + } spt2_bit; + }; + + /** + * @brief adc pcdto1 register, offset:0x14 + */ + union + { + __IO uint32_t pcdto1; + struct + { + __IO uint32_t pcdto1 : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } pcdto1_bit; + }; + + /** + * @brief adc pcdto2 register, offset:0x18 + */ + union + { + __IO uint32_t pcdto2; + struct + { + __IO uint32_t pcdto2 : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } pcdto2_bit; + }; + + /** + * @brief adc pcdto3 register, offset:0x1C + */ + union + { + __IO uint32_t pcdto3; + struct + { + __IO uint32_t pcdto3 : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } pcdto3_bit; + }; + + /** + * @brief adc pcdto4 register, offset:0x20 + */ + union + { + __IO uint32_t pcdto4; + struct + { + __IO uint32_t pcdto4 : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } pcdto4_bit; + }; + + /** + * @brief adc vmhb register, offset:0x24 + */ + union + { + __IO uint32_t vmhb; + struct + { + __IO uint32_t vmhb : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } vmhb_bit; + }; + + /** + * @brief adc vmlb register, offset:0x28 + */ + union + { + __IO uint32_t vmlb; + struct + { + __IO uint32_t vmlb : 12; /* [11:0] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } vmlb_bit; + }; + + /** + * @brief adc osq1 register, offset:0x2C + */ + union + { + __IO uint32_t osq1; + struct + { + __IO uint32_t osn13 : 5; /* [4:0] */ + __IO uint32_t osn14 : 5; /* [9:5] */ + __IO uint32_t osn15 : 5; /* [14:10] */ + __IO uint32_t osn16 : 5; /* [19:15] */ + __IO uint32_t oclen : 4; /* [23:20] */ + __IO uint32_t reserved1 : 8; /* [31:24] */ + } osq1_bit; + }; + + /** + * @brief adc osq2 register, offset:0x30 + */ + union + { + __IO uint32_t osq2; + struct + { + __IO uint32_t osn7 : 5; /* [4:0] */ + __IO uint32_t osn8 : 5; /* [9:5] */ + __IO uint32_t osn9 : 5; /* [14:10] */ + __IO uint32_t osn10 : 5; /* [19:15] */ + __IO uint32_t osn11 : 5; /* [24:20] */ + __IO uint32_t osn12 : 5; /* [29:25] */ + __IO uint32_t reserved1 : 2; /* [31:30] */ + } osq2_bit; + }; + + /** + * @brief adc osq3 register, offset:0x34 + */ + union + { + __IO uint32_t osq3; + struct + { + __IO uint32_t osn1 : 5; /* [4:0] */ + __IO uint32_t osn2 : 5; /* [9:5] */ + __IO uint32_t osn3 : 5; /* [14:10] */ + __IO uint32_t osn4 : 5; /* [19:15] */ + __IO uint32_t osn5 : 5; /* [24:20] */ + __IO uint32_t osn6 : 5; /* [29:25] */ + __IO uint32_t reserved1 : 2; /* [31:30] */ + } osq3_bit; + }; + + /** + * @brief adc psq register, offset:0x38 + */ + union + { + __IO uint32_t psq; + struct + { + __IO uint32_t psn1 : 5; /* [4:0] */ + __IO uint32_t psn2 : 5; /* [9:5] */ + __IO uint32_t psn3 : 5; /* [14:10] */ + __IO uint32_t psn4 : 5; /* [19:15] */ + __IO uint32_t pclen : 2; /* [21:20] */ + __IO uint32_t reserved1 : 10;/* [31:22] */ + } psq_bit; + }; + + /** + * @brief adc pdt1 register, offset:0x3C + */ + union + { + __IO uint32_t pdt1; + struct + { + __IO uint32_t pdt1 : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } pdt1_bit; + }; + + /** + * @brief adc pdt2 register, offset:0x40 + */ + union + { + __IO uint32_t pdt2; + struct + { + __IO uint32_t pdt2 : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } pdt2_bit; + }; + + /** + * @brief adc pdt3 register, offset:0x44 + */ + union + { + __IO uint32_t pdt3; + struct + { + __IO uint32_t pdt3 : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } pdt3_bit; + }; + + /** + * @brief adc pdt4 register, offset:0x48 + */ + union + { + __IO uint32_t pdt4; + struct + { + __IO uint32_t pdt4 : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } pdt4_bit; + }; + + /** + * @brief adc odt register, offset:0x4C + */ + union + { + __IO uint32_t odt; + struct + { + __IO uint32_t odt : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } odt_bit; + }; + + /** + * @brief adc reserved register, offset:0x50~0x7C + */ + __IO uint32_t reserved1[12]; + + /** + * @brief adc oversample register, offset:0x80 + */ + union + { + __IO uint32_t ovsp; + struct + { + __IO uint32_t oosen : 1; /* [0] */ + __IO uint32_t posen : 1; /* [1] */ + __IO uint32_t osrsel : 3; /* [4:2] */ + __IO uint32_t osssel : 4; /* [8:5] */ + __IO uint32_t oostren : 1; /* [9] */ + __IO uint32_t oosrsel : 1; /* [10] */ + __IO uint32_t reserved1 : 21; /* [31:11] */ + } ovsp_bit; + }; +} adc_type; + +/** + * @} + */ + +#define ADC1 ((adc_type *) ADC1_BASE) + +/** @defgroup ADC_exported_functions + * @{ + */ + +void adc_reset(adc_type *adc_x); +void adc_enable(adc_type *adc_x, confirm_state new_state); +void adc_base_default_para_init(adc_base_config_type *adc_base_struct); +void adc_base_config(adc_type *adc_x, adc_base_config_type *adc_base_struct); +void adc_dma_mode_enable(adc_type *adc_x, confirm_state new_state); +void adc_interrupt_enable(adc_type *adc_x, uint32_t adc_int, confirm_state new_state); +void adc_calibration_init(adc_type *adc_x); +flag_status adc_calibration_init_status_get(adc_type *adc_x); +void adc_calibration_start(adc_type *adc_x); +flag_status adc_calibration_status_get(adc_type *adc_x); +void adc_voltage_monitor_enable(adc_type *adc_x, adc_voltage_monitoring_type adc_voltage_monitoring); +void adc_voltage_monitor_threshold_value_set(adc_type *adc_x, uint16_t adc_high_threshold, uint16_t adc_low_threshold); +void adc_voltage_monitor_single_channel_select(adc_type *adc_x, adc_channel_select_type adc_channel); +void adc_ordinary_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime); +void adc_preempt_channel_length_set(adc_type *adc_x, uint8_t adc_channel_lenght); +void adc_preempt_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime); +void adc_ordinary_conversion_trigger_set(adc_type *adc_x, adc_ordinary_trig_select_type adc_ordinary_trig, confirm_state new_state); +void adc_preempt_conversion_trigger_set(adc_type *adc_x, adc_preempt_trig_select_type adc_preempt_trig, confirm_state new_state); +void adc_preempt_offset_value_set(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel, uint16_t adc_offset_value); +void adc_ordinary_part_count_set(adc_type *adc_x, uint8_t adc_channel_count); +void adc_ordinary_part_mode_enable(adc_type *adc_x, confirm_state new_state); +void adc_preempt_part_mode_enable(adc_type *adc_x, confirm_state new_state); +void adc_preempt_auto_mode_enable(adc_type *adc_x, confirm_state new_state); +void adc_tempersensor_vintrv_enable(confirm_state new_state); +void adc_ordinary_software_trigger_enable(adc_type *adc_x, confirm_state new_state); +flag_status adc_ordinary_software_trigger_status_get(adc_type *adc_x); +void adc_preempt_software_trigger_enable(adc_type *adc_x, confirm_state new_state); +flag_status adc_preempt_software_trigger_status_get(adc_type *adc_x); +uint16_t adc_ordinary_conversion_data_get(adc_type *adc_x); +uint16_t adc_preempt_conversion_data_get(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel); +flag_status adc_flag_get(adc_type *adc_x, uint8_t adc_flag); +flag_status adc_interrupt_flag_get(adc_type *adc_x, uint8_t adc_flag); +void adc_flag_clear(adc_type *adc_x, uint32_t adc_flag); +void adc_ordinary_oversample_enable(adc_type *adc_x, confirm_state new_state); +void adc_preempt_oversample_enable(adc_type *adc_x, confirm_state new_state); +void adc_oversample_ratio_shift_set(adc_type *adc_x, adc_oversample_ratio_type adc_oversample_ratio, adc_oversample_shift_type adc_oversample_shift); +void adc_ordinary_oversample_trig_enable(adc_type *adc_x, confirm_state new_state); +void adc_ordinary_oversample_restart_set(adc_type *adc_x, adc_ordinary_oversample_restart_type adc_ordinary_oversample_restart); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_can.h b/libraries/drivers/inc/at32f425_can.h new file mode 100644 index 0000000..0d35df2 --- /dev/null +++ b/libraries/drivers/inc/at32f425_can.h @@ -0,0 +1,984 @@ +/** + ************************************************************************** + * @file at32f425_can.h + * @brief at32f425 can header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_CAN_H +#define __AT32F425_CAN_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup CAN + * @{ + */ + + +/** @defgroup CAN_timeout_count + * @{ + */ + +#define FZC_TIMEOUT ((uint32_t)0x0000FFFF) /*!< time out for fzc bit */ +#define DZC_TIMEOUT ((uint32_t)0x0000FFFF) /*!< time out for dzc bit */ + +/** + * @} + */ + +/** @defgroup CAN_flags_definition + * @brief can flag + * @{ + */ + +#define CAN_EAF_FLAG ((uint32_t)0x01) /*!< error active flag */ +#define CAN_EPF_FLAG ((uint32_t)0x02) /*!< error passive flag */ +#define CAN_BOF_FLAG ((uint32_t)0x03) /*!< bus-off flag */ +#define CAN_ETR_FLAG ((uint32_t)0x04) /*!< error type record flag */ +#define CAN_EOIF_FLAG ((uint32_t)0x05) /*!< error occur interrupt flag */ +#define CAN_TM0TCF_FLAG ((uint32_t)0x06) /*!< transmit mailbox 0 transmission completed flag */ +#define CAN_TM1TCF_FLAG ((uint32_t)0x07) /*!< transmit mailbox 1 transmission completed flag */ +#define CAN_TM2TCF_FLAG ((uint32_t)0x08) /*!< transmit mailbox 2 transmission completed flag */ +#define CAN_RF0MN_FLAG ((uint32_t)0x09) /*!< receive fifo 0 message num flag */ +#define CAN_RF0FF_FLAG ((uint32_t)0x0A) /*!< receive fifo 0 full flag */ +#define CAN_RF0OF_FLAG ((uint32_t)0x0B) /*!< receive fifo 0 overflow flag */ +#define CAN_RF1MN_FLAG ((uint32_t)0x0C) /*!< receive fifo 1 message num flag */ +#define CAN_RF1FF_FLAG ((uint32_t)0x0D) /*!< receive fifo 1 full flag */ +#define CAN_RF1OF_FLAG ((uint32_t)0x0E) /*!< receive fifo 1 overflow flag */ +#define CAN_QDZIF_FLAG ((uint32_t)0x0F) /*!< quit doze mode interrupt flag */ +#define CAN_EDZC_FLAG ((uint32_t)0x10) /*!< enter doze mode confirm flag */ +#define CAN_TMEF_FLAG ((uint32_t)0x11) /*!< transmit mailbox empty flag */ + +/** + * @} + */ + +/** @defgroup CAN_interrupts_definition + * @brief can interrupt + * @{ + */ + +#define CAN_TCIEN_INT ((uint32_t)0x00000001) /*!< transmission complete interrupt */ +#define CAN_RF0MIEN_INT ((uint32_t)0x00000002) /*!< receive fifo 0 message interrupt */ +#define CAN_RF0FIEN_INT ((uint32_t)0x00000004) /*!< receive fifo 0 full interrupt */ +#define CAN_RF0OIEN_INT ((uint32_t)0x00000008) /*!< receive fifo 0 overflow interrupt */ +#define CAN_RF1MIEN_INT ((uint32_t)0x00000010) /*!< receive fifo 1 message interrupt */ +#define CAN_RF1FIEN_INT ((uint32_t)0x00000020) /*!< receive fifo 1 full interrupt */ +#define CAN_RF1OIEN_INT ((uint32_t)0x00000040) /*!< receive fifo 1 overflow interrupt */ +#define CAN_EAIEN_INT ((uint32_t)0x00000100) /*!< error active interrupt */ +#define CAN_EPIEN_INT ((uint32_t)0x00000200) /*!< error passive interrupt */ +#define CAN_BOIEN_INT ((uint32_t)0x00000400) /*!< bus-off interrupt */ +#define CAN_ETRIEN_INT ((uint32_t)0x00000800) /*!< error type record interrupt */ +#define CAN_EOIEN_INT ((uint32_t)0x00008000) /*!< error occur interrupt */ +#define CAN_QDZIEN_INT ((uint32_t)0x00010000) /*!< quit doze mode interrupt */ +#define CAN_EDZIEN_INT ((uint32_t)0x00020000) /*!< enter doze mode confirm interrupt */ + +/** + * @} + */ + +/** + * @brief can flag clear operation macro definition val + */ +#define CAN_MSTS_EOIF_VAL ((uint32_t)0x00000004) /*!< eoif bit value, it clear by writing 1 */ +#define CAN_MSTS_QDZIF_VAL ((uint32_t)0x00000008) /*!< qdzif bit value, it clear by writing 1 */ +#define CAN_MSTS_EDZIF_VAL ((uint32_t)0x00000010) /*!< edzif bit value, it clear by writing 1 */ +#define CAN_TSTS_TM0TCF_VAL ((uint32_t)0x00000001) /*!< tm0tcf bit value, it clear by writing 1 */ +#define CAN_TSTS_TM1TCF_VAL ((uint32_t)0x00000100) /*!< tm1tcf bit value, it clear by writing 1 */ +#define CAN_TSTS_TM2TCF_VAL ((uint32_t)0x00010000) /*!< tm2tcf bit value, it clear by writing 1 */ +#define CAN_TSTS_TM0CT_VAL ((uint32_t)0x00000080) /*!< tm0ct bit value, it clear by writing 1 */ +#define CAN_TSTS_TM1CT_VAL ((uint32_t)0x00008000) /*!< tm1ct bit value, it clear by writing 1 */ +#define CAN_TSTS_TM2CT_VAL ((uint32_t)0x00800000) /*!< tm2ct bit value, it clear by writing 1 */ +#define CAN_RF0_RF0FF_VAL ((uint32_t)0x00000008) /*!< rf0ff bit value, it clear by writing 1 */ +#define CAN_RF0_RF0OF_VAL ((uint32_t)0x00000010) /*!< rf0of bit value, it clear by writing 1 */ +#define CAN_RF0_RF0R_VAL ((uint32_t)0x00000020) /*!< rf0r bit value, it clear by writing 1 */ +#define CAN_RF1_RF1FF_VAL ((uint32_t)0x00000008) /*!< rf1ff bit value, it clear by writing 1 */ +#define CAN_RF1_RF1OF_VAL ((uint32_t)0x00000010) /*!< rf1of bit value, it clear by writing 1 */ +#define CAN_RF1_RF1R_VAL ((uint32_t)0x00000020) /*!< rf1r bit value, it clear by writing 1 */ + +/** @defgroup CAN_exported_types + * @{ + */ + +/** + * @brief can filter fifo + */ +typedef enum +{ + CAN_FILTER_FIFO0 = 0x00, /*!< filter fifo 0 assignment for filter x */ + CAN_FILTER_FIFO1 = 0x01 /*!< filter fifo 1 assignment for filter x */ +} can_filter_fifo_type; + +/** + * @brief can filter mode + */ +typedef enum +{ + CAN_FILTER_MODE_ID_MASK = 0x00, /*!< identifier mask mode */ + CAN_FILTER_MODE_ID_LIST = 0x01 /*!< identifier list mode */ +} can_filter_mode_type; + +/** + * @brief can filter bit width select + */ +typedef enum +{ + CAN_FILTER_16BIT = 0x00, /*!< two 16-bit filters */ + CAN_FILTER_32BIT = 0x01 /*!< one 32-bit filter */ +} can_filter_bit_width_type; + +/** + * @brief can mode + */ +typedef enum +{ + CAN_MODE_COMMUNICATE = 0x00, /*!< communication mode */ + CAN_MODE_LOOPBACK = 0x01, /*!< loopback mode */ + CAN_MODE_LISTENONLY = 0x02, /*!< listen-only mode */ + CAN_MODE_LISTENONLY_LOOPBACK = 0x03 /*!< loopback combined with listen-only mode */ +} can_mode_type; + +/** + * @brief can operating mode + */ +typedef enum +{ + CAN_OPERATINGMODE_FREEZE = 0x00, /*!< freeze mode */ + CAN_OPERATINGMODE_DOZE = 0x01, /*!< doze mode */ + CAN_OPERATINGMODE_COMMUNICATE = 0x02 /*!< communication mode */ +} can_operating_mode_type; + +/** + * @brief can resynchronization adjust width + */ +typedef enum +{ + CAN_RSAW_1TQ = 0x00, /*!< 1 time quantum */ + CAN_RSAW_2TQ = 0x01, /*!< 2 time quantum */ + CAN_RSAW_3TQ = 0x02, /*!< 3 time quantum */ + CAN_RSAW_4TQ = 0x03 /*!< 4 time quantum */ +} can_rsaw_type; + +/** + * @brief can bit time segment 1 + */ +typedef enum +{ + CAN_BTS1_1TQ = 0x00, /*!< 1 time quantum */ + CAN_BTS1_2TQ = 0x01, /*!< 2 time quantum */ + CAN_BTS1_3TQ = 0x02, /*!< 3 time quantum */ + CAN_BTS1_4TQ = 0x03, /*!< 4 time quantum */ + CAN_BTS1_5TQ = 0x04, /*!< 5 time quantum */ + CAN_BTS1_6TQ = 0x05, /*!< 6 time quantum */ + CAN_BTS1_7TQ = 0x06, /*!< 7 time quantum */ + CAN_BTS1_8TQ = 0x07, /*!< 8 time quantum */ + CAN_BTS1_9TQ = 0x08, /*!< 9 time quantum */ + CAN_BTS1_10TQ = 0x09, /*!< 10 time quantum */ + CAN_BTS1_11TQ = 0x0A, /*!< 11 time quantum */ + CAN_BTS1_12TQ = 0x0B, /*!< 12 time quantum */ + CAN_BTS1_13TQ = 0x0C, /*!< 13 time quantum */ + CAN_BTS1_14TQ = 0x0D, /*!< 14 time quantum */ + CAN_BTS1_15TQ = 0x0E, /*!< 15 time quantum */ + CAN_BTS1_16TQ = 0x0F /*!< 16 time quantum */ +} can_bts1_type; + +/** + * @brief can bit time segment 2 + */ +typedef enum +{ + CAN_BTS2_1TQ = 0x00, /*!< 1 time quantum */ + CAN_BTS2_2TQ = 0x01, /*!< 2 time quantum */ + CAN_BTS2_3TQ = 0x02, /*!< 3 time quantum */ + CAN_BTS2_4TQ = 0x03, /*!< 4 time quantum */ + CAN_BTS2_5TQ = 0x04, /*!< 5 time quantum */ + CAN_BTS2_6TQ = 0x05, /*!< 6 time quantum */ + CAN_BTS2_7TQ = 0x06, /*!< 7 time quantum */ + CAN_BTS2_8TQ = 0x07 /*!< 8 time quantum */ +} can_bts2_type; + +/** + * @brief can identifier type + */ +typedef enum +{ + CAN_ID_STANDARD = 0x00, /*!< standard Id */ + CAN_ID_EXTENDED = 0x01 /*!< extended Id */ +} can_identifier_type; + +/** + * @brief can transmission frame type + */ +typedef enum +{ + CAN_TFT_DATA = 0x00, /*!< data frame */ + CAN_TFT_REMOTE = 0x01 /*!< remote frame */ +} can_trans_frame_type; + +/** + * @brief can tx mailboxes + */ +typedef enum +{ + CAN_TX_MAILBOX0 = 0x00, /*!< can tx mailbox 0 */ + CAN_TX_MAILBOX1 = 0x01, /*!< can tx mailbox 1 */ + CAN_TX_MAILBOX2 = 0x02 /*!< can tx mailbox 2 */ +} can_tx_mailbox_num_type; + +/** + * @brief can receive fifo + */ +typedef enum +{ + CAN_RX_FIFO0 = 0x00, /*!< can fifo 0 used to receive */ + CAN_RX_FIFO1 = 0x01 /*!< can fifo 1 used to receive */ +} can_rx_fifo_num_type; + +/** + * @brief can transmit status + */ +typedef enum +{ + CAN_TX_STATUS_FAILED = 0x00, /*!< can transmission failed */ + CAN_TX_STATUS_SUCCESSFUL = 0x01, /*!< can transmission successful */ + CAN_TX_STATUS_PENDING = 0x02, /*!< can transmission pending */ + CAN_TX_STATUS_NO_EMPTY = 0x04 /*!< can transmission no empty mailbox */ +} can_transmit_status_type; + +/** + * @brief can enter doze mode status + */ +typedef enum +{ + CAN_ENTER_DOZE_FAILED = 0x00, /*!< can enter the doze mode failed */ + CAN_ENTER_DOZE_SUCCESSFUL = 0x01 /*!< can enter the doze mode successful */ +} can_enter_doze_status_type; + +/** + * @brief can quit doze mode status + */ +typedef enum +{ + CAN_QUIT_DOZE_FAILED = 0x00, /*!< can quit doze mode failed */ + CAN_QUIT_DOZE_SUCCESSFUL = 0x01 /*!< can quit doze mode successful */ +} can_quit_doze_status_type; + +/** + * @brief can message discarding rule select when overflow + */ +typedef enum +{ + CAN_DISCARDING_FIRST_RECEIVED = 0x00, /*!< can discarding the first received message */ + CAN_DISCARDING_LAST_RECEIVED = 0x01 /*!< can discarding the last received message */ +} can_msg_discarding_rule_type; + +/** + * @brief can multiple message sending sequence rule + */ +typedef enum +{ + CAN_SENDING_BY_ID = 0x00, /*!< can sending the minimum id message first*/ + CAN_SENDING_BY_REQUEST = 0x01 /*!< can sending the first request message first */ +} can_msg_sending_rule_type; + +/** + * @brief can error type record + */ +typedef enum +{ + CAN_ERRORRECORD_NOERR = 0x00, /*!< no error */ + CAN_ERRORRECORD_STUFFERR = 0x01, /*!< stuff error */ + CAN_ERRORRECORD_FORMERR = 0x02, /*!< form error */ + CAN_ERRORRECORD_ACKERR = 0x03, /*!< acknowledgment error */ + CAN_ERRORRECORD_BITRECESSIVEERR = 0x04, /*!< bit recessive error */ + CAN_ERRORRECORD_BITDOMINANTERR = 0x05, /*!< bit dominant error */ + CAN_ERRORRECORD_CRCERR = 0x06, /*!< crc error */ + CAN_ERRORRECORD_SOFTWARESETERR = 0x07 /*!< software set error */ +} can_error_record_type; + +/** + * @brief can init structure definition + */ +typedef struct +{ + can_mode_type mode_selection; /*!< specifies the can mode.*/ + + confirm_state ttc_enable; /*!< time triggered communication mode enable */ + + confirm_state aebo_enable; /*!< automatic exit bus-off enable */ + + confirm_state aed_enable; /*!< automatic exit doze mode enable */ + + confirm_state prsf_enable; /*!< prohibit retransmission when sending fails enable */ + + can_msg_discarding_rule_type mdrsel_selection; /*!< message discarding rule select when overflow */ + + can_msg_sending_rule_type mmssr_selection; /*!< multiple message sending sequence rule */ + +} can_base_type; + +/** + * @brief can baudrate structure definition + */ +typedef struct +{ + uint16_t baudrate_div; /*!< baudrate division,this parameter can be 0x001~0x1000.*/ + + can_rsaw_type rsaw_size; /*!< resynchronization adjust width */ + + can_bts1_type bts1_size; /*!< bit time segment 1 */ + + can_bts2_type bts2_size; /*!< bit time segment 2 */ + +} can_baudrate_type; + +/** + * @brief can filter init structure definition + */ +typedef struct +{ + confirm_state filter_activate_enable; /*!< enable or disable the filter activate.*/ + + can_filter_mode_type filter_mode; /*!< config the filter mode mask or list.*/ + + can_filter_fifo_type filter_fifo; /*!< config the fifo which will be assigned to the filter. */ + + uint8_t filter_number; /*!< config the filter number, parameter ranges from 0 to 13. */ + + can_filter_bit_width_type filter_bit; /*!< config the filter bit width 16bit or 32bit.*/ + + uint16_t filter_id_high; /*!< config the filter identification, for 32-bit configuration + it's high 16 bits, for 16-bit configuration it's first. */ + + uint16_t filter_id_low; /*!< config the filter identification, for 32-bit configuration + it's low 16 bits, for 16-bit configuration it's second. */ + + uint16_t filter_mask_high; /*!< config the filter mask or identification, according to the filtering mode, + for 32-bit configuration it's high 16 bits, for 16-bit configuration it's first. */ + + uint16_t filter_mask_low; /*!< config the filter mask or identification, according to the filtering mode, + for 32-bit configuration it's low 16 bits, for 16-bit configuration it's second. */ +} can_filter_init_type; + +/** + * @brief can tx message structure definition + */ +typedef struct +{ + uint32_t standard_id; /*!< specifies the 11 bits standard identifier. + this parameter can be a value between 0 to 0x7FF. */ + + uint32_t extended_id; /*!< specifies the 29 bits extended identifier. + this parameter can be a value between 0 to 0x1FFFFFFF. */ + + can_identifier_type id_type; /*!< specifies identifier type for the transmit message.*/ + + can_trans_frame_type frame_type; /*!< specifies frame type for the transmit message.*/ + + uint8_t dlc; /*!< specifies frame data length that will be transmitted. + this parameter can be a value between 0 to 8 */ + + uint8_t data[8]; /*!< contains the transmit data. it ranges from 0 to 0xFF. */ + +} can_tx_message_type; + +/** + * @brief can rx message structure definition + */ +typedef struct +{ + uint32_t standard_id; /*!< specifies the 11 bits standard identifier + this parameter can be a value between 0 to 0x7FF. */ + + uint32_t extended_id; /*!< specifies the 29 bits extended identifier. + this parameter can be a value between 0 to 0x1FFFFFFF. */ + + can_identifier_type id_type; /*!< specifies identifier type for the receive message.*/ + + can_trans_frame_type frame_type; /*!< specifies frame type for the receive message.*/ + + uint8_t dlc; /*!< specifies the frame data length that will be received. + this parameter can be a value between 0 to 8 */ + + uint8_t data[8]; /*!< contains the receive data. it ranges from 0 to 0xFF.*/ + + uint8_t filter_index; /*!< specifies the message stored in which filter + this parameter can be a value between 0 to 0xFF */ +} can_rx_message_type; + +/** + * @brief can controller area network tx mailbox + */ +typedef struct +{ + /** + * @brief can tmi register + */ + union + { + __IO uint32_t tmi; + struct + { + __IO uint32_t tmsr : 1; /* [0] */ + __IO uint32_t tmfrsel : 1; /* [1] */ + __IO uint32_t tmidsel : 1; /* [2] */ + __IO uint32_t tmeid : 18;/* [20:3] */ + __IO uint32_t tmsid : 11;/* [31:21] */ + } tmi_bit; + }; + + /** + * @brief can tmc register + */ + union + { + __IO uint32_t tmc; + struct + { + __IO uint32_t tmdtbl : 4; /* [3:0] */ + __IO uint32_t reserved1 : 4; /* [7:4] */ + __IO uint32_t tmtsten : 1; /* [8] */ + __IO uint32_t reserved2 : 7; /* [15:9] */ + __IO uint32_t tmts : 16;/* [31:16] */ + } tmc_bit; + }; + + /** + * @brief can tmdtl register + */ + union + { + __IO uint32_t tmdtl; + struct + { + __IO uint32_t tmdt0 : 8; /* [7:0] */ + __IO uint32_t tmdt1 : 8; /* [15:8] */ + __IO uint32_t tmdt2 : 8; /* [23:16] */ + __IO uint32_t tmdt3 : 8; /* [31:24] */ + } tmdtl_bit; + }; + + /** + * @brief can tmdth register + */ + union + { + __IO uint32_t tmdth; + struct + { + __IO uint32_t tmdt4 : 8; /* [7:0] */ + __IO uint32_t tmdt5 : 8; /* [15:8] */ + __IO uint32_t tmdt6 : 8; /* [23:16] */ + __IO uint32_t tmdt7 : 8; /* [31:24] */ + } tmdth_bit; + }; +} can_tx_mailbox_type; + +/** + * @brief can controller area network fifo mailbox + */ +typedef struct +{ + /** + * @brief can rfi register + */ + union + { + __IO uint32_t rfi; + struct + { + __IO uint32_t reserved1 : 1; /* [0] */ + __IO uint32_t rffri : 1; /* [1] */ + __IO uint32_t rfidi : 1; /* [2] */ + __IO uint32_t rfeid : 18;/* [20:3] */ + __IO uint32_t rfsid : 11;/* [31:21] */ + } rfi_bit; + }; + + /** + * @brief can rfc register + */ + union + { + __IO uint32_t rfc; + struct + { + __IO uint32_t rfdtl : 4; /* [3:0] */ + __IO uint32_t reserved1 : 4; /* [7:4] */ + __IO uint32_t rffmn : 8; /* [15:8] */ + __IO uint32_t rfts : 16;/* [31:16] */ + } rfc_bit; + }; + + /** + * @brief can rfdtl register + */ + union + { + __IO uint32_t rfdtl; + struct + { + __IO uint32_t rfdt0 : 8; /* [7:0] */ + __IO uint32_t rfdt1 : 8; /* [15:8] */ + __IO uint32_t rfdt2 : 8; /* [23:16] */ + __IO uint32_t rfdt3 : 8; /* [31:24] */ + } rfdtl_bit; + }; + + /** + * @brief can rfdth register + */ + union + { + __IO uint32_t rfdth; + struct + { + __IO uint32_t rfdt4 : 8; /* [7:0] */ + __IO uint32_t rfdt5 : 8; /* [15:8] */ + __IO uint32_t rfdt6 : 8; /* [23:16] */ + __IO uint32_t rfdt7 : 8; /* [31:24] */ + } rfdth_bit; + }; +} can_fifo_mailbox_type; + +/** + * @brief can controller area network filter bit register + */ +typedef struct +{ + __IO uint32_t ffdb1; + __IO uint32_t ffdb2; +} can_filter_register_type; + +/** + * @brief type define can register all + */ +typedef struct +{ + + /** + * @brief can mctrl register, offset:0x00 + */ + union + { + __IO uint32_t mctrl; + struct + { + __IO uint32_t fzen : 1; /* [0] */ + __IO uint32_t dzen : 1; /* [1] */ + __IO uint32_t mmssr : 1; /* [2] */ + __IO uint32_t mdrsel : 1; /* [3] */ + __IO uint32_t prsfen : 1; /* [4] */ + __IO uint32_t aeden : 1; /* [5] */ + __IO uint32_t aeboen : 1; /* [6] */ + __IO uint32_t ttcen : 1; /* [7] */ + __IO uint32_t reserved1 : 7; /* [14:8] */ + __IO uint32_t sprst : 1; /* [15] */ + __IO uint32_t ptd : 1; /* [16] */ + __IO uint32_t reserved2 : 15;/*[31:17] */ + } mctrl_bit; + }; + + /** + * @brief can msts register, offset:0x04 + */ + union + { + __IO uint32_t msts; + struct + { + __IO uint32_t fzc : 1; /* [0] */ + __IO uint32_t dzc : 1; /* [1] */ + __IO uint32_t eoif : 1; /* [2] */ + __IO uint32_t qdzif : 1; /* [3] */ + __IO uint32_t edzif : 1; /* [4] */ + __IO uint32_t reserved1 : 3; /* [7:5] */ + __IO uint32_t cuss : 1; /* [8] */ + __IO uint32_t curs : 1; /* [9] */ + __IO uint32_t lsamprx : 1; /* [10] */ + __IO uint32_t realrx : 1; /* [11] */ + __IO uint32_t reserved2 : 20;/*[31:12] */ + } msts_bit; + }; + + /** + * @brief can tsts register, offset:0x08 + */ + union + { + __IO uint32_t tsts; + struct + { + __IO uint32_t tm0tcf : 1; /* [0] */ + __IO uint32_t tm0tsf : 1; /* [1] */ + __IO uint32_t tm0alf : 1; /* [2] */ + __IO uint32_t tm0tef : 1; /* [3] */ + __IO uint32_t reserved1 : 3; /* [6:4] */ + __IO uint32_t tm0ct : 1; /* [7] */ + __IO uint32_t tm1tcf : 1; /* [8] */ + __IO uint32_t tm1tsf : 1; /* [9] */ + __IO uint32_t tm1alf : 1; /* [10] */ + __IO uint32_t tm1tef : 1; /* [11] */ + __IO uint32_t reserved2 : 3; /* [14:12] */ + __IO uint32_t tm1ct : 1; /* [15] */ + __IO uint32_t tm2tcf : 1; /* [16] */ + __IO uint32_t tm2tsf : 1; /* [17] */ + __IO uint32_t tm2alf : 1; /* [18] */ + __IO uint32_t tm2tef : 1; /* [19] */ + __IO uint32_t reserved3 : 3; /* [22:20] */ + __IO uint32_t tm2ct : 1; /* [23] */ + __IO uint32_t tmnr : 2; /* [25:24] */ + __IO uint32_t tm0ef : 1; /* [26] */ + __IO uint32_t tm1ef : 1; /* [27] */ + __IO uint32_t tm2ef : 1; /* [28] */ + __IO uint32_t tm0lpf : 1; /* [29] */ + __IO uint32_t tm1lpf : 1; /* [30] */ + __IO uint32_t tm2lpf : 1; /* [31] */ + } tsts_bit; + }; + + /** + * @brief can rf0 register, offset:0x0C + */ + union + { + __IO uint32_t rf0; + struct + { + __IO uint32_t rf0mn : 2; /* [1:0] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t rf0ff : 1; /* [3] */ + __IO uint32_t rf0of : 1; /* [4] */ + __IO uint32_t rf0r : 1; /* [5] */ + __IO uint32_t reserved2 : 26;/* [31:6] */ + } rf0_bit; + }; + + /** + * @brief can rf1 register, offset:0x10 + */ + union + { + __IO uint32_t rf1; + struct + { + __IO uint32_t rf1mn : 2; /* [1:0] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t rf1ff : 1; /* [3] */ + __IO uint32_t rf1of : 1; /* [4] */ + __IO uint32_t rf1r : 1; /* [5] */ + __IO uint32_t reserved2 : 26;/* [31:6] */ + } rf1_bit; + }; + + /** + * @brief can inten register, offset:0x14 + */ + union + { + __IO uint32_t inten; + struct + { + __IO uint32_t tcien : 1; /* [0] */ + __IO uint32_t rf0mien : 1; /* [1] */ + __IO uint32_t rf0fien : 1; /* [2] */ + __IO uint32_t rf0oien : 1; /* [3] */ + __IO uint32_t rf1mien : 1; /* [4] */ + __IO uint32_t rf1fien : 1; /* [5] */ + __IO uint32_t rf1oien : 1; /* [6] */ + __IO uint32_t reserved1 : 1; /* [7] */ + __IO uint32_t eaien : 1; /* [8] */ + __IO uint32_t epien : 1; /* [9] */ + __IO uint32_t boien : 1; /* [10] */ + __IO uint32_t etrien : 1; /* [11] */ + __IO uint32_t reserved2 : 3; /* [14:12] */ + __IO uint32_t eoien : 1; /* [15] */ + __IO uint32_t qdzien : 1; /* [16] */ + __IO uint32_t edzien : 1; /* [17] */ + __IO uint32_t reserved3 : 14;/* [31:18] */ + } inten_bit; + }; + + /** + * @brief can ests register, offset:0x18 + */ + union + { + __IO uint32_t ests; + struct + { + __IO uint32_t eaf : 1; /* [0] */ + __IO uint32_t epf : 1; /* [1] */ + __IO uint32_t bof : 1; /* [2] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t etr : 3; /* [6:4] */ + __IO uint32_t reserved2 : 9; /* [15:7] */ + __IO uint32_t tec : 8; /* [23:16] */ + __IO uint32_t rec : 8; /* [31:24] */ + } ests_bit; + }; + + /** + * @brief can btmg register, offset:0x1C + */ + union + { + __IO uint32_t btmg; + struct + { + __IO uint32_t brdiv : 12;/* [11:0] */ + __IO uint32_t reserved1 : 4; /* [15:12] */ + __IO uint32_t bts1 : 4; /* [19:16] */ + __IO uint32_t bts2 : 3; /* [22:20] */ + __IO uint32_t reserved2 : 1; /* [23] */ + __IO uint32_t rsaw : 2; /* [25:24] */ + __IO uint32_t reserved3 : 4; /* [29:26] */ + __IO uint32_t lben : 1; /* [30] */ + __IO uint32_t loen : 1; /* [31] */ + } btmg_bit; + }; + + /** + * @brief can reserved register, offset:0x20~0x17C + */ + __IO uint32_t reserved1[88]; + + /** + * @brief can controller area network tx mailbox register, offset:0x180~0x1AC + */ + can_tx_mailbox_type tx_mailbox[3]; + + /** + * @brief can controller area network fifo mailbox register, offset:0x1B0~0x1CC + */ + can_fifo_mailbox_type fifo_mailbox[2]; + + /** + * @brief can reserved register, offset:0x1D0~0x1FC + */ + __IO uint32_t reserved2[12]; + + /** + * @brief can fctrl register, offset:0x200 + */ + union + { + __IO uint32_t fctrl; + struct + { + __IO uint32_t fcs : 1; /* [0] */ + __IO uint32_t reserved1 : 31;/* [31:1] */ + } fctrl_bit; + }; + + /** + * @brief can fmcfg register, offset:0x204 + */ + union + { + __IO uint32_t fmcfg; + struct + { + __IO uint32_t fmsel0 : 1; /* [0] */ + __IO uint32_t fmsel1 : 1; /* [1] */ + __IO uint32_t fmsel2 : 1; /* [2] */ + __IO uint32_t fmsel3 : 1; /* [3] */ + __IO uint32_t fmsel4 : 1; /* [4] */ + __IO uint32_t fmsel5 : 1; /* [5] */ + __IO uint32_t fmsel6 : 1; /* [6] */ + __IO uint32_t fmsel7 : 1; /* [7] */ + __IO uint32_t fmsel8 : 1; /* [8] */ + __IO uint32_t fmsel9 : 1; /* [9] */ + __IO uint32_t fmsel10 : 1; /* [10] */ + __IO uint32_t fmsel11 : 1; /* [11] */ + __IO uint32_t fmsel12 : 1; /* [12] */ + __IO uint32_t fmsel13 : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } fmcfg_bit; + }; + + /** + * @brief can reserved register, offset:0x208 + */ + __IO uint32_t reserved3; + + /** + * @brief can fbwcfg register, offset:0x20C + */ + union + { + __IO uint32_t fbwcfg; + struct + { + __IO uint32_t fbwsel0 : 1; /* [0] */ + __IO uint32_t fbwsel1 : 1; /* [1] */ + __IO uint32_t fbwsel2 : 1; /* [2] */ + __IO uint32_t fbwsel3 : 1; /* [3] */ + __IO uint32_t fbwsel4 : 1; /* [4] */ + __IO uint32_t fbwsel5 : 1; /* [5] */ + __IO uint32_t fbwsel6 : 1; /* [6] */ + __IO uint32_t fbwsel7 : 1; /* [7] */ + __IO uint32_t fbwsel8 : 1; /* [8] */ + __IO uint32_t fbwsel9 : 1; /* [9] */ + __IO uint32_t fbwsel10 : 1; /* [10] */ + __IO uint32_t fbwsel11 : 1; /* [11] */ + __IO uint32_t fbwsel12 : 1; /* [12] */ + __IO uint32_t fbwsel13 : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } fbwcfg_bit; + }; + + /** + * @brief can reserved register, offset:0x210 + */ + __IO uint32_t reserved4; + + /** + * @brief can frf register, offset:0x214 + */ + union + { + __IO uint32_t frf; + struct + { + __IO uint32_t frfsel0 : 1; /* [0] */ + __IO uint32_t frfsel1 : 1; /* [1] */ + __IO uint32_t frfsel2 : 1; /* [2] */ + __IO uint32_t frfsel3 : 1; /* [3] */ + __IO uint32_t frfsel4 : 1; /* [4] */ + __IO uint32_t frfsel5 : 1; /* [5] */ + __IO uint32_t frfsel6 : 1; /* [6] */ + __IO uint32_t frfsel7 : 1; /* [7] */ + __IO uint32_t frfsel8 : 1; /* [8] */ + __IO uint32_t frfsel9 : 1; /* [9] */ + __IO uint32_t frfsel10 : 1; /* [10] */ + __IO uint32_t frfsel11 : 1; /* [11] */ + __IO uint32_t frfsel12 : 1; /* [12] */ + __IO uint32_t frfsel13 : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } frf_bit; + }; + + /** + * @brief can reserved register, offset:0x218 + */ + __IO uint32_t reserved5; + + /** + * @brief can facfg register, offset:0x21C + */ + union + { + __IO uint32_t facfg; + struct + { + __IO uint32_t faen0 : 1; /* [0] */ + __IO uint32_t faen1 : 1; /* [1] */ + __IO uint32_t faen2 : 1; /* [2] */ + __IO uint32_t faen3 : 1; /* [3] */ + __IO uint32_t faen4 : 1; /* [4] */ + __IO uint32_t faen5 : 1; /* [5] */ + __IO uint32_t faen6 : 1; /* [6] */ + __IO uint32_t faen7 : 1; /* [7] */ + __IO uint32_t faen8 : 1; /* [8] */ + __IO uint32_t faen9 : 1; /* [9] */ + __IO uint32_t faen10 : 1; /* [10] */ + __IO uint32_t faen11 : 1; /* [11] */ + __IO uint32_t faen12 : 1; /* [12] */ + __IO uint32_t faen13 : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } facfg_bit; + }; + + /** + * @brief can reserved register, offset:0x220~0x23C + */ + __IO uint32_t reserved6[8]; + + /** + * @brief can ffb register, offset:0x240~0x2AC + */ + can_filter_register_type ffb[14]; +} can_type; + +/** + * @} + */ + +#define CAN1 ((can_type *) CAN1_BASE) + +/** @defgroup CAN_exported_functions + * @{ + */ + +void can_reset(can_type* can_x); +void can_baudrate_default_para_init(can_baudrate_type* can_baudrate_struct); +error_status can_baudrate_set(can_type* can_x, can_baudrate_type* can_baudrate_struct); +void can_default_para_init(can_base_type* can_base_struct); +error_status can_base_init(can_type* can_x, can_base_type* can_base_struct); +void can_filter_default_para_init(can_filter_init_type* can_filter_init_struct); +void can_filter_init(can_type* can_x, can_filter_init_type* can_filter_init_struct); +void can_debug_transmission_prohibit(can_type* can_x, confirm_state new_state); +void can_ttc_mode_enable(can_type* can_x, confirm_state new_state); +uint8_t can_message_transmit(can_type* can_x, can_tx_message_type* tx_message_struct); +can_transmit_status_type can_transmit_status_get(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox); +void can_transmit_cancel(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox); +void can_message_receive(can_type* can_x, can_rx_fifo_num_type fifo_number, can_rx_message_type* rx_message_struct); +void can_receive_fifo_release(can_type* can_x, can_rx_fifo_num_type fifo_number); +uint8_t can_receive_message_pending_get(can_type* can_x, can_rx_fifo_num_type fifo_number); +error_status can_operating_mode_set(can_type* can_x, can_operating_mode_type can_operating_mode); +can_enter_doze_status_type can_doze_mode_enter(can_type* can_x); +can_quit_doze_status_type can_doze_mode_exit(can_type* can_x); +can_error_record_type can_error_type_record_get(can_type* can_x); +uint8_t can_receive_error_counter_get(can_type* can_x); +uint8_t can_transmit_error_counter_get(can_type* can_x); +void can_interrupt_enable(can_type* can_x, uint32_t can_int, confirm_state new_state); +flag_status can_interrupt_flag_get(can_type* can_x, uint32_t can_flag); +flag_status can_flag_get(can_type* can_x, uint32_t can_flag); +void can_flag_clear(can_type* can_x, uint32_t can_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_crc.h b/libraries/drivers/inc/at32f425_crc.h new file mode 100644 index 0000000..7f258ec --- /dev/null +++ b/libraries/drivers/inc/at32f425_crc.h @@ -0,0 +1,198 @@ +/** + ************************************************************************** + * @file at32f425_crc.h + * @brief at32f425 crc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_CRC_H +#define __AT32F425_CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup CRC + * @{ + */ + +/** @defgroup CRC_exported_types + * @{ + */ + +/** + * @brief crc reverse input data + */ +typedef enum +{ + CRC_REVERSE_INPUT_NO_AFFECTE = 0x00, /*!< input data no reverse */ + CRC_REVERSE_INPUT_BY_BYTE = 0x01, /*!< input data reverse by byte */ + CRC_REVERSE_INPUT_BY_HALFWORD = 0x02, /*!< input data reverse by half word */ + CRC_REVERSE_INPUT_BY_WORD = 0x03 /*!< input data reverse by word */ +} crc_reverse_input_type; + +/** + * @brief crc reverse output data + */ +typedef enum +{ + CRC_REVERSE_OUTPUT_NO_AFFECTE = 0x00, /*!< output data no reverse */ + CRC_REVERSE_OUTPUT_DATA = 0x01 /*!< output data reverse by word */ +} crc_reverse_output_type; + +/** + * @brief crc polynomial size + */ +typedef enum +{ + CRC_POLY_SIZE_32B = 0x00, /*!< polynomial size 32 bits */ + CRC_POLY_SIZE_16B = 0x01, /*!< polynomial size 16 bits */ + CRC_POLY_SIZE_8B = 0x02, /*!< polynomial size 8 bits */ + CRC_POLY_SIZE_7B = 0x03 /*!< polynomial size 7 bits */ +} crc_poly_size_type; + +/** + * @brief type define crc register all + */ +typedef struct +{ + /** + * @brief crc dt register, offset:0x00 + */ + union + { + __IO uint32_t dt; + struct + { + __IO uint32_t dt : 32; /* [31:0] */ + } dt_bit; + }; + + /** + * @brief crc cdt register, offset:0x04 + */ + union + { + __IO uint32_t cdt; + struct + { + __IO uint32_t cdt : 8 ; /* [7:0] */ + __IO uint32_t reserved1 : 24 ;/* [31:8] */ + } cdt_bit; + }; + + /** + * @brief crc ctrl register, offset:0x08 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t rst : 1 ; /* [0] */ + __IO uint32_t reserved1 : 2 ; /* [2:1] */ + __IO uint32_t poly_size : 2 ; /* [4:3] */ + __IO uint32_t revid : 2 ; /* [6:5] */ + __IO uint32_t revod : 1 ; /* [7] */ + __IO uint32_t reserved2 : 24 ;/* [31:8] */ + } ctrl_bit; + }; + + /** + * @brief crm reserved1 register, offset:0x0C + */ + __IO uint32_t reserved1; + + /** + * @brief crc idt register, offset:0x10 + */ + union + { + __IO uint32_t idt; + struct + { + __IO uint32_t idt : 32; /* [31:0] */ + } idt_bit; + }; + + /** + * @brief crc polynomial register, offset:0x14 + */ + union + { + __IO uint32_t poly; + struct + { + __IO uint32_t poly : 32; /* [31:0] */ + } poly_bit; + }; + +} crc_type; + +/** + * @} + */ + +#define CRC ((crc_type *) CRC_BASE) + +/** @defgroup CRC_exported_functions + * @{ + */ + +void crc_data_reset(void); +uint32_t crc_one_word_calculate(uint32_t data); +uint32_t crc_block_calculate(uint32_t *pbuffer, uint32_t length); +uint32_t crc_data_get(void); +void crc_common_data_set(uint8_t cdt_value); +uint8_t crc_common_data_get(void); +void crc_init_data_set(uint32_t value); +void crc_reverse_input_data_set(crc_reverse_input_type value); +void crc_reverse_output_data_set(crc_reverse_output_type value); +void crc_poly_value_set(uint32_t value); +uint32_t crc_poly_value_get(void); +void crc_poly_size_set(crc_poly_size_type size); +crc_poly_size_type crc_poly_size_get(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_crm.h b/libraries/drivers/inc/at32f425_crm.h new file mode 100644 index 0000000..ff85abd --- /dev/null +++ b/libraries/drivers/inc/at32f425_crm.h @@ -0,0 +1,912 @@ +/** + ************************************************************************** + * @file at32f425_crm.h + * @brief at32f425 crm header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_CRM_H +#define __AT32F425_CRM_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup CRM + * @{ + */ + +#define CRM_REG(value) PERIPH_REG(CRM_BASE, value) +#define CRM_REG_BIT(value) PERIPH_REG_BIT(value) + +/** @defgroup CRM_flags_definition + * @brief crm flag + * @{ + */ + +#define CRM_HICK_STABLE_FLAG MAKE_VALUE(0x00, 1) /*!< high speed internal clock stable flag */ +#define CRM_HEXT_STABLE_FLAG MAKE_VALUE(0x00, 17) /*!< high speed external crystal stable flag */ +#define CRM_PLL_STABLE_FLAG MAKE_VALUE(0x00, 25) /*!< phase locking loop stable flag */ +#define CRM_LEXT_STABLE_FLAG MAKE_VALUE(0x20, 1) /*!< low speed external crystal stable flag */ +#define CRM_LICK_STABLE_FLAG MAKE_VALUE(0x24, 1) /*!< low speed internal clock stable flag */ +#define CRM_ALL_RESET_FLAG MAKE_VALUE(0x24, 24) /*!< all reset flag */ +#define CRM_NRST_RESET_FLAG MAKE_VALUE(0x24, 26) /*!< nrst pin reset flag */ +#define CRM_POR_RESET_FLAG MAKE_VALUE(0x24, 27) /*!< power on reset flag */ +#define CRM_SW_RESET_FLAG MAKE_VALUE(0x24, 28) /*!< software reset flag */ +#define CRM_WDT_RESET_FLAG MAKE_VALUE(0x24, 29) /*!< watchdog timer reset flag */ +#define CRM_WWDT_RESET_FLAG MAKE_VALUE(0x24, 30) /*!< window watchdog timer reset flag */ +#define CRM_LOWPOWER_RESET_FLAG MAKE_VALUE(0x24, 31) /*!< low-power reset flag */ +#define CRM_LICK_READY_INT_FLAG MAKE_VALUE(0x08, 0) /*!< low speed internal clock stable interrupt ready flag */ +#define CRM_LEXT_READY_INT_FLAG MAKE_VALUE(0x08, 1) /*!< low speed external crystal stable interrupt ready flag */ +#define CRM_HICK_READY_INT_FLAG MAKE_VALUE(0x08, 2) /*!< high speed internal clock stable interrupt ready flag */ +#define CRM_HEXT_READY_INT_FLAG MAKE_VALUE(0x08, 3) /*!< high speed external crystal stable interrupt ready flag */ +#define CRM_PLL_READY_INT_FLAG MAKE_VALUE(0x08, 4) /*!< phase locking loop stable interrupt ready flag */ +#define CRM_CLOCK_FAILURE_INT_FLAG MAKE_VALUE(0x08, 7) /*!< clock failure interrupt ready flag */ + +/** + * @} + */ + +/** @defgroup CRM_interrupts_definition + * @brief crm interrupt + * @{ + */ + +#define CRM_LICK_STABLE_INT ((uint32_t)0x00000100) /*!< low speed internal clock stable interrupt */ +#define CRM_LEXT_STABLE_INT ((uint32_t)0x00000200) /*!< low speed external crystal stable interrupt */ +#define CRM_HICK_STABLE_INT ((uint32_t)0x00000400) /*!< high speed internal clock stable interrupt */ +#define CRM_HEXT_STABLE_INT ((uint32_t)0x00000800) /*!< high speed external crystal stable interrupt */ +#define CRM_PLL_STABLE_INT ((uint32_t)0x00001000) /*!< phase locking loop stable interrupt */ +#define CRM_CLOCK_FAILURE_INT ((uint32_t)0x00800000) /*!< clock failure interrupt */ + +/** + * @} + */ + +/** @defgroup CRM_exported_types + * @{ + */ + +/** + * @brief crm periph clock + */ +typedef enum +{ + /* ahb periph */ + CRM_DMA1_PERIPH_CLOCK = MAKE_VALUE(0x14, 0), /*!< dma1 periph clock */ + CRM_CRC_PERIPH_CLOCK = MAKE_VALUE(0x14, 6), /*!< crc periph clock */ + CRM_OTGFS1_PERIPH_CLOCK = MAKE_VALUE(0x14, 12), /*!< otgfs1 periph clock */ + CRM_GPIOA_PERIPH_CLOCK = MAKE_VALUE(0x14, 17), /*!< gpioa periph clock */ + CRM_GPIOB_PERIPH_CLOCK = MAKE_VALUE(0x14, 18), /*!< gpiob periph clock */ + CRM_GPIOC_PERIPH_CLOCK = MAKE_VALUE(0x14, 19), /*!< gpioc periph clock */ + CRM_GPIOD_PERIPH_CLOCK = MAKE_VALUE(0x14, 20), /*!< gpiod periph clock */ + CRM_GPIOF_PERIPH_CLOCK = MAKE_VALUE(0x14, 22), /*!< gpiof periph clock */ + /* apb2 periph */ + CRM_SCFG_PERIPH_CLOCK = MAKE_VALUE(0x18, 0), /*!< scfg periph clock */ + CRM_ADC1_PERIPH_CLOCK = MAKE_VALUE(0x18, 9), /*!< adc1 periph clock */ + CRM_TMR1_PERIPH_CLOCK = MAKE_VALUE(0x18, 11), /*!< tmr1 periph clock */ + CRM_SPI1_PERIPH_CLOCK = MAKE_VALUE(0x18, 12), /*!< spi1 periph clock */ + CRM_USART1_PERIPH_CLOCK = MAKE_VALUE(0x18, 14), /*!< usart1 periph clock */ + CRM_TMR15_PERIPH_CLOCK = MAKE_VALUE(0x18, 16), /*!< tmr15 periph clock */ + CRM_TMR16_PERIPH_CLOCK = MAKE_VALUE(0x18, 17), /*!< tmr16 periph clock */ + CRM_TMR17_PERIPH_CLOCK = MAKE_VALUE(0x18, 18), /*!< tmr17 periph clock */ + /* apb1 periph */ + CRM_TMR2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 0), /*!< tmr2 periph clock */ + CRM_TMR3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 1), /*!< tmr3 periph clock */ + CRM_TMR6_PERIPH_CLOCK = MAKE_VALUE(0x1C, 4), /*!< tmr6 periph clock */ + CRM_TMR7_PERIPH_CLOCK = MAKE_VALUE(0x1C, 5), /*!< tmr7 periph clock */ + CRM_TMR13_PERIPH_CLOCK = MAKE_VALUE(0x1C, 7), /*!< tmr13 periph clock */ + CRM_TMR14_PERIPH_CLOCK = MAKE_VALUE(0x1C, 8), /*!< tmr14 periph clock */ + CRM_WWDT_PERIPH_CLOCK = MAKE_VALUE(0x1C, 11), /*!< wwdt periph clock */ + CRM_SPI2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 14), /*!< spi2 periph clock */ + CRM_SPI3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 15), /*!< spi3 periph clock */ + CRM_USART2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 17), /*!< usart2 periph clock */ + CRM_USART3_PERIPH_CLOCK = MAKE_VALUE(0x1C, 18), /*!< usart3 periph clock */ + CRM_USART4_PERIPH_CLOCK = MAKE_VALUE(0x1C, 19), /*!< usart4 periph clock */ + CRM_I2C1_PERIPH_CLOCK = MAKE_VALUE(0x1C, 21), /*!< i2c1 periph clock */ + CRM_I2C2_PERIPH_CLOCK = MAKE_VALUE(0x1C, 22), /*!< i2c2 periph clock */ + CRM_CAN1_PERIPH_CLOCK = MAKE_VALUE(0x1C, 25), /*!< can1 periph clock */ + CRM_ACC_PERIPH_CLOCK = MAKE_VALUE(0x1C, 27), /*!< acc periph clock */ + CRM_PWC_PERIPH_CLOCK = MAKE_VALUE(0x1C, 28) /*!< pwc periph clock */ + +} crm_periph_clock_type; + +/** + * @brief crm periph reset + */ +typedef enum +{ + /* ahb periph */ + CRM_OTGFS1_PERIPH_RESET = MAKE_VALUE(0x28, 12), /*!< otgfs1 periph reset */ + CRM_GPIOA_PERIPH_RESET = MAKE_VALUE(0x28, 17), /*!< gpioa periph reset */ + CRM_GPIOB_PERIPH_RESET = MAKE_VALUE(0x28, 18), /*!< gpiob periph reset */ + CRM_GPIOC_PERIPH_RESET = MAKE_VALUE(0x28, 19), /*!< gpioc periph reset */ + CRM_GPIOD_PERIPH_RESET = MAKE_VALUE(0x28, 20), /*!< gpiod periph reset */ + CRM_GPIOF_PERIPH_RESET = MAKE_VALUE(0x28, 22), /*!< gpiof periph reset */ + /* apb2 periph */ + CRM_SCFG_PERIPH_RESET = MAKE_VALUE(0x0C, 0), /*!< scfg periph reset */ + CRM_EXINT_PERIPH_RESET = MAKE_VALUE(0x0C, 1), /*!< exint periph reset */ + CRM_ADC1_PERIPH_RESET = MAKE_VALUE(0x0C, 9), /*!< adc1 periph reset */ + CRM_TMR1_PERIPH_RESET = MAKE_VALUE(0x0C, 11), /*!< tmr1 periph reset */ + CRM_SPI1_PERIPH_RESET = MAKE_VALUE(0x0C, 12), /*!< spi2 periph reset */ + CRM_USART1_PERIPH_RESET = MAKE_VALUE(0x0C, 14), /*!< usart1 periph reset */ + CRM_TMR15_PERIPH_RESET = MAKE_VALUE(0x0C, 16), /*!< tmr15 periph reset */ + CRM_TMR16_PERIPH_RESET = MAKE_VALUE(0x0C, 17), /*!< tmr16 periph reset */ + CRM_TMR17_PERIPH_RESET = MAKE_VALUE(0x0C, 18), /*!< tmr17 periph reset */ + /* apb1 periph */ + CRM_TMR2_PERIPH_RESET = MAKE_VALUE(0x10, 0), /*!< tmr2 periph reset */ + CRM_TMR3_PERIPH_RESET = MAKE_VALUE(0x10, 1), /*!< tmr3 periph reset */ + CRM_TMR6_PERIPH_RESET = MAKE_VALUE(0x10, 4), /*!< tmr6 periph reset */ + CRM_TMR7_PERIPH_RESET = MAKE_VALUE(0x10, 5), /*!< tmr7 periph reset */ + CRM_TMR13_PERIPH_RESET = MAKE_VALUE(0x10, 7), /*!< tmr13 periph reset */ + CRM_TMR14_PERIPH_RESET = MAKE_VALUE(0x10, 8), /*!< tmr14 periph reset */ + CRM_WWDT_PERIPH_RESET = MAKE_VALUE(0x10, 11), /*!< wwdt periph reset */ + CRM_SPI2_PERIPH_RESET = MAKE_VALUE(0x10, 14), /*!< spi2 periph reset */ + CRM_SPI3_PERIPH_RESET = MAKE_VALUE(0x10, 15), /*!< spi3 periph reset */ + CRM_USART2_PERIPH_RESET = MAKE_VALUE(0x10, 17), /*!< usart2 periph reset */ + CRM_USART3_PERIPH_RESET = MAKE_VALUE(0x10, 18), /*!< usart3 periph reset */ + CRM_USART4_PERIPH_RESET = MAKE_VALUE(0x10, 19), /*!< usart4 periph reset */ + CRM_I2C1_PERIPH_RESET = MAKE_VALUE(0x10, 21), /*!< i2c1 periph reset */ + CRM_I2C2_PERIPH_RESET = MAKE_VALUE(0x10, 22), /*!< i2c2 periph reset */ + CRM_CAN1_PERIPH_RESET = MAKE_VALUE(0x10, 25), /*!< can1 periph reset */ + CRM_ACC_PERIPH_RESET = MAKE_VALUE(0x10, 27), /*!< acc periph reset */ + CRM_PWC_PERIPH_RESET = MAKE_VALUE(0x10, 28) /*!< pwc periph reset */ + +} crm_periph_reset_type; + +/** + * @brief crm periph clock in sleep mode + */ +typedef enum +{ + /* ahb periph */ + CRM_SRAM_PERIPH_CLOCK_SLEEP_MODE = MAKE_VALUE(0x14, 2), /*!< sram sleep mode periph clock */ + CRM_FLASH_PERIPH_CLOCK_SLEEP_MODE = MAKE_VALUE(0x14, 4) /*!< flash sleep mode periph clock */ +} crm_periph_clock_sleepmd_type; + +/** + * @brief crm pll mult_x + */ +typedef enum +{ + CRM_PLL_MULT_2 = 0, /*!< pll multiplication factor 2 */ + CRM_PLL_MULT_3 = 1, /*!< pll multiplication factor 3 */ + CRM_PLL_MULT_4 = 2, /*!< pll multiplication factor 4 */ + CRM_PLL_MULT_5 = 3, /*!< pll multiplication factor 5 */ + CRM_PLL_MULT_6 = 4, /*!< pll multiplication factor 6 */ + CRM_PLL_MULT_7 = 5, /*!< pll multiplication factor 7 */ + CRM_PLL_MULT_8 = 6, /*!< pll multiplication factor 8 */ + CRM_PLL_MULT_9 = 7, /*!< pll multiplication factor 9 */ + CRM_PLL_MULT_10 = 8, /*!< pll multiplication factor 10 */ + CRM_PLL_MULT_11 = 9, /*!< pll multiplication factor 11 */ + CRM_PLL_MULT_12 = 10, /*!< pll multiplication factor 12 */ + CRM_PLL_MULT_13 = 11, /*!< pll multiplication factor 13 */ + CRM_PLL_MULT_14 = 12, /*!< pll multiplication factor 14 */ + CRM_PLL_MULT_15 = 13, /*!< pll multiplication factor 15 */ + CRM_PLL_MULT_16 = 15, /*!< pll multiplication factor 16 */ + CRM_PLL_MULT_17 = 16, /*!< pll multiplication factor 17 */ + CRM_PLL_MULT_18 = 17, /*!< pll multiplication factor 18 */ + CRM_PLL_MULT_19 = 18, /*!< pll multiplication factor 19 */ + CRM_PLL_MULT_20 = 19, /*!< pll multiplication factor 20 */ + CRM_PLL_MULT_21 = 20, /*!< pll multiplication factor 21 */ + CRM_PLL_MULT_22 = 21, /*!< pll multiplication factor 22 */ + CRM_PLL_MULT_23 = 22, /*!< pll multiplication factor 23 */ + CRM_PLL_MULT_24 = 23, /*!< pll multiplication factor 24 */ + CRM_PLL_MULT_25 = 24, /*!< pll multiplication factor 25 */ + CRM_PLL_MULT_26 = 25, /*!< pll multiplication factor 26 */ + CRM_PLL_MULT_27 = 26, /*!< pll multiplication factor 27 */ + CRM_PLL_MULT_28 = 27, /*!< pll multiplication factor 28 */ + CRM_PLL_MULT_29 = 28, /*!< pll multiplication factor 29 */ + CRM_PLL_MULT_30 = 29, /*!< pll multiplication factor 30 */ + CRM_PLL_MULT_31 = 30, /*!< pll multiplication factor 31 */ + CRM_PLL_MULT_32 = 31, /*!< pll multiplication factor 32 */ + CRM_PLL_MULT_33 = 32, /*!< pll multiplication factor 33 */ + CRM_PLL_MULT_34 = 33, /*!< pll multiplication factor 34 */ + CRM_PLL_MULT_35 = 34, /*!< pll multiplication factor 35 */ + CRM_PLL_MULT_36 = 35, /*!< pll multiplication factor 36 */ + CRM_PLL_MULT_37 = 36, /*!< pll multiplication factor 37 */ + CRM_PLL_MULT_38 = 37, /*!< pll multiplication factor 38 */ + CRM_PLL_MULT_39 = 38, /*!< pll multiplication factor 39 */ + CRM_PLL_MULT_40 = 39, /*!< pll multiplication factor 40 */ + CRM_PLL_MULT_41 = 40, /*!< pll multiplication factor 41 */ + CRM_PLL_MULT_42 = 41, /*!< pll multiplication factor 42 */ + CRM_PLL_MULT_43 = 42, /*!< pll multiplication factor 43 */ + CRM_PLL_MULT_44 = 43, /*!< pll multiplication factor 44 */ + CRM_PLL_MULT_45 = 44, /*!< pll multiplication factor 45 */ + CRM_PLL_MULT_46 = 45, /*!< pll multiplication factor 46 */ + CRM_PLL_MULT_47 = 46, /*!< pll multiplication factor 47 */ + CRM_PLL_MULT_48 = 47, /*!< pll multiplication factor 48 */ + CRM_PLL_MULT_49 = 48, /*!< pll multiplication factor 49 */ + CRM_PLL_MULT_50 = 49, /*!< pll multiplication factor 50 */ + CRM_PLL_MULT_51 = 50, /*!< pll multiplication factor 51 */ + CRM_PLL_MULT_52 = 51, /*!< pll multiplication factor 52 */ + CRM_PLL_MULT_53 = 52, /*!< pll multiplication factor 53 */ + CRM_PLL_MULT_54 = 53, /*!< pll multiplication factor 54 */ + CRM_PLL_MULT_55 = 54, /*!< pll multiplication factor 55 */ + CRM_PLL_MULT_56 = 55, /*!< pll multiplication factor 56 */ + CRM_PLL_MULT_57 = 56, /*!< pll multiplication factor 57 */ + CRM_PLL_MULT_58 = 57, /*!< pll multiplication factor 58 */ + CRM_PLL_MULT_59 = 58, /*!< pll multiplication factor 59 */ + CRM_PLL_MULT_60 = 59, /*!< pll multiplication factor 60 */ + CRM_PLL_MULT_61 = 60, /*!< pll multiplication factor 61 */ + CRM_PLL_MULT_62 = 61, /*!< pll multiplication factor 62 */ + CRM_PLL_MULT_63 = 62, /*!< pll multiplication factor 63 */ + CRM_PLL_MULT_64 = 63 /*!< pll multiplication factor 64 */ +} crm_pll_mult_type; + +/** + * @brief crm pll fref_x + */ +typedef enum +{ + CRM_PLL_FREF_4M = 0, /*!< pll refrence clock between 3.9 mhz and 5 mhz */ + CRM_PLL_FREF_6M = 1, /*!< pll refrence clock between 5.2 mhz and 6.25 mhz */ + CRM_PLL_FREF_8M = 2, /*!< pll refrence clock between 7.8125 mhz and 8.33 mhz */ + CRM_PLL_FREF_12M = 3, /*!< pll refrence clock between 8.33 mhz and 12.5 mhz */ + CRM_PLL_FREF_16M = 4, /*!< pll refrence clock between 15.625 mhz and 20.83 mhz */ + CRM_PLL_FREF_25M = 5 /*!< pll refrence clock between 20.83 mhz and 31.255 mhz */ +} crm_pll_fref_type; + +/** + * @brief crm pll clock source + */ +typedef enum +{ + CRM_PLL_SOURCE_HICK = 0x00, /*!< high speed internal clock as pll reference clock source */ + CRM_PLL_SOURCE_HEXT = 0x01, /*!< high speed external crystal as pll reference clock source */ + CRM_PLL_SOURCE_HEXT_DIV = 0x02 /*!< high speed external crystal div as pll reference clock source */ +} crm_pll_clock_source_type; + +/** + * @brief crm pll fr + */ +typedef enum +{ + CRM_PLL_FR_1 = 0x00, /*!< pll post-division div1 */ + CRM_PLL_FR_2 = 0x01, /*!< pll post-division div2 */ + CRM_PLL_FR_4 = 0x02, /*!< pll post-division div4 */ + CRM_PLL_FR_8 = 0x03, /*!< pll post-division div8 */ + CRM_PLL_FR_16 = 0x04, /*!< pll post-division div16 */ + CRM_PLL_FR_32 = 0x05 /*!< pll post-division div32 */ +} crm_pll_fr_type; + +/** + * @brief crm clock source + */ +typedef enum +{ + CRM_CLOCK_SOURCE_HICK = 0x00, /*!< high speed internal clock */ + CRM_CLOCK_SOURCE_HEXT = 0x01, /*!< high speed external crystal */ + CRM_CLOCK_SOURCE_PLL = 0x02, /*!< phase locking loop */ + CRM_CLOCK_SOURCE_LEXT = 0x03, /*!< low speed external crystal */ + CRM_CLOCK_SOURCE_LICK = 0x04 /*!< low speed internal clock */ +} crm_clock_source_type; + +/** + * @brief crm ahb division + */ +typedef enum +{ + CRM_AHB_DIV_1 = 0x00, /*!< sclk div1 to ahbclk */ + CRM_AHB_DIV_2 = 0x08, /*!< sclk div2 to ahbclk */ + CRM_AHB_DIV_4 = 0x09, /*!< sclk div4 to ahbclk */ + CRM_AHB_DIV_8 = 0x0A, /*!< sclk div8 to ahbclk */ + CRM_AHB_DIV_16 = 0x0B, /*!< sclk div16 to ahbclk */ + CRM_AHB_DIV_64 = 0x0C, /*!< sclk div64 to ahbclk */ + CRM_AHB_DIV_128 = 0x0D, /*!< sclk div128 to ahbclk */ + CRM_AHB_DIV_256 = 0x0E, /*!< sclk div256 to ahbclk */ + CRM_AHB_DIV_512 = 0x0F /*!< sclk div512 to ahbclk */ +} crm_ahb_div_type; + +/** + * @brief crm apb1 division + */ +typedef enum +{ + CRM_APB1_DIV_1 = 0x00, /*!< ahbclk div1 to apb1clk */ + CRM_APB1_DIV_2 = 0x04, /*!< ahbclk div2 to apb1clk */ + CRM_APB1_DIV_4 = 0x05, /*!< ahbclk div4 to apb1clk */ + CRM_APB1_DIV_8 = 0x06, /*!< ahbclk div8 to apb1clk */ + CRM_APB1_DIV_16 = 0x07 /*!< ahbclk div16 to apb1clk */ +} crm_apb1_div_type; + +/** + * @brief crm apb2 division + */ +typedef enum +{ + CRM_APB2_DIV_1 = 0x00, /*!< ahbclk div1 to apb2clk */ + CRM_APB2_DIV_2 = 0x04, /*!< ahbclk div2 to apb2clk */ + CRM_APB2_DIV_4 = 0x05, /*!< ahbclk div4 to apb2clk */ + CRM_APB2_DIV_8 = 0x06, /*!< ahbclk div8 to apb2clk */ + CRM_APB2_DIV_16 = 0x07 /*!< ahbclk div16 to apb2clk */ +} crm_apb2_div_type; + +/** + * @brief crm adc division + */ +typedef enum +{ + CRM_ADC_DIV_2 = 0x00, /*!< apb2clk div2 to adcclk */ + CRM_ADC_DIV_4 = 0x01, /*!< apb2clk div4 to adcclk */ + CRM_ADC_DIV_6 = 0x02, /*!< apb2clk div6 to adcclk */ + CRM_ADC_DIV_8 = 0x03, /*!< apb2clk div8 to adcclk */ + CRM_ADC_DIV_12 = 0x05, /*!< apb2clk div12 to adcclk */ + CRM_ADC_DIV_16 = 0x07 /*!< apb2clk div16 to adcclk */ +} crm_adc_div_type; + +/** + * @brief crm usb division + */ +typedef enum +{ + CRM_USB_DIV_1_5 = 0x00, /*!< pllclk div1.5 to usbclk */ + CRM_USB_DIV_1 = 0x01, /*!< pllclk div1 to usbclk */ + CRM_USB_DIV_2_5 = 0x02, /*!< pllclk div2.5 to usbclk */ + CRM_USB_DIV_2 = 0x03, /*!< pllclk div2 to usbclk */ + CRM_USB_DIV_3_5 = 0x04, /*!< pllclk div3.5 to usbclk */ + CRM_USB_DIV_3 = 0x05, /*!< pllclk div3 to usbclk */ + CRM_USB_DIV_4 = 0x06 /*!< pllclk div4 to usbclk */ +} crm_usb_div_type; + +/** + * @brief crm ertc clock + */ +typedef enum +{ + CRM_ERTC_CLOCK_NOCLK = 0x00, /*!< no clock as ertc clock source */ + CRM_ERTC_CLOCK_LEXT = 0x01, /*!< low speed external crystal as ertc clock source */ + CRM_ERTC_CLOCK_LICK = 0x02, /*!< low speed internal clock as ertc clock source */ + CRM_ERTC_CLOCK_HEXT_DIV = 0x03 /*!< high speed external crystal div as ertc clock source */ +} crm_ertc_clock_type; + +/** + * @brief crm hick 48mhz division + */ +typedef enum +{ + CRM_HICK48_DIV6 = 0x00, /*!< high speed internal clock (48 mhz) div6 */ + CRM_HICK48_NODIV = 0x01 /*!< high speed internal clock (48 mhz) no div */ +} crm_hick_div_6_type; + +/** + * @brief crm sclk select + */ +typedef enum +{ + CRM_SCLK_HICK = 0x00, /*!< select high speed internal clock as sclk */ + CRM_SCLK_HEXT = 0x01, /*!< select high speed external crystal as sclk */ + CRM_SCLK_PLL = 0x02 /*!< select phase locking loop clock as sclk */ +} crm_sclk_type; + +/** + * @brief crm clkout select + */ +typedef enum +{ + CRM_CLKOUT_NOCLK = 0x00, /*!< output no clock to clkout pin */ + CRM_CLKOUT_LICK = 0x02, /*!< output low speed internal clock to clkout pin */ + CRM_CLKOUT_LEXT = 0x03, /*!< output low speed external crystal to clkout pin */ + CRM_CLKOUT_SCLK = 0x04, /*!< output system clock to clkout pin */ + CRM_CLKOUT_HICK = 0x05, /*!< output high speed internal clock to clkout pin */ + CRM_CLKOUT_HEXT = 0x06, /*!< output high speed external crystal to clkout pin */ + CRM_CLKOUT_PLL_DIV_2 = 0x07, /*!< output phase locking loop clock div2 to clkout pin */ + CRM_CLKOUT_PLL_DIV_4 = 0x0C, /*!< output phase locking loop clock div4 to clkout pin */ + CRM_CLKOUT_USB = 0x0D, /*!< output usbclk to clkout pin */ + CRM_CLKOUT_ADC = 0x0E /*!< output adcclk to clkout pin */ +} crm_clkout_select_type; + +/** + * @brief crm clkout division + */ +typedef enum +{ + CRM_CLKOUT_DIV_1 = 0x00, /*!< clkout div1 */ + CRM_CLKOUT_DIV_2 = 0x08, /*!< clkout div2 */ + CRM_CLKOUT_DIV_4 = 0x09, /*!< clkout div4 */ + CRM_CLKOUT_DIV_8 = 0x0A, /*!< clkout div8 */ + CRM_CLKOUT_DIV_16 = 0x0B, /*!< clkout div16 */ + CRM_CLKOUT_DIV_64 = 0x0C, /*!< clkout div64 */ + CRM_CLKOUT_DIV_128 = 0x0D, /*!< clkout div128 */ + CRM_CLKOUT_DIV_256 = 0x0E, /*!< clkout div256 */ + CRM_CLKOUT_DIV_512 = 0x0F /*!< clkout div512 */ +} crm_clkout_div_type; + +/** + * @brief crm usb 48 mhz clock source select + */ +typedef enum +{ + CRM_USB_CLOCK_SOURCE_PLL = 0x00, /*!< select phase locking loop clock as usb clock source */ + CRM_USB_CLOCK_SOURCE_HICK = 0x01 /*!< select high speed internal clock as usb clock source */ +} crm_usb_clock_source_type; + +/** + * @brief crm hick as system clock frequency select + */ +typedef enum +{ + CRM_HICK_SCLK_8MHZ = 0x00, /*!< fixed 8 mhz when hick is selected as sclk */ + CRM_HICK_SCLK_48MHZ = 0x01 /*!< 8 mhz or 48 mhz depend on hickdiv when hick is selected as sclk */ +} crm_hick_sclk_frequency_type; + +/** + * @brief crm clocks freqency structure + */ +typedef struct +{ + uint32_t sclk_freq; /*!< system clock frequency */ + uint32_t ahb_freq; /*!< ahb bus clock frequency */ + uint32_t apb2_freq; /*!< apb2 bus clock frequency */ + uint32_t apb1_freq; /*!< apb1 bus clock frequency */ + uint32_t adc_freq; /*!< adc clock frequency */ +} crm_clocks_freq_type; + +/** + * @brief type define crm register all + */ +typedef struct +{ + /** + * @brief crm ctrl register, offset:0x00 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t hicken : 1; /* [0] */ + __IO uint32_t hickstbl : 1; /* [1] */ + __IO uint32_t hicktrim : 6; /* [7:2] */ + __IO uint32_t hickcal : 8; /* [15:8] */ + __IO uint32_t hexten : 1; /* [16] */ + __IO uint32_t hextstbl : 1; /* [17] */ + __IO uint32_t hextbyps : 1; /* [18] */ + __IO uint32_t cfden : 1; /* [19] */ + __IO uint32_t reserved1 : 4; /* [23:20] */ + __IO uint32_t pllen : 1; /* [24] */ + __IO uint32_t pllstbl : 1; /* [25] */ + __IO uint32_t reserved2 : 6; /* [31:26] */ + } ctrl_bit; + }; + + /** + * @brief crm cfg register, offset:0x04 + */ + union + { + __IO uint32_t cfg; + struct + { + __IO uint32_t sclksel : 2; /* [1:0] */ + __IO uint32_t sclksts : 2; /* [3:2] */ + __IO uint32_t ahbdiv : 4; /* [7:4] */ + __IO uint32_t apb1div : 3; /* [10:8] */ + __IO uint32_t apb2div : 3; /* [13:11] */ + __IO uint32_t adcdiv_l : 2; /* [15:14] */ + __IO uint32_t pllrcs : 1; /* [16] */ + __IO uint32_t pllhextdiv : 1; /* [17] */ + __IO uint32_t pllmult_l : 4; /* [21:18] */ + __IO uint32_t usbdiv_l : 2; /* [23:22] */ + __IO uint32_t clkout_sel : 3; /* [26:24] */ + __IO uint32_t usbdiv_h : 1; /* [27] */ + __IO uint32_t adcdiv_h : 1; /* [28] */ + __IO uint32_t pllmult_h : 2; /* [30:29] */ + __IO uint32_t reserved1 : 1; /* [31] */ + } cfg_bit; + }; + + /** + * @brief crm clkint register, offset:0x08 + */ + union + { + __IO uint32_t clkint; + struct + { + __IO uint32_t lickstblf : 1; /* [0] */ + __IO uint32_t lextstblf : 1; /* [1] */ + __IO uint32_t hickstblf : 1; /* [2] */ + __IO uint32_t hextstblf : 1; /* [3] */ + __IO uint32_t pllstblf : 1; /* [4] */ + __IO uint32_t reserved1 : 2; /* [6:5] */ + __IO uint32_t cfdf : 1; /* [7] */ + __IO uint32_t lickstblien : 1; /* [8] */ + __IO uint32_t lextstblien : 1; /* [9] */ + __IO uint32_t hickstblien : 1; /* [10] */ + __IO uint32_t hextstblien : 1; /* [11] */ + __IO uint32_t pllstblien : 1; /* [12] */ + __IO uint32_t reserved2 : 3; /* [15:13] */ + __IO uint32_t lickstblfc : 1; /* [16] */ + __IO uint32_t lextstblfc : 1; /* [17] */ + __IO uint32_t hickstblfc : 1; /* [18] */ + __IO uint32_t hextstblfc : 1; /* [19] */ + __IO uint32_t pllstblfc : 1; /* [20] */ + __IO uint32_t reserved3 : 2; /* [22:21] */ + __IO uint32_t cfdfc : 1; /* [23] */ + __IO uint32_t reserved4 : 8; /* [31:24] */ + } clkint_bit; + }; + + /** + * @brief crm apb2rst register, offset:0x0C + */ + union + { + __IO uint32_t apb2rst; + struct + { + __IO uint32_t scfgrst : 1; /* [0] */ + __IO uint32_t exintrst : 1; /* [1] */ + __IO uint32_t reserved1 : 7; /* [8:2] */ + __IO uint32_t adc1rst : 1; /* [9] */ + __IO uint32_t reserved2 : 1; /* [10] */ + __IO uint32_t tmr1rst : 1; /* [11] */ + __IO uint32_t spi1rst : 1; /* [12] */ + __IO uint32_t reserved3 : 1; /* [13] */ + __IO uint32_t usart1rst : 1; /* [14] */ + __IO uint32_t reserved4 : 1; /* [15] */ + __IO uint32_t tmr15rst : 1; /* [16] */ + __IO uint32_t tmr16rst : 1; /* [17] */ + __IO uint32_t tmr17rst : 1; /* [18] */ + __IO uint32_t reserved5 : 13;/* [31:19] */ + } apb2rst_bit; + }; + + /** + * @brief crm apb1rst register, offset:0x10 + */ + union + { + __IO uint32_t apb1rst; + struct + { + __IO uint32_t tmr2rst : 1; /* [0] */ + __IO uint32_t tmr3rst : 1; /* [1] */ + __IO uint32_t reserved1 : 2; /* [3:2] */ + __IO uint32_t tmr6rst : 1; /* [4] */ + __IO uint32_t tmr7rst : 1; /* [5] */ + __IO uint32_t reserved2 : 1; /* [6] */ + __IO uint32_t tmr13rst : 1; /* [7] */ + __IO uint32_t tmr14rst : 1; /* [8] */ + __IO uint32_t reserved3 : 2; /* [10:9] */ + __IO uint32_t wwdtrst : 1; /* [11] */ + __IO uint32_t reserved4 : 2; /* [13:12] */ + __IO uint32_t spi2rst : 1; /* [14] */ + __IO uint32_t spi3rst : 1; /* [15] */ + __IO uint32_t reserved5 : 1; /* [16] */ + __IO uint32_t usart2rst : 1; /* [17] */ + __IO uint32_t usart3rst : 1; /* [18] */ + __IO uint32_t usart4rst : 1; /* [19] */ + __IO uint32_t reserved6 : 1; /* [20] */ + __IO uint32_t i2c1rst : 1; /* [21] */ + __IO uint32_t i2c2rst : 1; /* [22] */ + __IO uint32_t reserved7 : 2; /* [24:23] */ + __IO uint32_t can1rst : 1; /* [25] */ + __IO uint32_t reserved8 : 1; /* [26] */ + __IO uint32_t accrst : 1; /* [27] */ + __IO uint32_t pwcrst : 1; /* [28] */ + __IO uint32_t reserved9 : 2; /* [31:29] */ + } apb1rst_bit; + }; + + /** + * @brief crm ahben register, offset:0x14 + */ + union + { + __IO uint32_t ahben; + struct + { + __IO uint32_t dma1en : 1; /* [0] */ + __IO uint32_t reserved1 : 1; /* [1] */ + __IO uint32_t sramen : 1; /* [2] */ + __IO uint32_t reserved2 : 1; /* [3] */ + __IO uint32_t flashen : 1; /* [4] */ + __IO uint32_t reserved3 : 1; /* [5] */ + __IO uint32_t crcen : 1; /* [6] */ + __IO uint32_t reserved4 : 5; /* [11:7] */ + __IO uint32_t otgfs1en : 1; /* [12] */ + __IO uint32_t reserved5 : 4; /* [16:13] */ + __IO uint32_t gpioaen : 1; /* [17] */ + __IO uint32_t gpioben : 1; /* [18] */ + __IO uint32_t gpiocen : 1; /* [19] */ + __IO uint32_t gpioden : 1; /* [20] */ + __IO uint32_t reserved6 : 1; /* [21] */ + __IO uint32_t gpiofen : 1; /* [22] */ + __IO uint32_t reserved7 : 9; /* [31:23] */ + } ahben_bit; + }; + + /** + * @brief crm apb2en register, offset:0x18 + */ + union + { + __IO uint32_t apb2en; + struct + { + __IO uint32_t scfgen : 1; /* [0] */ + __IO uint32_t reserved1 : 8; /* [8:1] */ + __IO uint32_t adc1en : 1; /* [9] */ + __IO uint32_t reserved2 : 1; /* [10] */ + __IO uint32_t tmr1en : 1; /* [11] */ + __IO uint32_t spi1en : 1; /* [12] */ + __IO uint32_t reserved3 : 1; /* [13] */ + __IO uint32_t usart1en : 1; /* [14] */ + __IO uint32_t reserved4 : 1; /* [15] */ + __IO uint32_t tmr15en : 1; /* [16] */ + __IO uint32_t tmr16en : 1; /* [17] */ + __IO uint32_t tmr17en : 1; /* [18] */ + __IO uint32_t reserved5 : 13;/* [31:19] */ + } apb2en_bit; + }; + + /** + * @brief crm apb1en register, offset:0x1C + */ + union + { + __IO uint32_t apb1en; + struct + { + __IO uint32_t tmr2en : 1; /* [0] */ + __IO uint32_t tmr3en : 1; /* [1] */ + __IO uint32_t reserved1 : 2; /* [3:2] */ + __IO uint32_t tmr6en : 1; /* [4] */ + __IO uint32_t tmr7en : 1; /* [5] */ + __IO uint32_t reserved2 : 1; /* [6] */ + __IO uint32_t tmr13en : 1; /* [7] */ + __IO uint32_t tmr14en : 1; /* [8] */ + __IO uint32_t reserved3 : 2; /* [10:9] */ + __IO uint32_t wwdten : 1; /* [11] */ + __IO uint32_t reserved4 : 2; /* [13:12] */ + __IO uint32_t spi2en : 1; /* [14] */ + __IO uint32_t spi3en : 1; /* [15] */ + __IO uint32_t reserved5 : 1; /* [16] */ + __IO uint32_t usart2en : 1; /* [17] */ + __IO uint32_t usart3en : 1; /* [18] */ + __IO uint32_t usart4en : 1; /* [19] */ + __IO uint32_t reserved6 : 1; /* [20] */ + __IO uint32_t i2c1en : 1; /* [21] */ + __IO uint32_t i2c2en : 1; /* [22] */ + __IO uint32_t reserved7 : 2; /* [24:23] */ + __IO uint32_t can1en : 1; /* [25] */ + __IO uint32_t reserved8 : 1; /* [26] */ + __IO uint32_t accen : 1; /* [27] */ + __IO uint32_t pwcen : 1; /* [28] */ + __IO uint32_t reserved9 : 2; /* [31:29] */ + } apb1en_bit; + }; + + /** + * @brief crm bpdc register, offset:0x20 + */ + union + { + __IO uint32_t bpdc; + struct + { + __IO uint32_t lexten : 1; /* [0] */ + __IO uint32_t lextstbl : 1; /* [1] */ + __IO uint32_t lextbyps : 1; /* [2] */ + __IO uint32_t reserved1 : 5; /* [7:3] */ + __IO uint32_t ertcsel : 2; /* [9:8] */ + __IO uint32_t reserved2 : 5; /* [14:10] */ + __IO uint32_t ertcen : 1; /* [15] */ + __IO uint32_t bpdrst : 1; /* [16] */ + __IO uint32_t reserved3 : 15;/* [31:17] */ + } bpdc_bit; + }; + + /** + * @brief crm ctrlsts register, offset:0x24 + */ + union + { + __IO uint32_t ctrlsts; + struct + { + __IO uint32_t licken : 1; /* [0] */ + __IO uint32_t lickstbl : 1; /* [1] */ + __IO uint32_t reserved1 : 22;/* [23:2] */ + __IO uint32_t rstfc : 1; /* [24] */ + __IO uint32_t reserved2 : 1; /* [25] */ + __IO uint32_t nrstf : 1; /* [26] */ + __IO uint32_t porrstf : 1; /* [27] */ + __IO uint32_t swrstf : 1; /* [28] */ + __IO uint32_t wdtrstf : 1; /* [29] */ + __IO uint32_t wwdtrstf : 1; /* [30] */ + __IO uint32_t lprstf : 1; /* [31] */ + } ctrlsts_bit; + }; + + /** + * @brief crm ahbrst register, offset:0x28 + */ + union + { + __IO uint32_t ahbrst; + struct + { + __IO uint32_t reserved1 : 12;/* [11:0] */ + __IO uint32_t otgfs1rst : 1; /* [12] */ + __IO uint32_t reserved2 : 4; /* [16:13] */ + __IO uint32_t gpioarst : 1; /* [17] */ + __IO uint32_t gpiobrst : 1; /* [18] */ + __IO uint32_t gpiocrst : 1; /* [19] */ + __IO uint32_t gpiodrst : 1; /* [20] */ + __IO uint32_t reserved3 : 1; /* [21] */ + __IO uint32_t gpiofrst : 1; /* [22] */ + __IO uint32_t reserved4 : 9; /* [31:23] */ + } ahbrst_bit; + }; + + /** + * @brief crm pll register, offset:0x2C + */ + union + { + __IO uint32_t pll; + struct + { + __IO uint32_t pllfr : 3; /* [2:0] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t pllms : 4; /* [7:4] */ + __IO uint32_t pllns : 9; /* [16:8] */ + __IO uint32_t reserved2 : 7; /* [23:17] */ + __IO uint32_t pllfref : 3; /* [26:24] */ + __IO uint32_t reserved3 : 4; /* [30:27] */ + __IO uint32_t pllcfgen : 1; /* [31] */ + } pll_bit; + }; + + /** + * @brief crm misc1 register, offset:0x30 + */ + union + { + __IO uint32_t misc1; + struct + { + __IO uint32_t hickcal_key : 8; /* [7:0] */ + __IO uint32_t reserved1 : 8; /* [15:8] */ + __IO uint32_t clkout_sel : 1; /* [16] */ + __IO uint32_t reserved2 : 3; /* [19:17] */ + __IO uint32_t clkflashsrc : 1; /* [20] */ + __IO uint32_t reserved3 : 4; /* [24:21] */ + __IO uint32_t hickdiv : 1; /* [25] */ + __IO uint32_t reserved4 : 2; /* [27:26] */ + __IO uint32_t clkoutdiv : 4; /* [31:28] */ + } misc1_bit; + }; + + /** + * @brief crm reserved2 register, offset:0x40~0x34 + */ + __IO uint32_t reserved2[4]; + + /** + * @brief crm otg_exctrl register, offset:0x44 + */ + union + { + __IO uint32_t otg_exctrl; + struct + { + __IO uint32_t reserved1 : 30; /* [29:0] */ + __IO uint32_t usbdiv_rst : 1; /* [30] */ + __IO uint32_t reserved2 : 1; /* [31] */ + } otg_exctrl_bit; + }; + + /** + * @brief crm reserved2 register, offset:0x50~0x48 + */ + __IO uint32_t reserved3[3]; + + /** + * @brief crm misc2 register, offset:0x54 + */ + union + { + __IO uint32_t misc2; + struct + { + __IO uint32_t reserved1 : 8; /* [7:0] */ + __IO uint32_t hick_to_usb : 1; /* [8] */ + __IO uint32_t hick_to_sclk : 1; /* [9] */ + __IO uint32_t reserved3 : 22;/* [31:10] */ + } misc2_bit; + }; + +} crm_type; + +/** + * @} + */ + +#define CRM ((crm_type *) CRM_BASE) + +/** @defgroup CRM_exported_functions + * @{ + */ + +void crm_reset(void); +void crm_lext_bypass(confirm_state new_state); +void crm_hext_bypass(confirm_state new_state); +flag_status crm_flag_get(uint32_t flag); +flag_status crm_interrupt_flag_get(uint32_t flag); +error_status crm_hext_stable_wait(void); +void crm_hick_clock_trimming_set(uint8_t trim_value); +void crm_hick_clock_calibration_set(uint8_t cali_value); +void crm_periph_clock_enable(crm_periph_clock_type value, confirm_state new_state); +void crm_periph_reset(crm_periph_reset_type value, confirm_state new_state); +void crm_periph_sleep_mode_clock_enable(crm_periph_clock_sleepmd_type value, confirm_state new_state); +void crm_clock_source_enable(crm_clock_source_type source, confirm_state new_state); +void crm_flag_clear(uint32_t flag); +void crm_ertc_clock_select(crm_ertc_clock_type value); +void crm_ertc_clock_enable(confirm_state new_state); +void crm_ahb_div_set(crm_ahb_div_type value); +void crm_apb1_div_set(crm_apb1_div_type value); +void crm_apb2_div_set(crm_apb2_div_type value); +void crm_adc_clock_div_set(crm_adc_div_type div_value); +void crm_usb_clock_div_set(crm_usb_div_type div_value); +void crm_clock_failure_detection_enable(confirm_state new_state); +void crm_battery_powered_domain_reset(confirm_state new_state); +void crm_pll_config(crm_pll_clock_source_type clock_source, crm_pll_mult_type mult_value); +void crm_pll_config2(crm_pll_clock_source_type clock_source, uint16_t pll_ns, uint16_t pll_ms, crm_pll_fr_type pll_fr); +void crm_sysclk_switch(crm_sclk_type value); +crm_sclk_type crm_sysclk_switch_status_get(void); +void crm_clocks_freq_get(crm_clocks_freq_type *clocks_struct); +void crm_clock_out_set(crm_clkout_select_type clkout); +void crm_interrupt_enable(uint32_t crm_int, confirm_state new_state); +void crm_hick_divider_select(crm_hick_div_6_type value); +void crm_hick_sclk_frequency_select(crm_hick_sclk_frequency_type value); +void crm_usb_clock_source_select(crm_usb_clock_source_type value); +void crm_clkout_div_set(crm_clkout_div_type clkout_div); +void crm_usb_div_reset(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_debug.h b/libraries/drivers/inc/at32f425_debug.h new file mode 100644 index 0000000..2f85317 --- /dev/null +++ b/libraries/drivers/inc/at32f425_debug.h @@ -0,0 +1,182 @@ +/** + ************************************************************************** + * @file at32f425_debug.h + * @brief at32f425 debug header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_DEBUG_H +#define __AT32F425_DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup DEBUG + * @{ + */ + +/** @defgroup DEBUG_mode_definition + * @{ + */ + +#define DEBUG_SLEEP 0x00000001 /*!< debug sleep mode */ +#define DEBUG_DEEPSLEEP 0x00000002 /*!< debug deepsleep mode */ +#define DEBUG_STANDBY 0x00000004 /*!< debug standby mode */ +#define DEBUG_CAN_PAUSE 0x00000008 /*!< debug can pause */ +#define DEBUG_WDT_PAUSE 0x00000100 /*!< debug watchdog timer pause */ +#define DEBUG_WWDT_PAUSE 0x00000200 /*!< debug window watchdog timer pause */ +#define DEBUG_TMR1_PAUSE 0x00000400 /*!< debug timer1 pause */ +#define DEBUG_TMR2_PAUSE 0x00000800 /*!< debug timer2 pause */ +#define DEBUG_TMR3_PAUSE 0x00001000 /*!< debug timer3 pause */ +#define DEBUG_ERTC_PAUSE 0x00004000 /*!< debug ertc pause */ +#define DEBUG_I2C1_SMBUS_TIMEOUT 0x00008000 /*!< debug i2c1 smbus timeout */ +#define DEBUG_I2C2_SMBUS_TIMEOUT 0x00010000 /*!< debug i2c2 smbus timeout */ +#define DEBUG_TMR6_PAUSE 0x00080000 /*!< debug timer6 pause */ +#define DEBUG_TMR7_PAUSE 0x00100000 /*!< debug timer7 pause */ +#define DEBUG_ERTC_512_PAUSE 0x00200000 /*!< debug ertc 512 pause */ +#define DEBUG_TMR15_PAUSE 0x00400000 /*!< debug timer15 pause */ +#define DEBUG_TMR16_PAUSE 0x00800000 /*!< debug timer16 pause */ +#define DEBUG_TMR17_PAUSE 0x01000000 /*!< debug timer17 pause */ +#define DEBUG_TMR13_PAUSE 0x04000000 /*!< debug timer13 pause */ +#define DEBUG_TMR14_PAUSE 0x08000000 /*!< debug timer14 pause */ + +/** + * @} + */ + +/** @defgroup DEBUG_exported_types + * @{ + */ + +/** + * @brief type define debug register all + */ +typedef struct +{ + /** + * @brief debug idcode register, offset:0x00 + */ + union + { + __IO uint32_t pid; + struct + { + __IO uint32_t pid : 32;/* [31:0] */ + } idcode_bit; + }; + + /** + * @brief debug ctrl register, offset:0x04 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t sleep_debug : 1;/* [0] */ + __IO uint32_t deepsleep_debug : 1;/* [1] */ + __IO uint32_t standby_debug : 1;/* [2] */ + __IO uint32_t can_debug : 1;/* [3] */ + __IO uint32_t reserved1 : 4;/* [7:4] */ + __IO uint32_t wdt_pause : 1;/* [8] */ + __IO uint32_t wwdt_pause : 1;/* [9] */ + __IO uint32_t tmr1_pause : 1;/* [10] */ + __IO uint32_t tmr2_pause : 1;/* [11] */ + __IO uint32_t tmr3_pause : 1;/* [12] */ + __IO uint32_t reserved2 : 1;/* [13] */ + __IO uint32_t ertc_pause : 1;/* [14] */ + __IO uint32_t i2c1_smbus_timeout : 1;/* [15] */ + __IO uint32_t i2c2_smbus_timeout : 1;/* [16] */ + __IO uint32_t reserved3 : 2;/* [18:17] */ + __IO uint32_t tmr6_pause : 1;/* [19] */ + __IO uint32_t tmr7_pause : 1;/* [20] */ + __IO uint32_t ertc_512_pause : 1;/* [21] */ + __IO uint32_t tmr15_pause : 1;/* [22] */ + __IO uint32_t tmr16_pause : 1;/* [23] */ + __IO uint32_t tmr17_pause : 1;/* [24] */ + __IO uint32_t reserved4 : 1;/* [25] */ + __IO uint32_t tmr13_pause : 1;/* [26] */ + __IO uint32_t tmr14_pause : 1;/* [27] */ + __IO uint32_t reserved5 : 4;/* [31:28] */ + } ctrl_bit; + }; + + /** + * @brief debug reserved1 register, offset:0x08~0x1C + */ + __IO uint32_t reserved1[6]; + + /** + * @brief debug ser id register, offset:0x20 + */ + union + { + __IO uint32_t ser_id; + struct + { + __IO uint32_t rev_id : 3;/* [2:0] */ + __IO uint32_t reserved1 : 5;/* [7:3] */ + __IO uint32_t ser_id : 8;/* [15:8] */ + __IO uint32_t reserved2 : 16;/* [31:16] */ + } ser_id_bit; + }; + +} debug_type; + +/** + * @} + */ + +#define DEBUGMCU ((debug_type *) DEBUG_BASE) + +/** @defgroup DEBUG_exported_functions + * @{ + */ + +uint16_t debug_device_id_get(void); +void debug_periph_mode_set(uint32_t periph_debug_mode, confirm_state new_state); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_def.h b/libraries/drivers/inc/at32f425_def.h new file mode 100644 index 0000000..03ba13d --- /dev/null +++ b/libraries/drivers/inc/at32f425_def.h @@ -0,0 +1,69 @@ +/** + ************************************************************************** + * @file at32f425_def.h + * @brief at32f425 macros header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_DEF_H +#define __AT32F425_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* gnu compiler */ +#if defined (__GNUC__) + #ifndef ALIGNED_HEAD + #define ALIGNED_HEAD + #endif + #ifndef ALIGNED_TAIL + #define ALIGNED_TAIL __attribute__ ((aligned (4))) + #endif +#endif + +/* arm compiler */ +#if defined (__CC_ARM) + #ifndef ALIGNED_HEAD + #define ALIGNED_HEAD __align(4) + #endif + #ifndef ALIGNED_TAIL + #define ALIGNED_TAIL + #endif +#endif + +/* iar compiler */ +#if defined (__ICCARM__) + #ifndef ALIGNED_HEAD + #define ALIGNED_HEAD + #endif + #ifndef ALIGNED_TAIL + #define ALIGNED_TAIL + #endif +#endif + +#define UNUSED(x) (void)x /* to avoid gcc/g++ warnings */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_dma.h b/libraries/drivers/inc/at32f425_dma.h new file mode 100644 index 0000000..b5a0328 --- /dev/null +++ b/libraries/drivers/inc/at32f425_dma.h @@ -0,0 +1,481 @@ +/** + ************************************************************************** + * @file at32f425_dma.h + * @brief at32f425 dma header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_DMA_H +#define __AT32F425_DMA_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup DMA + * @{ + */ + +/** @defgroup DMA_interrupts_definition + * @brief dma interrupt + * @{ + */ + +#define DMA_FDT_INT ((uint32_t)0x00000002) /*!< dma full data transfer interrupt */ +#define DMA_HDT_INT ((uint32_t)0x00000004) /*!< dma half data transfer interrupt */ +#define DMA_DTERR_INT ((uint32_t)0x00000008) /*!< dma errorr interrupt */ + +/** + * @} + */ + +/** @defgroup DMA_flexible_channel + * @{ + */ + +#define FLEX_CHANNEL1 ((uint8_t)0x01) /*!< dma flexible channel1 */ +#define FLEX_CHANNEL2 ((uint8_t)0x02) /*!< dma flexible channel2 */ +#define FLEX_CHANNEL3 ((uint8_t)0x03) /*!< dma flexible channel3 */ +#define FLEX_CHANNEL4 ((uint8_t)0x04) /*!< dma flexible channel4 */ +#define FLEX_CHANNEL5 ((uint8_t)0x05) /*!< dma flexible channel5 */ +#define FLEX_CHANNEL6 ((uint8_t)0x06) /*!< dma flexible channel6 */ +#define FLEX_CHANNEL7 ((uint8_t)0x07) /*!< dma flexible channel7 */ + +/** + * @} + */ + +/** @defgroup DMA_flags_definition + * @brief dma flag + * @{ + */ + +#define DMA1_GL1_FLAG ((uint32_t)0x00000001) /*!< dma1 channel1 global flag */ +#define DMA1_FDT1_FLAG ((uint32_t)0x00000002) /*!< dma1 channel1 full data transfer flag */ +#define DMA1_HDT1_FLAG ((uint32_t)0x00000004) /*!< dma1 channel1 half data transfer flag */ +#define DMA1_DTERR1_FLAG ((uint32_t)0x00000008) /*!< dma1 channel1 error flag */ +#define DMA1_GL2_FLAG ((uint32_t)0x00000010) /*!< dma1 channel2 global flag */ +#define DMA1_FDT2_FLAG ((uint32_t)0x00000020) /*!< dma1 channel2 full data transfer flag */ +#define DMA1_HDT2_FLAG ((uint32_t)0x00000040) /*!< dma1 channel2 half data transfer flag */ +#define DMA1_DTERR2_FLAG ((uint32_t)0x00000080) /*!< dma1 channel2 error flag */ +#define DMA1_GL3_FLAG ((uint32_t)0x00000100) /*!< dma1 channel3 global flag */ +#define DMA1_FDT3_FLAG ((uint32_t)0x00000200) /*!< dma1 channel3 full data transfer flag */ +#define DMA1_HDT3_FLAG ((uint32_t)0x00000400) /*!< dma1 channel3 half data transfer flag */ +#define DMA1_DTERR3_FLAG ((uint32_t)0x00000800) /*!< dma1 channel3 error flag */ +#define DMA1_GL4_FLAG ((uint32_t)0x00001000) /*!< dma1 channel4 global flag */ +#define DMA1_FDT4_FLAG ((uint32_t)0x00002000) /*!< dma1 channel4 full data transfer flag */ +#define DMA1_HDT4_FLAG ((uint32_t)0x00004000) /*!< dma1 channel4 half data transfer flag */ +#define DMA1_DTERR4_FLAG ((uint32_t)0x00008000) /*!< dma1 channel4 error flag */ +#define DMA1_GL5_FLAG ((uint32_t)0x00010000) /*!< dma1 channel5 global flag */ +#define DMA1_FDT5_FLAG ((uint32_t)0x00020000) /*!< dma1 channel5 full data transfer flag */ +#define DMA1_HDT5_FLAG ((uint32_t)0x00040000) /*!< dma1 channel5 half data transfer flag */ +#define DMA1_DTERR5_FLAG ((uint32_t)0x00080000) /*!< dma1 channel5 error flag */ +#define DMA1_GL6_FLAG ((uint32_t)0x00100000) /*!< dma1 channel6 global flag */ +#define DMA1_FDT6_FLAG ((uint32_t)0x00200000) /*!< dma1 channel6 full data transfer flag */ +#define DMA1_HDT6_FLAG ((uint32_t)0x00400000) /*!< dma1 channel6 half data transfer flag */ +#define DMA1_DTERR6_FLAG ((uint32_t)0x00800000) /*!< dma1 channel6 error flag */ +#define DMA1_GL7_FLAG ((uint32_t)0x01000000) /*!< dma1 channel7 global flag */ +#define DMA1_FDT7_FLAG ((uint32_t)0x02000000) /*!< dma1 channel7 full data transfer flag */ +#define DMA1_HDT7_FLAG ((uint32_t)0x04000000) /*!< dma1 channel7 half data transfer flag */ +#define DMA1_DTERR7_FLAG ((uint32_t)0x08000000) /*!< dma1 channel7 error flag */ + +/** + * @} + */ + +/** @defgroup DMA_exported_types + * @{ + */ + +/** + * @brief dma flexible request type + */ +typedef enum +{ + DMA_FLEXIBLE_ADC1 = 0x05, /*!< adc1 flexible request id */ + DMA_FLEXIBLE_SPI1_RX = 0x10, /*!< spi1_rx flexible request id */ + DMA_FLEXIBLE_SPI1_TX = 0x11, /*!< spi1_tx flexible request id */ + DMA_FLEXIBLE_SPI2_RX = 0x12, /*!< spi2_rx flexible request id */ + DMA_FLEXIBLE_SPI2_TX = 0x13, /*!< spi2_tx flexible request id */ + DMA_FLEXIBLE_SPI3_RX = 0x3C, /*!< spi3_rx flexible request id */ + DMA_FLEXIBLE_SPI3_TX = 0x3D, /*!< spi3_tx flexible request id */ + DMA_FLEXIBLE_UART1_RX = 0x32, /*!< usart1_rx flexible request id */ + DMA_FLEXIBLE_UART1_TX = 0x33, /*!< usart1_tx flexible request id */ + DMA_FLEXIBLE_UART2_RX = 0x34, /*!< usart2_rx flexible request id */ + DMA_FLEXIBLE_UART2_TX = 0x35, /*!< usart2_tx flexible request id */ + DMA_FLEXIBLE_UART3_RX = 0x36, /*!< usart3_rx flexible request id */ + DMA_FLEXIBLE_UART3_TX = 0x37, /*!< usart3_tx flexible request id */ + DMA_FLEXIBLE_UART4_RX = 0x38, /*!< usart4_rx flexible request id */ + DMA_FLEXIBLE_UART4_TX = 0x39, /*!< usart4_tx flexible request id */ + DMA_FLEXIBLE_I2C1_RX = 0x0A, /*!< i2c1_rx flexible request id */ + DMA_FLEXIBLE_I2C1_TX = 0x0B, /*!< i2c1_tx flexible request id */ + DMA_FLEXIBLE_I2C2_RX = 0x0C, /*!< i2c2_rx flexible request id */ + DMA_FLEXIBLE_I2C2_TX = 0x0D, /*!< i2c2_tx flexible request id */ + DMA_FLEXIBLE_TMR1_TRIG = 0x18, /*!< tmr1_trig flexible request id */ + DMA_FLEXIBLE_TMR1_HALL = 0x18, /*!< tmr1_hall flexible request id */ + DMA_FLEXIBLE_TMR1_OVERFLOW = 0x19, /*!< tmr1_overflow flexible request id */ + DMA_FLEXIBLE_TMR1_CH1 = 0x14, /*!< tmr1_ch1 flexible request id */ + DMA_FLEXIBLE_TMR1_CH2 = 0x15, /*!< tmr1_ch2 flexible request id */ + DMA_FLEXIBLE_TMR1_CH3 = 0x16, /*!< tmr1_ch3 flexible request id */ + DMA_FLEXIBLE_TMR1_CH4 = 0x17, /*!< tmr1_ch4 flexible request id */ + DMA_FLEXIBLE_TMR2_TRIG = 0x1E, /*!< tmr2_trig flexible request id */ + DMA_FLEXIBLE_TMR2_OVERFLOW = 0x1F, /*!< tmr2_overflow flexible request id */ + DMA_FLEXIBLE_TMR2_CH1 = 0x1A, /*!< tmr2_ch1 flexible request id */ + DMA_FLEXIBLE_TMR2_CH2 = 0x1B, /*!< tmr2_ch2 flexible request id */ + DMA_FLEXIBLE_TMR2_CH3 = 0x1C, /*!< tmr2_ch3 flexible request id */ + DMA_FLEXIBLE_TMR2_CH4 = 0x1D, /*!< tmr2_ch4 flexible request id */ + DMA_FLEXIBLE_TMR3_TRIG = 0x24, /*!< tmr3_trig flexible request id */ + DMA_FLEXIBLE_TMR3_OVERFLOW = 0x25, /*!< tmr3_overflow flexible request id */ + DMA_FLEXIBLE_TMR3_CH1 = 0x20, /*!< tmr3_ch1 flexible request id */ + DMA_FLEXIBLE_TMR3_CH2 = 0x21, /*!< tmr3_ch2 flexible request id */ + DMA_FLEXIBLE_TMR3_CH3 = 0x22, /*!< tmr3_ch3 flexible request id */ + DMA_FLEXIBLE_TMR3_CH4 = 0x23, /*!< tmr3_ch4 flexible request id */ + DMA_FLEXIBLE_TMR6_OVERFLOW = 0x26, /*!< tmr6_overflow flexible request id */ + DMA_FLEXIBLE_TMR7_OVERFLOW = 0x27, /*!< tmr7_overflow flexible request id */ + DMA_FLEXIBLE_TMR15_TRIG = 0x2A, /*!< tmr15_trig flexible request id */ + DMA_FLEXIBLE_TMR15_HALL = 0x2A, /*!< tmr15_hall flexible request id */ + DMA_FLEXIBLE_TMR15_OVERFLOW = 0x2B, /*!< tmr15_overflow flexible request id */ + DMA_FLEXIBLE_TMR15_CH1 = 0x28, /*!< tmr15_ch1 flexible request id */ + DMA_FLEXIBLE_TMR15_CH2 = 0x29, /*!< tmr15_ch2 flexible request id */ + DMA_FLEXIBLE_TMR16_OVERFLOW = 0x2E, /*!< tmr16_overflow flexible request id */ + DMA_FLEXIBLE_TMR16_CH1 = 0x2C, /*!< tmr16_ch1 flexible request id */ + DMA_FLEXIBLE_TMR17_OVERFLOW = 0x31, /*!< tmr17_overflow flexible request id */ + DMA_FLEXIBLE_TMR17_CH1 = 0x2F, /*!< tmr17_ch1 flexible request id */ +} dma_flexible_request_type; + +/** + * @brief dma direction type + */ +typedef enum +{ + DMA_DIR_PERIPHERAL_TO_MEMORY = 0x0000, /*!< dma data transfer direction:peripheral to memory */ + DMA_DIR_MEMORY_TO_PERIPHERAL = 0x0010, /*!< dma data transfer direction:memory to peripheral */ + DMA_DIR_MEMORY_TO_MEMORY = 0x4000 /*!< dma data transfer direction:memory to memory */ +} dma_dir_type; + +/** + * @brief dma peripheral incremented type + */ +typedef enum +{ + DMA_PERIPHERAL_INC_DISABLE = 0x00, /*!< dma peripheral increment mode disable */ + DMA_PERIPHERAL_INC_ENABLE = 0x01 /*!< dma peripheral increment mode enable */ +} dma_peripheral_inc_type; + +/** + * @brief dma memory incremented type + */ +typedef enum +{ + DMA_MEMORY_INC_DISABLE = 0x00, /*!< dma memory increment mode disable */ + DMA_MEMORY_INC_ENABLE = 0x01 /*!< dma memory increment mode enable */ +} dma_memory_inc_type; + +/** + * @brief dma peripheral data size type + */ +typedef enum +{ + DMA_PERIPHERAL_DATA_WIDTH_BYTE = 0x00, /*!< dma peripheral databus width 8bit */ + DMA_PERIPHERAL_DATA_WIDTH_HALFWORD = 0x01, /*!< dma peripheral databus width 16bit */ + DMA_PERIPHERAL_DATA_WIDTH_WORD = 0x02 /*!< dma peripheral databus width 32bit */ +} dma_peripheral_data_size_type; + +/** + * @brief dma memory data size type + */ +typedef enum +{ + DMA_MEMORY_DATA_WIDTH_BYTE = 0x00, /*!< dma memory databus width 8bit */ + DMA_MEMORY_DATA_WIDTH_HALFWORD = 0x01, /*!< dma memory databus width 16bit */ + DMA_MEMORY_DATA_WIDTH_WORD = 0x02 /*!< dma memory databus width 32bit */ +} dma_memory_data_size_type; + +/** + * @brief dma priority level type + */ +typedef enum +{ + DMA_PRIORITY_LOW = 0x00, /*!< dma channel priority: low */ + DMA_PRIORITY_MEDIUM = 0x01, /*!< dma channel priority: mediue */ + DMA_PRIORITY_HIGH = 0x02, /*!< dma channel priority: high */ + DMA_PRIORITY_VERY_HIGH = 0x03 /*!< dma channel priority: very high */ +} dma_priority_level_type; + +/** + * @brief dma init type + */ +typedef struct +{ + uint32_t peripheral_base_addr; /*!< base addrress for peripheral */ + uint32_t memory_base_addr; /*!< base addrress for memory */ + dma_dir_type direction; /*!< dma transmit direction, peripheral as source or as destnation */ + uint16_t buffer_size; /*!< counter to transfer */ + confirm_state peripheral_inc_enable; /*!< periphera address increment after one transmit */ + confirm_state memory_inc_enable; /*!< memory address increment after one transmit */ + dma_peripheral_data_size_type peripheral_data_width; /*!< peripheral data width for transmit */ + dma_memory_data_size_type memory_data_width; /*!< memory data width for transmit */ + confirm_state loop_mode_enable; /*!< when circular mode enable, buffer size will reload if count to 0 */ + dma_priority_level_type priority; /*!< dma priority can choose from very high, high, dedium or low */ +} dma_init_type; + +/** + * @brief type define dma register + */ +typedef struct +{ + /** + * @brief dma sts register, offset:0x00 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t gf1 : 1; /* [0] */ + __IO uint32_t fdtf1 : 1; /* [1] */ + __IO uint32_t hdtf1 : 1; /* [2] */ + __IO uint32_t dterrf1 : 1; /* [3] */ + __IO uint32_t gf2 : 1; /* [4] */ + __IO uint32_t fdtf2 : 1; /* [5] */ + __IO uint32_t hdtf2 : 1; /* [6] */ + __IO uint32_t dterrf2 : 1; /* [7] */ + __IO uint32_t gf3 : 1; /* [8] */ + __IO uint32_t fdtf3 : 1; /* [9] */ + __IO uint32_t hdtf3 : 1; /* [10] */ + __IO uint32_t dterrf3 : 1; /* [11] */ + __IO uint32_t gf4 : 1; /* [12] */ + __IO uint32_t fdtf4 : 1; /* [13] */ + __IO uint32_t hdtf4 : 1; /* [14] */ + __IO uint32_t dterrf4 : 1; /* [15] */ + __IO uint32_t gf5 : 1; /* [16] */ + __IO uint32_t fdtf5 : 1; /* [17] */ + __IO uint32_t hdtf5 : 1; /* [18] */ + __IO uint32_t dterrf5 : 1; /* [19] */ + __IO uint32_t gf6 : 1; /* [20] */ + __IO uint32_t fdtf6 : 1; /* [21] */ + __IO uint32_t hdtf6 : 1; /* [22] */ + __IO uint32_t dterrf6 : 1; /* [23] */ + __IO uint32_t gf7 : 1; /* [24] */ + __IO uint32_t fdtf7 : 1; /* [25] */ + __IO uint32_t hdtf7 : 1; /* [26] */ + __IO uint32_t dterrf7 : 1; /* [27] */ + __IO uint32_t reserved1 : 4; /* [31:28] */ + } sts_bit; + }; + + /** + * @brief dma clr register, offset:0x04 + */ + union + { + __IO uint32_t clr; + struct + { + __IO uint32_t gfc1 : 1; /* [0] */ + __IO uint32_t fdtfc1 : 1; /* [1] */ + __IO uint32_t hdtfc1 : 1; /* [2] */ + __IO uint32_t dterrfc1 : 1; /* [3] */ + __IO uint32_t gfc2 : 1; /* [4] */ + __IO uint32_t fdtfc2 : 1; /* [5] */ + __IO uint32_t hdtfc2 : 1; /* [6] */ + __IO uint32_t dterrfc2 : 1; /* [7] */ + __IO uint32_t gfc3 : 1; /* [8] */ + __IO uint32_t fdtfc3 : 1; /* [9] */ + __IO uint32_t hdtfc3 : 1; /* [10] */ + __IO uint32_t dterrfc3 : 1; /* [11] */ + __IO uint32_t gfc4 : 1; /* [12] */ + __IO uint32_t fdtfc4 : 1; /* [13] */ + __IO uint32_t hdtfc4 : 1; /* [14] */ + __IO uint32_t dterrfc4 : 1; /* [15] */ + __IO uint32_t gfc5 : 1; /* [16] */ + __IO uint32_t fdtfc5 : 1; /* [17] */ + __IO uint32_t hdtfc5 : 1; /* [18] */ + __IO uint32_t dterrfc5 : 1; /* [19] */ + __IO uint32_t gfc6 : 1; /* [20] */ + __IO uint32_t fdtfc6 : 1; /* [21] */ + __IO uint32_t hdtfc6 : 1; /* [22] */ + __IO uint32_t dterrfc6 : 1; /* [23] */ + __IO uint32_t gfc7 : 1; /* [24] */ + __IO uint32_t fdtfc7 : 1; /* [25] */ + __IO uint32_t hdtfc7 : 1; /* [26] */ + __IO uint32_t dterrfc7 : 1; /* [27] */ + __IO uint32_t reserved1 : 4; /* [31:28] */ + } clr_bit; + }; + /** + * @brief reserved, offset:0x08~0x9C + */ + __IO uint32_t reserved1[38]; + /** + * @brief dma src_sel0 register, offset:0xA0 + */ + union + { + __IO uint32_t src_sel0; + struct + { + __IO uint32_t ch1_src : 8; /* [7:0] */ + __IO uint32_t ch2_src : 8; /* [15:8] */ + __IO uint32_t ch3_src : 8; /* [23:16] */ + __IO uint32_t ch4_src : 8; /* [31:24] */ + } src_sel0_bit; + }; + + /** + * @brief dma src_sel1 register, offset:0xA4 + */ + union + { + __IO uint32_t src_sel1; + struct + { + __IO uint32_t ch5_src : 8; /* [7:0] */ + __IO uint32_t ch6_src : 8; /* [15:8] */ + __IO uint32_t ch7_src : 8; /* [23:16] */ + __IO uint32_t dma_flex_en : 1; /* [24] */ + __IO uint32_t reserved1 : 7; /* [31:25] */ + } src_sel1_bit; + }; +} dma_type; + +/** + * @brief type define dma channel register all + */ +typedef struct +{ + /** + * @brief dma ctrl register, offset:0x08+20*(x-1) x=1...7 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t chen : 1; /* [0] */ + __IO uint32_t fdtien : 1; /* [1] */ + __IO uint32_t hdtien : 1; /* [2] */ + __IO uint32_t dterrien : 1; /* [3] */ + __IO uint32_t dtd : 1; /* [4] */ + __IO uint32_t lm : 1; /* [5] */ + __IO uint32_t pincm : 1; /* [6] */ + __IO uint32_t mincm : 1; /* [7] */ + __IO uint32_t pwidth : 2; /* [9:8] */ + __IO uint32_t mwidth : 2; /* [11:10] */ + __IO uint32_t chpl : 2; /* [13:12] */ + __IO uint32_t m2m : 1; /* [14] */ + __IO uint32_t reserved1 : 17;/* [31:15] */ + } ctrl_bit; + }; + + /** + * @brief dma dtcnt register, offset:0x0C+20*(x-1) x=1...7 + */ + union + { + __IO uint32_t dtcnt; + struct + { + __IO uint32_t cnt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } dtcnt_bit; + }; + + /** + * @brief dma cpba register, offset:0x10+20*(x-1) x=1...7 + */ + union + { + __IO uint32_t paddr; + struct + { + __IO uint32_t paddr : 32;/* [31:0] */ + } paddr_bit; + }; + + /** + * @brief dma cmba register, offset:0x14+20*(x-1) x=1...7 + */ + union + { + __IO uint32_t maddr; + struct + { + __IO uint32_t maddr : 32;/* [31:0] */ + } maddr_bit; + }; +} dma_channel_type; + +/** + * @} + */ + +#define DMA1 ((dma_type *) DMA1_BASE) +#define DMA1_CHANNEL1 ((dma_channel_type *) DMA1_CHANNEL1_BASE) +#define DMA1_CHANNEL2 ((dma_channel_type *) DMA1_CHANNEL2_BASE) +#define DMA1_CHANNEL3 ((dma_channel_type *) DMA1_CHANNEL3_BASE) +#define DMA1_CHANNEL4 ((dma_channel_type *) DMA1_CHANNEL4_BASE) +#define DMA1_CHANNEL5 ((dma_channel_type *) DMA1_CHANNEL5_BASE) +#define DMA1_CHANNEL6 ((dma_channel_type *) DMA1_CHANNEL6_BASE) +#define DMA1_CHANNEL7 ((dma_channel_type *) DMA1_CHANNEL7_BASE) + + +/** @defgroup DMA_exported_functions + * @{ + */ + +void dma_reset(dma_channel_type* dmax_channely); +void dma_data_number_set(dma_channel_type* dmax_channely, uint16_t data_number); +uint16_t dma_data_number_get(dma_channel_type* dmax_channely); +void dma_interrupt_enable(dma_channel_type* dmax_channely, uint32_t dma_int, confirm_state new_state); +void dma_channel_enable(dma_channel_type* dmax_channely, confirm_state new_state); +void dma_flexible_config(dma_type* dma_x, uint8_t flex_channelx, dma_flexible_request_type flexible_request); +flag_status dma_flag_get(uint32_t dmax_flag); +flag_status dma_interrupt_flag_get(uint32_t dmax_flag); +void dma_flag_clear(uint32_t dmax_flag); +void dma_default_para_init(dma_init_type* dma_init_struct); +void dma_init(dma_channel_type* dmax_channely, dma_init_type* dma_init_struct); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_ertc.h b/libraries/drivers/inc/at32f425_ertc.h new file mode 100644 index 0000000..2f148f6 --- /dev/null +++ b/libraries/drivers/inc/at32f425_ertc.h @@ -0,0 +1,943 @@ +/** + ************************************************************************** + * @file at32f425_ertc.h + * @brief at32f425 ertc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_ERTC_H +#define __AT32F425_ERTC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup ERTC + * @{ + */ + +/** @defgroup ERTC_interrupts_definition + * @brief ertc interrupt + * @{ + */ + +#define ERTC_TP_INT ((uint32_t)0x00000004) /*!< ertc tamper interrupt */ +#define ERTC_ALA_INT ((uint32_t)0x00001000) /*!< ertc alarm a interrupt */ +#define ERTC_WAT_INT ((uint32_t)0x00004000) /*!< ertc wakeup timer interrupt */ +#define ERTC_TS_INT ((uint32_t)0x00008000) /*!< ertc timestamp interrupt */ + +/** + * @} + */ + +/** @defgroup ERTC_flags_definition + * @brief ertc flag + * @{ + */ + +#define ERTC_ALAWF_FLAG ((uint32_t)0x00000001) /*!< ertc alarm a register allows write flag */ +#define ERTC_WATWF_FLAG ((uint32_t)0x00000004) /*!< ertc wakeup timer register allows write flag */ +#define ERTC_TADJF_FLAG ((uint32_t)0x00000008) /*!< ertc time adjustment flag */ +#define ERTC_INITF_FLAG ((uint32_t)0x00000010) /*!< ertc calendar initialization flag */ +#define ERTC_UPDF_FLAG ((uint32_t)0x00000020) /*!< ertc calendar update flag */ +#define ERTC_IMF_FLAG ((uint32_t)0x00000040) /*!< ertc enter initialization mode flag */ +#define ERTC_ALAF_FLAG ((uint32_t)0x00000100) /*!< ertc alarm clock a flag */ +#define ERTC_WATF_FLAG ((uint32_t)0x00000400) /*!< ertc wakeup timer flag */ +#define ERTC_TSF_FLAG ((uint32_t)0x00000800) /*!< ertc timestamp flag */ +#define ERTC_TSOF_FLAG ((uint32_t)0x00001000) /*!< ertc timestamp overflow flag */ +#define ERTC_TP1F_FLAG ((uint32_t)0x00002000) /*!< ertc tamper detection 1 flag */ +#define ERTC_CALUPDF_FLAG ((uint32_t)0x00010000) /*!< ertc calibration value update completed flag */ + +/** + * @brief ertc alarm mask + */ +#define ERTC_ALARM_MASK_NONE ((uint32_t)0x00000000) /*!< ertc alarm match all */ +#define ERTC_ALARM_MASK_SEC ((uint32_t)0x00000080) /*!< ertc alarm don't match seconds */ +#define ERTC_ALARM_MASK_MIN ((uint32_t)0x00008000) /*!< ertc alarm don't match minute */ +#define ERTC_ALARM_MASK_HOUR ((uint32_t)0x00800000) /*!< ertc alarm don't match hour */ +#define ERTC_ALARM_MASK_DATE_WEEK ((uint32_t)0x80000000) /*!< ertc alarm don't match date or week */ +#define ERTC_ALARM_MASK_ALL ((uint32_t)0x80808080) /*!< ertc alarm don't match all */ + +/** + * @brief compatible with older versions + */ +#define ERTC_WAT_CLK_CK_A_16BITS ERTC_WAT_CLK_CK_B_16BITS +#define ERTC_WAT_CLK_CK_A_17BITS ERTC_WAT_CLK_CK_B_17BITS + +/** + * @} + */ + +/** @defgroup ERTC_exported_types + * @{ + */ + +/** + * @brief ertc hour mode + */ +typedef enum +{ + ERTC_HOUR_MODE_24 = 0x00, /*!< 24-hour format */ + ERTC_HOUR_MODE_12 = 0x01 /*!< 12-hour format */ +} ertc_hour_mode_set_type; + +/** + * @brief ertc 12-hour format am/pm + */ +typedef enum +{ + ERTC_24H = 0x00, /*!< 24-hour format */ + ERTC_AM = 0x00, /*!< 12-hour format, ante meridiem */ + ERTC_PM = 0x01 /*!< 12-hour format, meridiem */ +} ertc_am_pm_type; + +/** + * @brief ertc week or date select + */ +typedef enum +{ + ERTC_SLECT_DATE = 0x00, /*!< slect date mode */ + ERTC_SLECT_WEEK = 0x01 /*!< slect week mode */ +} ertc_week_date_select_type; + +/** + * @brief ertc alarm x select + */ +typedef enum +{ + ERTC_ALA = 0x00, /*!< select alarm a */ +} ertc_alarm_type; + +/** + * @brief ertc alarm sub second mask + */ +typedef enum +{ + ERTC_ALARM_SBS_MASK_ALL = 0x00, /*!< do not match the sub-second */ + ERTC_ALARM_SBS_MASK_14_1 = 0x01, /*!< only compare bit [0] */ + ERTC_ALARM_SBS_MASK_14_2 = 0x02, /*!< only compare bit [1:0] */ + ERTC_ALARM_SBS_MASK_14_3 = 0x03, /*!< only compare bit [2:0] */ + ERTC_ALARM_SBS_MASK_14_4 = 0x04, /*!< only compare bit [3:0] */ + ERTC_ALARM_SBS_MASK_14_5 = 0x05, /*!< only compare bit [4:0] */ + ERTC_ALARM_SBS_MASK_14_6 = 0x06, /*!< only compare bit [5:0] */ + ERTC_ALARM_SBS_MASK_14_7 = 0x07, /*!< only compare bit [6:0] */ + ERTC_ALARM_SBS_MASK_14_8 = 0x08, /*!< only compare bit [7:0] */ + ERTC_ALARM_SBS_MASK_14_9 = 0x09, /*!< only compare bit [8:0] */ + ERTC_ALARM_SBS_MASK_14_10 = 0x0A, /*!< only compare bit [9:0] */ + ERTC_ALARM_SBS_MASK_14_11 = 0x0B, /*!< only compare bit [10:0] */ + ERTC_ALARM_SBS_MASK_14_12 = 0x0C, /*!< only compare bit [11:0] */ + ERTC_ALARM_SBS_MASK_14_13 = 0x0D, /*!< only compare bit [12:0] */ + ERTC_ALARM_SBS_MASK_14 = 0x0E, /*!< only compare bit [13:0] */ + ERTC_ALARM_SBS_MASK_NONE = 0x0F /*!< compare bit [14:0] */ +} ertc_alarm_sbs_mask_type; + +/** + * @brief ertc wakeup timer clock select + */ +typedef enum +{ + ERTC_WAT_CLK_ERTCCLK_DIV16 = 0x00, /*!< the wake up timer clock is ERTC_CLK / 16 */ + ERTC_WAT_CLK_ERTCCLK_DIV8 = 0x01, /*!< the wake up timer clock is ERTC_CLK / 8 */ + ERTC_WAT_CLK_ERTCCLK_DIV4 = 0x02, /*!< the wake up timer clock is ERTC_CLK / 4 */ + ERTC_WAT_CLK_ERTCCLK_DIV2 = 0x03, /*!< the wake up timer clock is ERTC_CLK / 2 */ + ERTC_WAT_CLK_CK_B_16BITS = 0x04, /*!< the wake up timer clock is CK_B, wakeup counter = ERTC_WAT */ + ERTC_WAT_CLK_CK_B_17BITS = 0x06 /*!< the wake up timer clock is CK_B, wakeup counter = ERTC_WAT + 65535 */ +} ertc_wakeup_clock_type; + +/** + * @brief ertc smooth calibration period + */ +typedef enum +{ + ERTC_SMOOTH_CAL_PERIOD_32 = 0x00, /*!< 32 second calibration period */ + ERTC_SMOOTH_CAL_PERIOD_16 = 0x01, /*!< 16 second calibration period */ + ERTC_SMOOTH_CAL_PERIOD_8 = 0x02 /*!< 8 second calibration period */ +} ertc_smooth_cal_period_type; + +/** + * @brief ertc smooth calibration clock add mode + */ +typedef enum +{ + ERTC_SMOOTH_CAL_CLK_ADD_0 = 0x00, /*!< do not increase clock */ + ERTC_SMOOTH_CAL_CLK_ADD_512 = 0x01 /*!< add 512 clocks */ +} ertc_smooth_cal_clk_add_type; + +/** + * @brief ertc calibration output mode + */ +typedef enum +{ + ERTC_CAL_OUTPUT_512HZ = 0x00, /*!< output 512 hz */ + ERTC_CAL_OUTPUT_1HZ = 0x01 /*!< output 1 hz */ +} ertc_cal_output_select_type; + +/** + * @brief time adjust add mode + */ +typedef enum +{ + ERTC_TIME_ADD_NONE = 0x00, /*!< none operation */ + ERTC_TIME_ADD_1S = 0x01 /*!< add 1 second */ +} ertc_time_adjust_type; + +/** + * @brief ertc daylight saving time hour adjustment mode + */ +typedef enum +{ + ERTC_DST_ADD_1H = 0x00, /*!< add 1 hour */ + ERTC_DST_DEC_1H = 0x01 /*!< dec 1 hour */ +} ertc_dst_operation_type; + +/** + * @brief ertc daylight saving time store operation mode + */ +typedef enum +{ + ERTC_DST_SAVE_0 = 0x00, /*!< set the bpr register value to 0 */ + ERTC_DST_SAVE_1 = 0x01 /*!< set the bpr register value to 1 */ +} ertc_dst_save_type; + +/** + * @brief output source + */ +typedef enum +{ + ERTC_OUTPUT_DISABLE = 0x00, /*!< diable output */ + ERTC_OUTPUT_ALARM_A = 0x01, /*!< output alarm a event */ + ERTC_OUTPUT_WAKEUP = 0x03 /*!< output wakeup event */ +} ertc_output_source_type; + +/** + * @brief output polarity + */ +typedef enum +{ + ERTC_OUTPUT_POLARITY_HIGH = 0x00, /*!< when the event occurs, the output is high */ + ERTC_OUTPUT_POLARITY_LOW = 0x01 /*!< when the event occurs, the output is low */ +} ertc_output_polarity_type; + +/** + * @brief output type + */ +typedef enum +{ + ERTC_OUTPUT_TYPE_OPEN_DRAIN = 0x00, /*!< open drain output */ + ERTC_OUTPUT_TYPE_PUSH_PULL = 0x01 /*!< push pull output */ +} ertc_output_type; + +/** + * @brief ertc timestamp valid edge + */ +typedef enum +{ + ERTC_TIMESTAMP_EDGE_RISING = 0x00, /*!< rising edge trigger */ + ERTC_TIMESTAMP_EDGE_FALLING = 0x01 /*!< falling edge trigger */ +} ertc_timestamp_valid_edge_type; + +/** + * @brief ertc tamper x select + */ +typedef enum +{ + ERTC_TAMPER_1 = 0x00, /*!< tamper 1 */ +} ertc_tamper_select_type; + +/** + * @brief tamper detection pre-charge time + */ +typedef enum +{ + ERTC_TAMPER_PR_1_ERTCCLK = 0x00, /*!< pre-charge time is 1 ERTC_CLK */ + ERTC_TAMPER_PR_2_ERTCCLK = 0x01, /*!< pre-charge time is 2 ERTC_CLK */ + ERTC_TAMPER_PR_4_ERTCCLK = 0x02, /*!< pre-charge time is 4 ERTC_CLK */ + ERTC_TAMPER_PR_8_ERTCCLK = 0x03 /*!< pre-charge time is 8 ERTC_CLK */ +} ertc_tamper_precharge_type; + +/** + * @brief ertc tamper filter + */ +typedef enum +{ + ERTC_TAMPER_FILTER_DISABLE = 0x00, /*!< disable filter function */ + ERTC_TAMPER_FILTER_2 = 0x01, /*!< 2 consecutive samples arw valid, effective tamper event */ + ERTC_TAMPER_FILTER_4 = 0x02, /*!< 4 consecutive samples arw valid, effective tamper event */ + ERTC_TAMPER_FILTER_8 = 0x03 /*!< 8 consecutive samples arw valid, effective tamper event */ +} ertc_tamper_filter_type; + +/** + * @brief ertc tamper detection frequency + */ +typedef enum +{ + ERTC_TAMPER_FREQ_DIV_32768 = 0x00, /*!< ERTC_CLK / 32768 */ + ERTC_TAMPER_FREQ_DIV_16384 = 0x01, /*!< ERTC_CLK / 16384 */ + ERTC_TAMPER_FREQ_DIV_8192 = 0x02, /*!< ERTC_CLK / 8192 */ + ERTC_TAMPER_FREQ_DIV_4096 = 0x03, /*!< ERTC_CLK / 4096 */ + ERTC_TAMPER_FREQ_DIV_2048 = 0x04, /*!< ERTC_CLK / 2048 */ + ERTC_TAMPER_FREQ_DIV_1024 = 0x05, /*!< ERTC_CLK / 1024 */ + ERTC_TAMPER_FREQ_DIV_512 = 0x06, /*!< ERTC_CLK / 512 */ + ERTC_TAMPER_FREQ_DIV_256 = 0x07 /*!< ERTC_CLK / 256 */ +} ertc_tamper_detect_freq_type; + +/** + * @brief ertc tamper valid edge + */ +typedef enum +{ + ERTC_TAMPER_EDGE_RISING = 0x00, /*!< rising gedge */ + ERTC_TAMPER_EDGE_FALLING = 0x01, /*!< falling gedge */ + ERTC_TAMPER_EDGE_LOW = 0x00, /*!< low level */ + ERTC_TAMPER_EDGE_HIGH = 0x01 /*!< high level */ +} ertc_tamper_valid_edge_type; + +/** + * @brief ertc bpr register + */ +typedef enum +{ + ERTC_DT1 = 0, /*!< bpr data register 0 */ + ERTC_DT2 = 1, /*!< bpr data register 1 */ + ERTC_DT3 = 2, /*!< bpr data register 2 */ + ERTC_DT4 = 3, /*!< bpr data register 3 */ + ERTC_DT5 = 4, /*!< bpr data register 4 */ +} ertc_dt_type; + +/** + * @brief ertc time + */ +typedef struct +{ + uint8_t year; /*!< year */ + uint8_t month; /*!< month */ + uint8_t day; /*!< date */ + uint8_t hour; /*!< hour */ + uint8_t min; /*!< minute */ + uint8_t sec; /*!< second */ + uint8_t week; /*!< week */ + ertc_am_pm_type ampm; /*!< ante meridiem / post meridiem */ +} ertc_time_type; + +/** + * @brief ertc alarm + */ +typedef struct +{ + uint8_t day; /*!< date */ + uint8_t hour; /*!< hour */ + uint8_t min; /*!< minute */ + uint8_t sec; /*!< second */ + ertc_am_pm_type ampm; /*!< ante meridiem / post meridiem */ + uint32_t mask; /*!< alarm mask*/ + uint8_t week_date_sel; /*!< week or date mode */ + uint8_t week; /*!< week */ +} ertc_alarm_value_type; + +/** + * @brief ertc time reg union + */ +typedef union +{ + __IO uint32_t time; + struct + { + __IO uint32_t s : 7; /* [6:0] */ + __IO uint32_t reserved1 : 1; /* [7] */ + __IO uint32_t m : 7; /* [14:8] */ + __IO uint32_t reserved2 : 1; /* [15] */ + __IO uint32_t h : 6; /* [21:16] */ + __IO uint32_t ampm : 1; /* [22] */ + __IO uint32_t reserved3 : 9; /* [31:23] */ + } time_bit; +} ertc_reg_time_type; + +/** + * @brief ertc date reg union + */ +typedef union +{ + __IO uint32_t date; + struct + { + __IO uint32_t d :6; /* [5:0] */ + __IO uint32_t reserved1 :2; /* [7:6] */ + __IO uint32_t m :5; /* [12:8] */ + __IO uint32_t wk :3; /* [15:13] */ + __IO uint32_t y :8; /* [23:16] */ + __IO uint32_t reserved2 :8; /* [31:24] */ + } date_bit; +} ertc_reg_date_type; + +/** + * @brief ertc alarm reg union + */ +typedef union +{ + __IO uint32_t ala; + struct + { + __IO uint32_t s :7; /* [6:0] */ + __IO uint32_t mask1 :1; /* [7] */ + __IO uint32_t m :7; /* [14:8] */ + __IO uint32_t mask2 :1; /* [15] */ + __IO uint32_t h :6; /* [21:16] */ + __IO uint32_t ampm :1; /* [22] */ + __IO uint32_t mask3 :1; /* [23] */ + __IO uint32_t d :6; /* [29:24] */ + __IO uint32_t wksel :1; /* [30] */ + __IO uint32_t mask4 :1; /* [31] */ + } ala_bit; +} ertc_reg_alarm_type; + +/** + * @brief ertc scal reg union + */ +typedef union +{ + __IO uint32_t scal; + struct + { + __IO uint32_t dec :9; /* [8:0] */ + __IO uint32_t reserved1 :4; /* [12:9] */ + __IO uint32_t cal16 :1; /* [13] */ + __IO uint32_t cal8 :1; /* [14] */ + __IO uint32_t add :1; /* [15] */ + __IO uint32_t reserved2 :16;/* [31:16] */ + } scal_bit; +} ertc_reg_scal_type; + +/** + * @brief ertc tadj reg union + */ +typedef union +{ + __IO uint32_t tadj; + struct + { + __IO uint32_t decsbs :15;/* [14:0] */ + __IO uint32_t reserved1 :16;/* [30:15] */ + __IO uint32_t add1s :1; /* [31] */ + } tadj_bit; +} ertc_reg_tadj_type; + +/** + * @brief ertc tstm reg union + */ +typedef union +{ + __IO uint32_t tstm; + struct + { + __IO uint32_t s :7; /* [6:0] */ + __IO uint32_t reserved1 :1; /* [7] */ + __IO uint32_t m :7; /* [14:8] */ + __IO uint32_t reserved2 :1; /* [15] */ + __IO uint32_t h :6; /* [21:16] */ + __IO uint32_t ampm :1; /* [22] */ + __IO uint32_t reserved3 :9; /* [31:23] */ + } tstm_bit; +} ertc_reg_tstm_type; + +/** + * @brief ertc tsdt register, offset:0x34 + */ +typedef union +{ + __IO uint32_t tsdt; + struct + { + __IO uint32_t d :6; /* [5:0] */ + __IO uint32_t reserved1 :2; /* [7:6] */ + __IO uint32_t m :5; /* [12:8] */ + __IO uint32_t wk :3; /* [15:13] */ + __IO uint32_t reserved2 :16;/* [31:16] */ + } tsdt_bit; +} ertc_reg_tsdt_type; + +/** + * @brief type define ertc register all + */ +typedef struct +{ + + /** + * @brief ertc time register, offset:0x00 + */ + union + { + __IO uint32_t time; + struct + { + __IO uint32_t s : 7; /* [6:0] */ + __IO uint32_t reserved1 : 1; /* [7] */ + __IO uint32_t m : 7; /* [14:8] */ + __IO uint32_t reserved2 : 1; /* [15] */ + __IO uint32_t h : 6; /* [21:16] */ + __IO uint32_t ampm : 1; /* [22] */ + __IO uint32_t reserved3 : 9; /* [31:23] */ + } time_bit; + }; + + /** + * @brief ertc date register, offset:0x04 + */ + union + { + __IO uint32_t date; + struct + { + __IO uint32_t d :6; /* [5:0] */ + __IO uint32_t reserved1 :2; /* [7:6] */ + __IO uint32_t m :5; /* [12:8] */ + __IO uint32_t wk :3; /* [15:13] */ + __IO uint32_t y :8; /* [23:16] */ + __IO uint32_t reserved2 :8; /* [31:24] */ + } date_bit; + }; + + /** + * @brief ertc ctrl register, offset:0x08 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t watclk :3; /* [2:0] */ + __IO uint32_t tsedg :1; /* [3] */ + __IO uint32_t rcden :1; /* [4] */ + __IO uint32_t dren :1; /* [5] */ + __IO uint32_t hm :1; /* [6] */ + __IO uint32_t reserved1 :1; /* [7] */ + __IO uint32_t alaen :1; /* [8] */ + __IO uint32_t reserved2 :1; /* [9] */ + __IO uint32_t waten :1; /* [10] */ + __IO uint32_t tsen :1; /* [11] */ + __IO uint32_t alaien :1; /* [12] */ + __IO uint32_t reserved3 :1; /* [13] */ + __IO uint32_t watien :1; /* [14] */ + __IO uint32_t tsien :1; /* [15] */ + __IO uint32_t add1h :1; /* [16] */ + __IO uint32_t dec1h :1; /* [17] */ + __IO uint32_t bpr :1; /* [18] */ + __IO uint32_t calosel :1; /* [19] */ + __IO uint32_t outp :1; /* [20] */ + __IO uint32_t outsel :2; /* [22:21] */ + __IO uint32_t caloen :1; /* [23] */ + __IO uint32_t reserved4 :8; /* [31:24] */ + } ctrl_bit; + }; + + /** + * @brief ertc sts register, offset:0x0C + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t alawf :1; /* [0] */ + __IO uint32_t reserved1 :1; /* [1] */ + __IO uint32_t watwf :1; /* [2] */ + __IO uint32_t tadjf :1; /* [3] */ + __IO uint32_t initf :1; /* [4] */ + __IO uint32_t updf :1; /* [5] */ + __IO uint32_t imf :1; /* [6] */ + __IO uint32_t imen :1; /* [7] */ + __IO uint32_t alaf :1; /* [8] */ + __IO uint32_t reserved2 :1; /* [9] */ + __IO uint32_t watf :1; /* [10] */ + __IO uint32_t tsf :1; /* [11] */ + __IO uint32_t tsof :1; /* [12] */ + __IO uint32_t tp1f :1; /* [13] */ + __IO uint32_t reserved3 :1; /* [14] */ + __IO uint32_t reserved4 :1; /* [15] */ + __IO uint32_t calupdf :1; /* [16] */ + __IO uint32_t reserved5 :15;/* [31:17] */ + } sts_bit; + }; + + /** + * @brief ertc div register, offset:0x10 + */ + union + { + __IO uint32_t div; + struct + { + __IO uint32_t divb :15;/* [14:0] */ + __IO uint32_t reserved1 :1; /* [15] */ + __IO uint32_t diva :7; /* [22:16] */ + __IO uint32_t reserved2 :9; /* [31:23] */ + } div_bit; + }; + + /** + * @brief ertc wat register, offset:0x14 + */ + union + { + __IO uint32_t wat; + struct + { + __IO uint32_t val :16;/* [15:0] */ + __IO uint32_t reserved1 :16;/* [31:16] */ + } wat_bit; + }; + + /** + * @brief ertc reserved register, offset:0x18 + */ + __IO uint32_t reserved1; + + /** + * @brief ertc ala register, offset:0x1C + */ + union + { + __IO uint32_t ala; + struct + { + __IO uint32_t s :7; /* [6:0] */ + __IO uint32_t mask1 :1; /* [7] */ + __IO uint32_t m :7; /* [14:8] */ + __IO uint32_t mask2 :1; /* [15] */ + __IO uint32_t h :6; /* [21:16] */ + __IO uint32_t ampm :1; /* [22] */ + __IO uint32_t mask3 :1; /* [23] */ + __IO uint32_t d :6; /* [29:24] */ + __IO uint32_t wksel :1; /* [30] */ + __IO uint32_t mask4 :1; /* [31] */ + } ala_bit; + }; + + /** + * @brief ertc reserved register, offset:0x20 + */ + __IO uint32_t reserved2; + + /** + * @brief ertc wp register, offset:0x24 + */ + union + { + __IO uint32_t wp; + struct + { + __IO uint32_t cmd :8; /* [7:0] */ + __IO uint32_t reserved1 :24;/* [31:8] */ + } wp_bit; + }; + + /** + * @brief ertc sbs register, offset:0x28 + */ + union + { + __IO uint32_t sbs; + struct + { + __IO uint32_t sbs :16;/* [15:0] */ + __IO uint32_t reserved1 :16;/* [31:16] */ + } sbs_bit; + }; + + /** + * @brief ertc tadj register, offset:0x2C + */ + union + { + __IO uint32_t tadj; + struct + { + __IO uint32_t decsbs :15;/* [14:0] */ + __IO uint32_t reserved1 :16;/* [30:15] */ + __IO uint32_t add1s :1; /* [31] */ + } tadj_bit; + }; + + /** + * @brief ertc tstm register, offset:0x30 + */ + union + { + __IO uint32_t tstm; + struct + { + __IO uint32_t s :7; /* [6:0] */ + __IO uint32_t reserved1 :1; /* [7] */ + __IO uint32_t m :7; /* [14:8] */ + __IO uint32_t reserved2 :1; /* [15] */ + __IO uint32_t h :6; /* [21:16] */ + __IO uint32_t ampm :1; /* [22] */ + __IO uint32_t reserved3 :9; /* [31:23] */ + } tstm_bit; + }; + + /** + * @brief ertc tsdt register, offset:0x34 + */ + union + { + __IO uint32_t tsdt; + struct + { + __IO uint32_t d :6; /* [5:0] */ + __IO uint32_t reserved1 :2; /* [7:6] */ + __IO uint32_t m :5; /* [12:8] */ + __IO uint32_t wk :3; /* [15:13] */ + __IO uint32_t reserved2 :16;/* [31:16] */ + } tsdt_bit; + }; + + /** + * @brief ertc tssbs register, offset:0x38 + */ + union + { + __IO uint32_t tssbs; + struct + { + __IO uint32_t sbs :16;/* [15:0] */ + __IO uint32_t reserved1 :16;/* [31:16] */ + } tssbs_bit; + }; + + /** + * @brief ertc scal register, offset:0x3C + */ + union + { + __IO uint32_t scal; + struct + { + __IO uint32_t dec :9; /* [8:0] */ + __IO uint32_t reserved1 :4; /* [12:9] */ + __IO uint32_t cal16 :1; /* [13] */ + __IO uint32_t cal8 :1; /* [14] */ + __IO uint32_t add :1; /* [15] */ + __IO uint32_t reserved2 :16;/* [31:16] */ + } scal_bit; + }; + + /** + * @brief ertc tamp register, offset:0x40 + */ + union + { + __IO uint32_t tamp; + struct + { + __IO uint32_t tp1en :1; /* [0] */ + __IO uint32_t tp1edg :1; /* [1] */ + __IO uint32_t tpien :1; /* [2] */ + __IO uint32_t reserved1 :1; /* [3] */ + __IO uint32_t reserved2 :1; /* [4] */ + __IO uint32_t reserved3 :2; /* [6:5] */ + __IO uint32_t tptsen :1; /* [7] */ + __IO uint32_t tpfreq :3; /* [10:8] */ + __IO uint32_t tpflt :2; /* [12:11] */ + __IO uint32_t tppr :2; /* [14:13] */ + __IO uint32_t tppu :1; /* [15] */ + __IO uint32_t reserved4 :1; /* [16] */ + __IO uint32_t reserved5 :1; /* [17] */ + __IO uint32_t outtype :1; /* [18] */ + __IO uint32_t reserved6 :13;/* [31:19] */ + } tamp_bit; + }; + + /** + * @brief ertc alasbs register, offset:0x44 + */ + union + { + __IO uint32_t alasbs; + struct + { + __IO uint32_t sbs :15;/* [14:0] */ + __IO uint32_t reserved1 :9; /* [23:15] */ + __IO uint32_t sbsmsk :4; /* [27:24] */ + __IO uint32_t reserved2 :4; /* [31:28] */ + } alasbs_bit; + }; + + /** + * @brief ertc reserved register, offset:0x48 + */ + __IO uint32_t reserved3; + + /** + * @brief reserved register, offset:0x4c + */ + __IO uint32_t reserved4; + + /** + * @brief ertc dt1 register, offset:0x50 + */ + union + { + __IO uint32_t dt1; + struct + { + __IO uint32_t dt :32;/* [31:0] */ + } dt1_bit; + }; + + /** + * @brief ertc dt2 register, offset:0x54 + */ + union + { + __IO uint32_t dt2; + struct + { + __IO uint32_t dt :32;/* [31:0] */ + } dt2_bit; + }; + + /** + * @brief ertc dt3 register, offset:0x58 + */ + union + { + __IO uint32_t dt3; + struct + { + __IO uint32_t dt :32;/* [31:0] */ + } dt3_bit; + }; + + /** + * @brief ertc dt4 register, offset:0x5C + */ + union + { + __IO uint32_t dt4; + struct + { + __IO uint32_t dt :32;/* [31:0] */ + } dt4_bit; + }; + + /** + * @brief ertc dt5 register, offset:0x60 + */ + union + { + __IO uint32_t dt5; + struct + { + __IO uint32_t dt :32;/* [31:0] */ + } dt5_bit; + }; + +} ertc_type; + +/** + * @} + */ + +#define ERTC ((ertc_type *) ERTC_BASE) + +/** @defgroup ERTC_exported_functions + * @{ + */ + +uint8_t ertc_num_to_bcd(uint8_t num); +uint8_t ertc_bcd_to_num(uint8_t bcd); +void ertc_write_protect_enable(void); +void ertc_write_protect_disable(void); +error_status ertc_wait_update(void); +error_status ertc_wait_flag(uint32_t flag, flag_status status); +error_status ertc_init_mode_enter(void); +void ertc_init_mode_exit(void); +error_status ertc_reset(void); +error_status ertc_divider_set(uint16_t div_a, uint16_t div_b); +error_status ertc_hour_mode_set(ertc_hour_mode_set_type mode); +error_status ertc_date_set(uint8_t year, uint8_t month, uint8_t date, uint8_t week); +error_status ertc_time_set(uint8_t hour, uint8_t min, uint8_t sec, ertc_am_pm_type ampm); +void ertc_calendar_get(ertc_time_type* time); +uint32_t ertc_sub_second_get(void); +void ertc_alarm_mask_set(ertc_alarm_type alarm_x, uint32_t mask); +void ertc_alarm_week_date_select(ertc_alarm_type alarm_x, ertc_week_date_select_type wk); +void ertc_alarm_set(ertc_alarm_type alarm_x, uint8_t week_date, uint8_t hour, uint8_t min, uint8_t sec, ertc_am_pm_type ampm); +void ertc_alarm_sub_second_set(ertc_alarm_type alarm_x, uint32_t value, ertc_alarm_sbs_mask_type mask); +error_status ertc_alarm_enable(ertc_alarm_type alarm_x, confirm_state new_state); +void ertc_alarm_get(ertc_alarm_type alarm_x, ertc_alarm_value_type* alarm); +uint32_t ertc_alarm_sub_second_get(ertc_alarm_type alarm_x); +void ertc_wakeup_clock_set(ertc_wakeup_clock_type clock); +void ertc_wakeup_counter_set(uint32_t counter); +uint16_t ertc_wakeup_counter_get(void); +error_status ertc_wakeup_enable(confirm_state new_state); +error_status ertc_smooth_calibration_config(ertc_smooth_cal_period_type period, ertc_smooth_cal_clk_add_type clk_add, uint32_t clk_dec); +void ertc_cal_output_select(ertc_cal_output_select_type output); +void ertc_cal_output_enable(confirm_state new_state); +error_status ertc_time_adjust(ertc_time_adjust_type add1s, uint32_t decsbs); +void ertc_daylight_set(ertc_dst_operation_type operation, ertc_dst_save_type save); +uint8_t ertc_daylight_bpr_get(void); +error_status ertc_refer_clock_detect_enable(confirm_state new_state); +void ertc_direct_read_enable(confirm_state new_state); +void ertc_output_set(ertc_output_source_type source, ertc_output_polarity_type polarity, ertc_output_type type); +void ertc_timestamp_valid_edge_set(ertc_timestamp_valid_edge_type edge); +void ertc_timestamp_enable(confirm_state new_state); +void ertc_timestamp_get(ertc_time_type* time); +uint32_t ertc_timestamp_sub_second_get(void); +void ertc_tamper_pull_up_enable(confirm_state new_state); +void ertc_tamper_precharge_set(ertc_tamper_precharge_type precharge); +void ertc_tamper_filter_set(ertc_tamper_filter_type filter); +void ertc_tamper_detect_freq_set(ertc_tamper_detect_freq_type freq); +void ertc_tamper_valid_edge_set(ertc_tamper_select_type tamper_x, ertc_tamper_valid_edge_type trigger); +void ertc_tamper_timestamp_enable(confirm_state new_state); +void ertc_tamper_enable(ertc_tamper_select_type tamper_x, confirm_state new_state); +void ertc_interrupt_enable(uint32_t source, confirm_state new_state); +flag_status ertc_interrupt_get(uint32_t source); +flag_status ertc_flag_get(uint32_t flag); +flag_status ertc_interrupt_flag_get(uint32_t flag); +void ertc_flag_clear(uint32_t flag); +void ertc_bpr_data_write(ertc_dt_type dt, uint32_t data); +uint32_t ertc_bpr_data_read(ertc_dt_type dt); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_exint.h b/libraries/drivers/inc/at32f425_exint.h new file mode 100644 index 0000000..347bca0 --- /dev/null +++ b/libraries/drivers/inc/at32f425_exint.h @@ -0,0 +1,232 @@ +/** + ************************************************************************** + * @file at32f425_exint.h + * @brief at32f425 exint header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_EXINT_H +#define __AT32F425_EXINT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup EXINT + * @{ + */ + +/** @defgroup EXINT_lines + * @{ + */ + +#define EXINT_LINE_NONE ((uint32_t)0x000000) +#define EXINT_LINE_0 ((uint32_t)0x000001) /*!< external interrupt line 0 */ +#define EXINT_LINE_1 ((uint32_t)0x000002) /*!< external interrupt line 1 */ +#define EXINT_LINE_2 ((uint32_t)0x000004) /*!< external interrupt line 2 */ +#define EXINT_LINE_3 ((uint32_t)0x000008) /*!< external interrupt line 3 */ +#define EXINT_LINE_4 ((uint32_t)0x000010) /*!< external interrupt line 4 */ +#define EXINT_LINE_5 ((uint32_t)0x000020) /*!< external interrupt line 5 */ +#define EXINT_LINE_6 ((uint32_t)0x000040) /*!< external interrupt line 6 */ +#define EXINT_LINE_7 ((uint32_t)0x000080) /*!< external interrupt line 7 */ +#define EXINT_LINE_8 ((uint32_t)0x000100) /*!< external interrupt line 8 */ +#define EXINT_LINE_9 ((uint32_t)0x000200) /*!< external interrupt line 9 */ +#define EXINT_LINE_10 ((uint32_t)0x000400) /*!< external interrupt line 10 */ +#define EXINT_LINE_11 ((uint32_t)0x000800) /*!< external interrupt line 11 */ +#define EXINT_LINE_12 ((uint32_t)0x001000) /*!< external interrupt line 12 */ +#define EXINT_LINE_13 ((uint32_t)0x002000) /*!< external interrupt line 13 */ +#define EXINT_LINE_14 ((uint32_t)0x004000) /*!< external interrupt line 14 */ +#define EXINT_LINE_15 ((uint32_t)0x008000) /*!< external interrupt line 15 */ +#define EXINT_LINE_16 ((uint32_t)0x010000) /*!< external interrupt line 16 connected to the pvm output */ +#define EXINT_LINE_17 ((uint32_t)0x020000) /*!< external interrupt line 17 connected to the ertc alarm event */ +#define EXINT_LINE_18 ((uint32_t)0x040000) /*!< external interrupt line 18 connected to otg interrupt */ +#define EXINT_LINE_19 ((uint32_t)0x080000) /*!< external interrupt line 19 connected to the ertc timestamp event */ +#define EXINT_LINE_20 ((uint32_t)0x100000) /*!< external interrupt line 20 connected to the ertc wakeup timer event */ + + +/** + * @} + */ + +/** @defgroup EXINT_exported_types + * @{ + */ + +/** + * @brief exint line mode type + */ +typedef enum +{ + EXINT_LINE_INTERRUPUT = 0x00, /*!< external interrupt line interrupt mode */ + EXINT_LINE_EVENT = 0x01 /*!< external interrupt line event mode */ +} exint_line_mode_type; + +/** + * @brief exint polarity configuration type + */ +typedef enum +{ + EXINT_TRIGGER_RISING_EDGE = 0x00, /*!< external interrupt line rising trigger mode */ + EXINT_TRIGGER_FALLING_EDGE = 0x01, /*!< external interrupt line falling trigger mode */ + EXINT_TRIGGER_BOTH_EDGE = 0x02 /*!< external interrupt line both rising and falling trigger mode */ +} exint_polarity_config_type; + +/** + * @brief exint init type + */ +typedef struct +{ + exint_line_mode_type line_mode; /*!< choose mode event or interrupt mode */ + uint32_t line_select; /*!< select the exint line, availiable for single line or multiple lines */ + exint_polarity_config_type line_polarity; /*!< select the tregger polarity, with rising edge, falling edge or both edge */ + confirm_state line_enable; /*!< enable or disable exint */ +} exint_init_type; + +/** + * @brief type define exint register all + */ +typedef struct +{ + + /** + * @brief exint inten register, offset:0x00 + */ + union + { + __IO uint32_t inten; + struct + { + __IO uint32_t intenx : 22;/* [21:0] */ + __IO uint32_t reserved1 : 10;/* [31:22] */ + } inten_bit; + }; + + /** + * @brief exint evten register, offset:0x04 + */ + union + { + __IO uint32_t evten; + struct + { + __IO uint32_t evtenx : 22;/* [21:0] */ + __IO uint32_t reserved1 : 10;/* [31:22] */ + } evten_bit; + }; + + /** + * @brief exint polcfg1 register, offset:0x08 + */ + union + { + __IO uint32_t polcfg1; + struct + { + __IO uint32_t rpx : 22;/* [21:0] */ + __IO uint32_t reserved1 : 10;/* [31:22] */ + } polcfg1_bit; + }; + + /** + * @brief exint polcfg2 register, offset:0x0C + */ + union + { + __IO uint32_t polcfg2; + struct + { + __IO uint32_t fpx : 22;/* [21:0] */ + __IO uint32_t reserved1 : 10;/* [31:22] */ + } polcfg2_bit; + }; + + /** + * @brief exint swtrg register, offset:0x10 + */ + union + { + __IO uint32_t swtrg; + struct + { + __IO uint32_t swtx : 22;/* [21:0] */ + __IO uint32_t reserved1 : 10;/* [31:22] */ + } swtrg_bit; + }; + + /** + * @brief exint intsts register, offset:0x14 + */ + union + { + __IO uint32_t intsts; + struct + { + __IO uint32_t linex : 20;/* [21:0] */ + __IO uint32_t reserved1 : 12;/* [31:22] */ + } intsts_bit; + }; +} exint_type; + +/** + * @} + */ + +#define EXINT ((exint_type *) EXINT_BASE) + +/** @defgroup EXINT_exported_functions + * @{ + */ + +void exint_reset(void); +void exint_default_para_init(exint_init_type *exint_struct); +void exint_init(exint_init_type *exint_struct); +void exint_flag_clear(uint32_t exint_line); +flag_status exint_flag_get(uint32_t exint_line); +flag_status exint_interrupt_flag_get(uint32_t exint_line); +void exint_software_interrupt_event_generate(uint32_t exint_line); +void exint_interrupt_enable(uint32_t exint_line, confirm_state new_state); +void exint_event_enable(uint32_t exint_line, confirm_state new_state); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_flash.h b/libraries/drivers/inc/at32f425_flash.h new file mode 100644 index 0000000..c2670de --- /dev/null +++ b/libraries/drivers/inc/at32f425_flash.h @@ -0,0 +1,577 @@ +/** + ************************************************************************** + * @file at32f425_flash.h + * @brief at32f425 flash header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_FLASH_H +#define __AT32F425_FLASH_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/** @defgroup FLASH_keys + * @brief flash keys + * @{ + */ + +#define FLASH_UNLOCK_KEY1 ((uint32_t)0x45670123) /*!< flash operation unlock order key1 */ +#define FLASH_UNLOCK_KEY2 ((uint32_t)0xCDEF89AB) /*!< flash operation unlock order key2 */ +#define FAP_RELIEVE_KEY ((uint16_t)0x00A5) /*!< flash fap relieve key val */ +#define FAP_HIGH_LEVEL_KEY ((uint16_t)0x00CC) /*!< flash fap high level enable key val */ +#define SLIB_UNLOCK_KEY ((uint32_t)0xA35F6D24) /*!< flash slib operation unlock order key */ + +/** + * @} + */ + +/** @defgroup FLASH_flags + * @brief flash flag + * @{ + */ + +#define FLASH_OBF_FLAG ((uint32_t)0x00000001) /*!< flash operate busy flag */ +#define FLASH_ODF_FLAG ((uint32_t)0x00000020) /*!< flash operate done flag */ +#define FLASH_PRGMERR_FLAG ((uint32_t)0x00000004) /*!< flash program error flag */ +#define FLASH_EPPERR_FLAG ((uint32_t)0x00000010) /*!< flash erase/program protection error flag */ +#define FLASH_USDERR_FLAG ((uint32_t)0x40000001) /*!< flash user system data error flag */ + +/** + * @} + */ + +/** @defgroup FLASH_interrupts + * @brief flash interrupts + * @{ + */ + +#define FLASH_ERR_INT ((uint32_t)0x00000001) /*!< flash error interrupt */ +#define FLASH_ODF_INT ((uint32_t)0x00000002) /*!< flash operate done interrupt */ + +/** + * @} + */ + +/** @defgroup FLASH_slib_mask + * @brief flash slib mask + * @{ + */ + +#define FLASH_SLIB_START_SECTOR ((uint32_t)0x000007FF) /*!< flash slib start sector */ +#define FLASH_SLIB_INST_START_SECTOR ((uint32_t)0x003FF800) /*!< flash slib i-bus area start sector */ +#define FLASH_SLIB_END_SECTOR ((uint32_t)0xFFC00000) /*!< flash slib end sector */ + +/** + * @} + */ + +/** @defgroup FLASH_user_system_data + * @brief flash user system data + * @{ + */ + +#define USD_WDT_ATO_DISABLE ((uint16_t)0x0001) /*!< wdt auto start disabled */ +#define USD_WDT_ATO_ENABLE ((uint16_t)0x0000) /*!< wdt auto start enabled */ + +#define USD_DEPSLP_NO_RST ((uint16_t)0x0002) /*!< no reset generated when entering in deepsleep */ +#define USD_DEPSLP_RST ((uint16_t)0x0000) /*!< reset generated when entering in deepsleep */ + +#define USD_STDBY_NO_RST ((uint16_t)0x0004) /*!< no reset generated when entering in standby */ +#define USD_STDBY_RST ((uint16_t)0x0000) /*!< reset generated when entering in standby */ + +#define USD_BOOT1_LOW ((uint16_t)0x0010) /*!< when boot0 is high level, boot from bootmem */ +#define USD_BOOT1_HIGH ((uint16_t)0x0000) /*!< when boot0 is high level, boot from sram */ + +#define USD_DEPSLP_WDT_CONTINUE ((uint16_t)0x0020) /*!< wdt continue count when entering in deepsleep */ +#define USD_DEPSLP_WDT_STOP ((uint16_t)0x0000) /*!< wdt stop count when entering in deepsleep */ + +#define USD_STDBY_WDT_CONTINUE ((uint16_t)0x0040) /*!< wdt continue count when entering in standby */ +#define USD_STDBY_WDT_STOP ((uint16_t)0x0000) /*!< wdt stop count when entering in standby */ + +/** + * @} + */ + +/** @defgroup FLASH_timeout_definition + * @brief flash timeout definition + * @{ + */ + +#define ERASE_TIMEOUT ((uint32_t)0x40000000) /*!< internal flash erase operation timeout */ +#define PROGRAMMING_TIMEOUT ((uint32_t)0x00100000) /*!< internal flash program operation timeout */ +#define OPERATION_TIMEOUT ((uint32_t)0x10000000) /*!< flash common operation timeout */ + +/** + * @} + */ + +/** + * @brief set the flash psr register + * @param wtcyc: the flash wait cycle. + * this parameter can be one of the following values: + * - FLASH_WAIT_CYCLE_0 + * - FLASH_WAIT_CYCLE_1 + * - FLASH_WAIT_CYCLE_2 + * - FLASH_WAIT_CYCLE_3 + */ +#define flash_psr_set(wtcyc) (FLASH->psr = (uint32_t)(0x150 | wtcyc)) + +/** @defgroup FLASH_exported_types + * @{ + */ + +/** + * @brief flash status type + */ +typedef enum +{ + FLASH_OPERATE_BUSY = 0x00, /*!< flash status is operate busy */ + FLASH_PROGRAM_ERROR = 0x01, /*!< flash status is program error */ + FLASH_EPP_ERROR = 0x02, /*!< flash status is epp error */ + FLASH_OPERATE_DONE = 0x03, /*!< flash status is operate done */ + FLASH_OPERATE_TIMEOUT = 0x04 /*!< flash status is operate timeout */ +} flash_status_type; + +/** + * @brief flash wait cycle type + */ +typedef enum +{ + FLASH_WAIT_CYCLE_0 = 0x00, /*!< sysclk 1~32mhz */ + FLASH_WAIT_CYCLE_1 = 0x01, /*!< sysclk 33~64mhz */ + FLASH_WAIT_CYCLE_2 = 0x02, /*!< sysclk 65~96mhz */ + FLASH_WAIT_CYCLE_3 = 0x03 /*!< sysclk 97~120mhz */ +} flash_wait_cycle_type; + +/** + * @brief type define flash register all + */ +typedef struct +{ + /** + * @brief flash psr register, offset:0x00 + */ + union + { + __IO uint32_t psr; + struct + { + __IO uint32_t wtcyc : 3; /* [2:0] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t pft_en : 1; /* [4] */ + __IO uint32_t pft_enf : 1; /* [5] */ + __IO uint32_t pft_en2 : 1; /* [6] */ + __IO uint32_t pft_enf2 : 1; /* [7] */ + __IO uint32_t pft_lat_dis : 1; /* [8] */ + __IO uint32_t reserved2 : 23;/* [31:9] */ + } psr_bit; + }; + + /** + * @brief flash unlock register, offset:0x04 + */ + union + { + __IO uint32_t unlock; + struct + { + __IO uint32_t ukval : 32;/* [31:0] */ + } unlock_bit; + }; + + /** + * @brief flash usd unlock register, offset:0x08 + */ + union + { + __IO uint32_t usd_unlock; + struct + { + __IO uint32_t usd_ukval : 32;/* [31:0] */ + } usd_unlock_bit; + }; + + /** + * @brief flash sts register, offset:0x0C + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t obf : 1; /* [0] */ + __IO uint32_t reserved1 : 1; /* [1] */ + __IO uint32_t prgmerr : 1; /* [2] */ + __IO uint32_t reserved2 : 1; /* [3] */ + __IO uint32_t epperr : 1; /* [4] */ + __IO uint32_t odf : 1; /* [5] */ + __IO uint32_t reserved3 : 26;/* [31:6] */ + } sts_bit; + }; + + /** + * @brief flash ctrl register, offset:0x10 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t fprgm : 1; /* [0] */ + __IO uint32_t secers : 1; /* [1] */ + __IO uint32_t bankers : 1; /* [2] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t usdprgm : 1; /* [4] */ + __IO uint32_t usders : 1; /* [5] */ + __IO uint32_t erstr : 1; /* [6] */ + __IO uint32_t oplk : 1; /* [7] */ + __IO uint32_t reserved2 : 1; /* [8] */ + __IO uint32_t usdulks : 1; /* [9] */ + __IO uint32_t errie : 1; /* [10] */ + __IO uint32_t reserved3 : 1; /* [11] */ + __IO uint32_t odfie : 1; /* [12] */ + __IO uint32_t reserved4 : 4; /* [16:13] */ + __IO uint32_t lpmen : 1; /* [17] */ + __IO uint32_t reserved5 : 14;/* [31:18] */ + } ctrl_bit; + }; + + /** + * @brief flash addr register, offset:0x14 + */ + union + { + __IO uint32_t addr; + struct + { + __IO uint32_t fa : 32;/* [31:0] */ + } addr_bit; + }; + + /** + * @brief flash reserved1 register, offset:0x18 + */ + __IO uint32_t reserved1; + + /** + * @brief flash usd register, offset:0x1C + */ + union + { + __IO uint32_t usd; + struct + { + __IO uint32_t usderr : 1; /* [0] */ + __IO uint32_t fap : 1; /* [1] */ + __IO uint32_t wdt_ato_en : 1; /* [2] */ + __IO uint32_t depslp_rst : 1; /* [3] */ + __IO uint32_t stdby_rst : 1; /* [4] */ + __IO uint32_t reserved1 : 1; /* [5] */ + __IO uint32_t boot1 : 1; /* [6] */ + __IO uint32_t depslp_wdt : 1; /* [7] */ + __IO uint32_t stdby_wdt : 1; /* [8] */ + __IO uint32_t reserved2 : 1; /* [9] */ + __IO uint32_t user_d0 : 8; /* [17:10] */ + __IO uint32_t user_d1 : 8; /* [25:18] */ + __IO uint32_t fap_hl : 1; /* [26] */ + __IO uint32_t reserved3 : 5; /* [31:27] */ + } usd_bit; + }; + + /** + * @brief flash epps register, offset:0x20 + */ + union + { + __IO uint32_t epps; + struct + { + __IO uint32_t epps : 32;/* [31:0] */ + } epps_bit; + }; + + /** + * @brief flash reserved2 register, offset:0x70~0x24 + */ + __IO uint32_t reserved2[20]; + + /** + * @brief flash slib_sts0 register, offset:0x74 + */ + union + { + __IO uint32_t slib_sts0; + struct + { + __IO uint32_t btm_ap_enf : 1; /* [0] */ + __IO uint32_t reserved1 : 1; /* [1] */ + __IO uint32_t em_slib_enf : 1; /* [2] */ + __IO uint32_t slib_enf : 1; /* [3] */ + __IO uint32_t reserved2 : 12;/* [15:4] */ + __IO uint32_t em_slib_inst_ss : 8; /* [23:16] */ + __IO uint32_t reserved3 : 8; /* [31:24] */ + } slib_sts0_bit; + }; + + /** + * @brief flash slib_sts1 register, offset:0x78 + */ + union + { + __IO uint32_t slib_sts1; + struct + { + __IO uint32_t slib_ss : 11;/* [10:0] */ + __IO uint32_t slib_inst_ss : 11;/* [21:11] */ + __IO uint32_t slib_es : 10;/* [31:22] */ + } slib_sts1_bit; + }; + + /** + * @brief flash slib_pwd_clr register, offset:0x7C + */ + union + { + __IO uint32_t slib_pwd_clr; + struct + { + __IO uint32_t slib_pclr_val : 32;/* [31:0] */ + } slib_pwd_clr_bit; + }; + + /** + * @brief flash slib_misc_sts register, offset:0x80 + */ + union + { + __IO uint32_t slib_misc_sts; + struct + { + __IO uint32_t slib_pwd_err : 1; /* [0] */ + __IO uint32_t slib_pwd_ok : 1; /* [1] */ + __IO uint32_t slib_ulkf : 1; /* [2] */ + __IO uint32_t reserved1 : 29;/* [31:3] */ + } slib_misc_sts_bit; + }; + + /** + * @brief flash crc_addr register, offset:0x84 + */ + union + { + __IO uint32_t crc_addr; + struct + { + __IO uint32_t crc_addr : 32;/* [31:0] */ + } crc_addr_bit; + }; + + /** + * @brief flash crc_ctrl register, offset:0x88 + */ + union + { + __IO uint32_t crc_ctrl; + struct + { + __IO uint32_t crc_sn : 16;/* [15:0] */ + __IO uint32_t crc_strt : 1; /* [16] */ + __IO uint32_t reserved1 : 15;/* [31:17] */ + } crc_ctrl_bit; + }; + + /** + * @brief flash crc_chkr register, offset:0x8C + */ + union + { + __IO uint32_t crc_chkr; + struct + { + __IO uint32_t crc_chkr : 32;/* [31:0] */ + } crc_chkr_bit; + }; + + /** + * @brief flash reserved3 register, offset:0x15C~0x90 + */ + __IO uint32_t reserved3[52]; + + /** + * @brief flash slib_set_pwd register, offset:0x160 + */ + union + { + __IO uint32_t slib_set_pwd; + struct + { + __IO uint32_t slib_pset_val : 32;/* [31:0] */ + } slib_set_pwd_bit; + }; + + /** + * @brief flash slib_set_range register, offset:0x164 + */ + union + { + __IO uint32_t slib_set_range; + struct + { + __IO uint32_t slib_ss_set : 11;/* [10:0] */ + __IO uint32_t slib_iss_set : 11;/* [21:11] */ + __IO uint32_t slib_es_set : 10;/* [31:22] */ + } slib_set_range_bit; + }; + + /** + * @brief flash em_slib_set register, offset:0x168 + */ + union + { + __IO uint32_t em_slib_set; + struct + { + __IO uint32_t em_slib_set : 16;/* [15:0] */ + __IO uint32_t em_slib_iss_set : 8; /* [23:16] */ + __IO uint32_t reserved1 : 8; /* [31:24] */ + } em_slib_set_bit; + }; + + /** + * @brief flash btm_mode_set register, offset:0x16C + */ + union + { + __IO uint32_t btm_mode_set; + struct + { + __IO uint32_t btm_mode_set : 8; /* [7:0] */ + __IO uint32_t reserved1 : 24;/* [31:8] */ + } btm_mode_set_bit; + }; + + /** + * @brief flash slib_unlock register, offset:0x170 + */ + union + { + __IO uint32_t slib_unlock; + struct + { + __IO uint32_t slib_ukval : 32;/* [31:0] */ + } slib_unlock_bit; + }; + +} flash_type; + +/** + * @brief user system data + */ +typedef struct +{ + __IO uint16_t fap; + __IO uint16_t ssb; + __IO uint16_t data0; + __IO uint16_t data1; + __IO uint16_t epp0; + __IO uint16_t epp1; + __IO uint16_t epp2; + __IO uint16_t epp3; +} usd_type; + +/** + * @} + */ + +#define FLASH ((flash_type *) FLASH_REG_BASE) +#define USD ((usd_type *) USD_BASE) + +/** @defgroup FLASH_exported_functions + * @{ + */ + +flag_status flash_flag_get(uint32_t flash_flag); +void flash_flag_clear(uint32_t flash_flag); +flash_status_type flash_operation_status_get(void); +flash_status_type flash_operation_wait_for(uint32_t time_out); +void flash_unlock(void); +void flash_lock(void); +flash_status_type flash_sector_erase(uint32_t sector_address); +flash_status_type flash_internal_all_erase(void); +flash_status_type flash_user_system_data_erase(void); +flash_status_type flash_word_program(uint32_t address, uint32_t data); +flash_status_type flash_halfword_program(uint32_t address, uint16_t data); +flash_status_type flash_byte_program(uint32_t address, uint8_t data); +flash_status_type flash_user_system_data_program(uint32_t address, uint8_t data); +flash_status_type flash_epp_set(uint32_t *sector_bits); +void flash_epp_status_get(uint32_t *sector_bits); +flash_status_type flash_fap_enable(confirm_state new_state); +flag_status flash_fap_status_get(void); +flash_status_type flash_fap_high_level_enable(void); +flag_status flash_fap_high_level_status_get(void); +flash_status_type flash_ssb_set(uint8_t usd_ssb); +uint8_t flash_ssb_status_get(void); +void flash_interrupt_enable(uint32_t flash_int, confirm_state new_state); +flash_status_type flash_slib_enable(uint32_t pwd, uint16_t start_sector, uint16_t inst_start_sector, uint16_t end_sector); +error_status flash_slib_disable(uint32_t pwd); +flag_status flash_slib_state_get(void); +uint16_t flash_slib_start_sector_get(void); +uint16_t flash_slib_inststart_sector_get(void); +uint16_t flash_slib_end_sector_get(void); +uint32_t flash_crc_calibrate(uint32_t start_addr, uint32_t sector_cnt); +void flash_boot_memory_extension_mode_enable(void); +flash_status_type flash_extension_memory_slib_enable(uint32_t pwd, uint16_t inst_start_sector); +flag_status flash_extension_memory_slib_state_get(void); +uint16_t flash_em_slib_inststart_sector_get(void); +void flash_low_power_mode_enable(confirm_state new_state); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_gpio.h b/libraries/drivers/inc/at32f425_gpio.h new file mode 100644 index 0000000..2e6aa8a --- /dev/null +++ b/libraries/drivers/inc/at32f425_gpio.h @@ -0,0 +1,553 @@ +/** + ************************************************************************** + * @file at32f425_gpio.h + * @brief at32f425 gpio header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_GPIO_H +#define __AT32F425_GPIO_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/** @defgroup GPIO_pins_number_definition + * @{ + */ + +#define GPIO_PINS_0 0x0001 /*!< gpio pins number 0 */ +#define GPIO_PINS_1 0x0002 /*!< gpio pins number 1 */ +#define GPIO_PINS_2 0x0004 /*!< gpio pins number 2 */ +#define GPIO_PINS_3 0x0008 /*!< gpio pins number 3 */ +#define GPIO_PINS_4 0x0010 /*!< gpio pins number 4 */ +#define GPIO_PINS_5 0x0020 /*!< gpio pins number 5 */ +#define GPIO_PINS_6 0x0040 /*!< gpio pins number 6 */ +#define GPIO_PINS_7 0x0080 /*!< gpio pins number 7 */ +#define GPIO_PINS_8 0x0100 /*!< gpio pins number 8 */ +#define GPIO_PINS_9 0x0200 /*!< gpio pins number 9 */ +#define GPIO_PINS_10 0x0400 /*!< gpio pins number 10 */ +#define GPIO_PINS_11 0x0800 /*!< gpio pins number 11 */ +#define GPIO_PINS_12 0x1000 /*!< gpio pins number 12 */ +#define GPIO_PINS_13 0x2000 /*!< gpio pins number 13 */ +#define GPIO_PINS_14 0x4000 /*!< gpio pins number 14 */ +#define GPIO_PINS_15 0x8000 /*!< gpio pins number 15 */ +#define GPIO_PINS_ALL 0xFFFF /*!< gpio all pins */ + +/** + * @} + */ + +/** @defgroup GPIO_exported_types + * @{ + */ + +/** + * @brief gpio mode select + */ +typedef enum +{ + GPIO_MODE_INPUT = 0x00, /*!< gpio input mode */ + GPIO_MODE_OUTPUT = 0x01, /*!< gpio output mode */ + GPIO_MODE_MUX = 0x02, /*!< gpio mux function mode */ + GPIO_MODE_ANALOG = 0x03 /*!< gpio analog in/out mode */ +} gpio_mode_type; + +/** + * @brief gpio output drive strength select + */ +typedef enum +{ + GPIO_DRIVE_STRENGTH_STRONGER = 0x01, /*!< stronger sourcing/sinking strength */ + GPIO_DRIVE_STRENGTH_MODERATE = 0x02 /*!< moderate sourcing/sinking strength */ +} gpio_drive_type; + +/** + * @brief gpio output type + */ +typedef enum +{ + GPIO_OUTPUT_PUSH_PULL = 0x00, /*!< output push-pull */ + GPIO_OUTPUT_OPEN_DRAIN = 0x01 /*!< output open-drain */ +} gpio_output_type; + +/** + * @brief gpio pull type + */ +typedef enum +{ + GPIO_PULL_NONE = 0x00, /*!< floating for input, no pull for output */ + GPIO_PULL_UP = 0x01, /*!< pull-up */ + GPIO_PULL_DOWN = 0x02 /*!< pull-down */ +} gpio_pull_type; + +/** + * @brief gpio init type + */ +typedef struct +{ + uint32_t gpio_pins; /*!< pins number selection */ + gpio_output_type gpio_out_type; /*!< output type selection */ + gpio_pull_type gpio_pull; /*!< pull type selection */ + gpio_mode_type gpio_mode; /*!< mode selection */ + gpio_drive_type gpio_drive_strength; /*!< drive strength selection */ +} gpio_init_type; + +/** + * @brief gpio pins source type + */ +typedef enum +{ + GPIO_PINS_SOURCE0 = 0x00, /*!< gpio pins source number 0 */ + GPIO_PINS_SOURCE1 = 0x01, /*!< gpio pins source number 1 */ + GPIO_PINS_SOURCE2 = 0x02, /*!< gpio pins source number 2 */ + GPIO_PINS_SOURCE3 = 0x03, /*!< gpio pins source number 3 */ + GPIO_PINS_SOURCE4 = 0x04, /*!< gpio pins source number 4 */ + GPIO_PINS_SOURCE5 = 0x05, /*!< gpio pins source number 5 */ + GPIO_PINS_SOURCE6 = 0x06, /*!< gpio pins source number 6 */ + GPIO_PINS_SOURCE7 = 0x07, /*!< gpio pins source number 7 */ + GPIO_PINS_SOURCE8 = 0x08, /*!< gpio pins source number 8 */ + GPIO_PINS_SOURCE9 = 0x09, /*!< gpio pins source number 9 */ + GPIO_PINS_SOURCE10 = 0x0A, /*!< gpio pins source number 10 */ + GPIO_PINS_SOURCE11 = 0x0B, /*!< gpio pins source number 11 */ + GPIO_PINS_SOURCE12 = 0x0C, /*!< gpio pins source number 12 */ + GPIO_PINS_SOURCE13 = 0x0D, /*!< gpio pins source number 13 */ + GPIO_PINS_SOURCE14 = 0x0E, /*!< gpio pins source number 14 */ + GPIO_PINS_SOURCE15 = 0x0F /*!< gpio pins source number 15 */ +} gpio_pins_source_type; + +/** + * @brief gpio muxing function selection type + */ +typedef enum +{ + GPIO_MUX_0 = 0x00, /*!< gpio muxing function selection 0 */ + GPIO_MUX_1 = 0x01, /*!< gpio muxing function selection 1 */ + GPIO_MUX_2 = 0x02, /*!< gpio muxing function selection 2 */ + GPIO_MUX_3 = 0x03, /*!< gpio muxing function selection 3 */ + GPIO_MUX_4 = 0x04, /*!< gpio muxing function selection 4 */ + GPIO_MUX_5 = 0x05, /*!< gpio muxing function selection 5 */ + GPIO_MUX_6 = 0x06, /*!< gpio muxing function selection 6 */ + GPIO_MUX_7 = 0x07, /*!< gpio muxing function selection 7 */ +} gpio_mux_sel_type; + +/** + * @brief type define gpio register all + */ +typedef struct +{ + /** + * @brief gpio mode register, offset:0x00 + */ + union + { + __IO uint32_t cfgr; + struct + { + __IO uint32_t iomc0 : 2; /* [1:0] */ + __IO uint32_t iomc1 : 2; /* [3:2] */ + __IO uint32_t iomc2 : 2; /* [5:4] */ + __IO uint32_t iomc3 : 2; /* [7:6] */ + __IO uint32_t iomc4 : 2; /* [9:8] */ + __IO uint32_t iomc5 : 2; /* [11:10] */ + __IO uint32_t iomc6 : 2; /* [13:12] */ + __IO uint32_t iomc7 : 2; /* [15:14] */ + __IO uint32_t iomc8 : 2; /* [17:16] */ + __IO uint32_t iomc9 : 2; /* [19:18] */ + __IO uint32_t iomc10 : 2; /* [21:20] */ + __IO uint32_t iomc11 : 2; /* [23:22] */ + __IO uint32_t iomc12 : 2; /* [25:24] */ + __IO uint32_t iomc13 : 2; /* [27:26] */ + __IO uint32_t iomc14 : 2; /* [29:28] */ + __IO uint32_t iomc15 : 2; /* [31:30] */ + } cfgr_bit; + }; + + /** + * @brief gpio output type register, offset:0x04 + */ + union + { + __IO uint32_t omode; + struct + { + __IO uint32_t om0 : 1; /* [0] */ + __IO uint32_t om1 : 1; /* [1] */ + __IO uint32_t om2 : 1; /* [2] */ + __IO uint32_t om3 : 1; /* [3] */ + __IO uint32_t om4 : 1; /* [4] */ + __IO uint32_t om5 : 1; /* [5] */ + __IO uint32_t om6 : 1; /* [6] */ + __IO uint32_t om7 : 1; /* [7] */ + __IO uint32_t om8 : 1; /* [8] */ + __IO uint32_t om9 : 1; /* [9] */ + __IO uint32_t om10 : 1; /* [10] */ + __IO uint32_t om11 : 1; /* [11] */ + __IO uint32_t om12 : 1; /* [12] */ + __IO uint32_t om13 : 1; /* [13] */ + __IO uint32_t om14 : 1; /* [14] */ + __IO uint32_t om15 : 1; /* [15] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } omode_bit; + }; + + /** + * @brief gpio output driver register, offset:0x08 + */ + union + { + __IO uint32_t odrvr; + struct + { + __IO uint32_t odrv0 : 2; /* [1:0] */ + __IO uint32_t odrv1 : 2; /* [3:2] */ + __IO uint32_t odrv2 : 2; /* [5:4] */ + __IO uint32_t odrv3 : 2; /* [7:6] */ + __IO uint32_t odrv4 : 2; /* [9:8] */ + __IO uint32_t odrv5 : 2; /* [11:10] */ + __IO uint32_t odrv6 : 2; /* [13:12] */ + __IO uint32_t odrv7 : 2; /* [15:14] */ + __IO uint32_t odrv8 : 2; /* [17:16] */ + __IO uint32_t odrv9 : 2; /* [19:18] */ + __IO uint32_t odrv10 : 2; /* [21:20] */ + __IO uint32_t odrv11 : 2; /* [23:22] */ + __IO uint32_t odrv12 : 2; /* [25:24] */ + __IO uint32_t odrv13 : 2; /* [27:26] */ + __IO uint32_t odrv14 : 2; /* [29:28] */ + __IO uint32_t odrv15 : 2; /* [31:30] */ + } odrvr_bit; + }; + + /** + * @brief gpio pull up/down register, offset:0x0C + */ + union + { + __IO uint32_t pull; + struct + { + __IO uint32_t pull0 : 2; /* [1:0] */ + __IO uint32_t pull1 : 2; /* [3:2] */ + __IO uint32_t pull2 : 2; /* [5:4] */ + __IO uint32_t pull3 : 2; /* [7:6] */ + __IO uint32_t pull4 : 2; /* [9:8] */ + __IO uint32_t pull5 : 2; /* [11:10] */ + __IO uint32_t pull6 : 2; /* [13:12] */ + __IO uint32_t pull7 : 2; /* [15:14] */ + __IO uint32_t pull8 : 2; /* [17:16] */ + __IO uint32_t pull9 : 2; /* [19:18] */ + __IO uint32_t pull10 : 2; /* [21:20] */ + __IO uint32_t pull11 : 2; /* [23:22] */ + __IO uint32_t pull12 : 2; /* [25:24] */ + __IO uint32_t pull13 : 2; /* [27:26] */ + __IO uint32_t pull14 : 2; /* [29:28] */ + __IO uint32_t pull15 : 2; /* [31:30] */ + } pull_bit; + }; + + /** + * @brief gpio input data register, offset:0x10 + */ + union + { + __IO uint32_t idt; + struct + { + __IO uint32_t idt0 : 1; /* [0] */ + __IO uint32_t idt1 : 1; /* [1] */ + __IO uint32_t idt2 : 1; /* [2] */ + __IO uint32_t idt3 : 1; /* [3] */ + __IO uint32_t idt4 : 1; /* [4] */ + __IO uint32_t idt5 : 1; /* [5] */ + __IO uint32_t idt6 : 1; /* [6] */ + __IO uint32_t idt7 : 1; /* [7] */ + __IO uint32_t idt8 : 1; /* [8] */ + __IO uint32_t idt9 : 1; /* [9] */ + __IO uint32_t idt10 : 1; /* [10] */ + __IO uint32_t idt11 : 1; /* [11] */ + __IO uint32_t idt12 : 1; /* [12] */ + __IO uint32_t idt13 : 1; /* [13] */ + __IO uint32_t idt14 : 1; /* [14] */ + __IO uint32_t idt15 : 1; /* [15] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } idt_bit; + }; + + /** + * @brief gpio output data register, offset:0x14 + */ + union + { + __IO uint32_t odt; + struct + { + __IO uint32_t odt0 : 1; /* [0] */ + __IO uint32_t odt1 : 1; /* [1] */ + __IO uint32_t odt2 : 1; /* [2] */ + __IO uint32_t odt3 : 1; /* [3] */ + __IO uint32_t odt4 : 1; /* [4] */ + __IO uint32_t odt5 : 1; /* [5] */ + __IO uint32_t odt6 : 1; /* [6] */ + __IO uint32_t odt7 : 1; /* [7] */ + __IO uint32_t odt8 : 1; /* [8] */ + __IO uint32_t odt9 : 1; /* [9] */ + __IO uint32_t odt10 : 1; /* [10] */ + __IO uint32_t odt11 : 1; /* [11] */ + __IO uint32_t odt12 : 1; /* [12] */ + __IO uint32_t odt13 : 1; /* [13] */ + __IO uint32_t odt14 : 1; /* [14] */ + __IO uint32_t odt15 : 1; /* [15] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } odt_bit; + }; + + /** + * @brief gpio scr register, offset:0x18 + */ + union + { + __IO uint32_t scr; + struct + { + __IO uint32_t iosb0 : 1; /* [0] */ + __IO uint32_t iosb1 : 1; /* [1] */ + __IO uint32_t iosb2 : 1; /* [2] */ + __IO uint32_t iosb3 : 1; /* [3] */ + __IO uint32_t iosb4 : 1; /* [4] */ + __IO uint32_t iosb5 : 1; /* [5] */ + __IO uint32_t iosb6 : 1; /* [6] */ + __IO uint32_t iosb7 : 1; /* [7] */ + __IO uint32_t iosb8 : 1; /* [8] */ + __IO uint32_t iosb9 : 1; /* [9] */ + __IO uint32_t iosb10 : 1; /* [10] */ + __IO uint32_t iosb11 : 1; /* [11] */ + __IO uint32_t iosb12 : 1; /* [12] */ + __IO uint32_t iosb13 : 1; /* [13] */ + __IO uint32_t iosb14 : 1; /* [14] */ + __IO uint32_t iosb15 : 1; /* [15] */ + __IO uint32_t iocb0 : 1; /* [16] */ + __IO uint32_t iocb1 : 1; /* [17] */ + __IO uint32_t iocb2 : 1; /* [18] */ + __IO uint32_t iocb3 : 1; /* [19] */ + __IO uint32_t iocb4 : 1; /* [20] */ + __IO uint32_t iocb5 : 1; /* [21] */ + __IO uint32_t iocb6 : 1; /* [22] */ + __IO uint32_t iocb7 : 1; /* [23] */ + __IO uint32_t iocb8 : 1; /* [24] */ + __IO uint32_t iocb9 : 1; /* [25] */ + __IO uint32_t iocb10 : 1; /* [26] */ + __IO uint32_t iocb11 : 1; /* [27] */ + __IO uint32_t iocb12 : 1; /* [28] */ + __IO uint32_t iocb13 : 1; /* [29] */ + __IO uint32_t iocb14 : 1; /* [30] */ + __IO uint32_t iocb15 : 1; /* [31] */ + } scr_bit; + }; + + /** + * @brief gpio wpr register, offset:0x1C + */ + union + { + __IO uint32_t wpr; + struct + { + __IO uint32_t wpen0 : 1; /* [0] */ + __IO uint32_t wpen1 : 1; /* [1] */ + __IO uint32_t wpen2 : 1; /* [2] */ + __IO uint32_t wpen3 : 1; /* [3] */ + __IO uint32_t wpen4 : 1; /* [4] */ + __IO uint32_t wpen5 : 1; /* [5] */ + __IO uint32_t wpen6 : 1; /* [6] */ + __IO uint32_t wpen7 : 1; /* [7] */ + __IO uint32_t wpen8 : 1; /* [8] */ + __IO uint32_t wpen9 : 1; /* [9] */ + __IO uint32_t wpen10 : 1; /* [10] */ + __IO uint32_t wpen11 : 1; /* [11] */ + __IO uint32_t wpen12 : 1; /* [12] */ + __IO uint32_t wpen13 : 1; /* [13] */ + __IO uint32_t wpen14 : 1; /* [14] */ + __IO uint32_t wpen15 : 1; /* [15] */ + __IO uint32_t wpseq : 1; /* [16] */ + __IO uint32_t reserved1 : 15;/* [31:17] */ + } wpr_bit; + }; + + /** + * @brief gpio muxl register, offset:0x20 + */ + union + { + __IO uint32_t muxl; + struct + { + __IO uint32_t muxl0 : 4; /* [3:0] */ + __IO uint32_t muxl1 : 4; /* [7:4] */ + __IO uint32_t muxl2 : 4; /* [11:8] */ + __IO uint32_t muxl3 : 4; /* [15:12] */ + __IO uint32_t muxl4 : 4; /* [19:16] */ + __IO uint32_t muxl5 : 4; /* [23:20] */ + __IO uint32_t muxl6 : 4; /* [27:24] */ + __IO uint32_t muxl7 : 4; /* [31:28] */ + } muxl_bit; + }; + + /** + * @brief gpio muxh register, offset:0x24 + */ + union + { + __IO uint32_t muxh; + struct + { + __IO uint32_t muxh8 : 4; /* [3:0] */ + __IO uint32_t muxh9 : 4; /* [7:4] */ + __IO uint32_t muxh10 : 4; /* [11:8] */ + __IO uint32_t muxh11 : 4; /* [15:12] */ + __IO uint32_t muxh12 : 4; /* [19:16] */ + __IO uint32_t muxh13 : 4; /* [23:20] */ + __IO uint32_t muxh14 : 4; /* [27:24] */ + __IO uint32_t muxh15 : 4; /* [31:28] */ + } muxh_bit; + }; + + /** + * @brief gpio clr register, offset:0x28 + */ + union + { + __IO uint32_t clr; + struct + { + __IO uint32_t iocb0 : 1; /* [0] */ + __IO uint32_t iocb1 : 1; /* [1] */ + __IO uint32_t iocb2 : 1; /* [2] */ + __IO uint32_t iocb3 : 1; /* [3] */ + __IO uint32_t iocb4 : 1; /* [4] */ + __IO uint32_t iocb5 : 1; /* [5] */ + __IO uint32_t iocb6 : 1; /* [6] */ + __IO uint32_t iocb7 : 1; /* [7] */ + __IO uint32_t iocb8 : 1; /* [8] */ + __IO uint32_t iocb9 : 1; /* [9] */ + __IO uint32_t iocb10 : 1; /* [10] */ + __IO uint32_t iocb11 : 1; /* [11] */ + __IO uint32_t iocb12 : 1; /* [12] */ + __IO uint32_t iocb13 : 1; /* [13] */ + __IO uint32_t iocb14 : 1; /* [14] */ + __IO uint32_t iocb15 : 1; /* [15] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } clr_bit; + }; + + /** + * @brief gpio reserved1 register, offset:0x2C~0x38 + */ + __IO uint32_t reserved1[4]; + + /** + * @brief gpio hdrv register, offset:0x3C + */ + union + { + __IO uint32_t hdrv; + struct + { + __IO uint32_t hdrv0 : 1; /* [0] */ + __IO uint32_t hdrv1 : 1; /* [1] */ + __IO uint32_t hdrv2 : 1; /* [2] */ + __IO uint32_t hdrv3 : 1; /* [3] */ + __IO uint32_t hdrv4 : 1; /* [4] */ + __IO uint32_t hdrv5 : 1; /* [5] */ + __IO uint32_t hdrv6 : 1; /* [6] */ + __IO uint32_t hdrv7 : 1; /* [7] */ + __IO uint32_t hdrv8 : 1; /* [8] */ + __IO uint32_t hdrv9 : 1; /* [9] */ + __IO uint32_t hdrv10 : 1; /* [10] */ + __IO uint32_t hdrv11 : 1; /* [11] */ + __IO uint32_t hdrv12 : 1; /* [12] */ + __IO uint32_t hdrv13 : 1; /* [13] */ + __IO uint32_t hdrv14 : 1; /* [14] */ + __IO uint32_t hdrv15 : 1; /* [15] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } hdrv_bit; + }; + +} gpio_type; + +/** + * @} + */ + +#define GPIOA ((gpio_type *) GPIOA_BASE) +#define GPIOB ((gpio_type *) GPIOB_BASE) +#define GPIOC ((gpio_type *) GPIOC_BASE) +#define GPIOD ((gpio_type *) GPIOD_BASE) +#define GPIOF ((gpio_type *) GPIOF_BASE) + + +/** @defgroup GPIO_exported_functions + * @{ + */ + +void gpio_reset(gpio_type *gpio_x); +void gpio_init(gpio_type *gpio_x, gpio_init_type *gpio_init_struct); +void gpio_default_para_init(gpio_init_type *gpio_init_struct); +flag_status gpio_input_data_bit_read(gpio_type *gpio_x, uint16_t pins); +uint16_t gpio_input_data_read(gpio_type *gpio_x); +flag_status gpio_output_data_bit_read(gpio_type *gpio_x, uint16_t pins); +uint16_t gpio_output_data_read(gpio_type *gpio_x); +void gpio_bits_set(gpio_type *gpio_x, uint16_t pins); +void gpio_bits_reset(gpio_type *gpio_x, uint16_t pins); +void gpio_bits_write(gpio_type *gpio_x, uint16_t pins, confirm_state bit_state); +void gpio_port_write(gpio_type *gpio_x, uint16_t port_value); +void gpio_pin_wp_config(gpio_type *gpio_x, uint16_t pins); +void gpio_pins_huge_driven_config(gpio_type *gpio_x, uint16_t pins, confirm_state new_state); +void gpio_pin_mux_config(gpio_type *gpio_x, gpio_pins_source_type gpio_pin_source, gpio_mux_sel_type gpio_mux); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_i2c.h b/libraries/drivers/inc/at32f425_i2c.h new file mode 100644 index 0000000..5516608 --- /dev/null +++ b/libraries/drivers/inc/at32f425_i2c.h @@ -0,0 +1,477 @@ +/** + ************************************************************************** + * @file at32f425_i2c.h + * @brief at32f425 i2c header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_I2C_H +#define __AT32F425_I2C_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/** + * @brief maximum number of single transfers + */ +#define MAX_TRANSFER_CNT 255 /*!< maximum number of single transfers */ + +/** @defgroup I2C_interrupts_definition + * @brief i2c interrupt + * @{ + */ + +#define I2C_TD_INT ((uint32_t)0x00000002) /*!< i2c transmit data interrupt */ +#define I2C_RD_INT ((uint32_t)0x00000004) /*!< i2c receive data interrupt */ +#define I2C_ADDR_INT ((uint32_t)0x00000008) /*!< i2c address match interrupt */ +#define I2C_ACKFIAL_INT ((uint32_t)0x00000010) /*!< i2c ack fail interrupt */ +#define I2C_STOP_INT ((uint32_t)0x00000020) /*!< i2c stop detect interrupt */ +#define I2C_TDC_INT ((uint32_t)0x00000040) /*!< i2c transmit data complete interrupt */ +#define I2C_ERR_INT ((uint32_t)0x00000080) /*!< i2c bus error interrupt */ + +/** + * @} + */ + +/** @defgroup I2C_flags_definition + * @brief i2c flag + * @{ + */ + +#define I2C_TDBE_FLAG ((uint32_t)0x00000001) /*!< i2c transmit data buffer empty flag */ +#define I2C_TDIS_FLAG ((uint32_t)0x00000002) /*!< i2c send interrupt status */ +#define I2C_RDBF_FLAG ((uint32_t)0x00000004) /*!< i2c receive data buffer full flag */ +#define I2C_ADDRF_FLAG ((uint32_t)0x00000008) /*!< i2c 0~7 bit address match flag */ +#define I2C_ACKFAIL_FLAG ((uint32_t)0x00000010) /*!< i2c acknowledge failure flag */ +#define I2C_STOPF_FLAG ((uint32_t)0x00000020) /*!< i2c stop condition generation complete flag */ +#define I2C_TDC_FLAG ((uint32_t)0x00000040) /*!< i2c transmit data complete flag */ +#define I2C_TCRLD_FLAG ((uint32_t)0x00000080) /*!< i2c transmission is complete, waiting to load data */ +#define I2C_BUSERR_FLAG ((uint32_t)0x00000100) /*!< i2c bus error flag */ +#define I2C_ARLOST_FLAG ((uint32_t)0x00000200) /*!< i2c arbitration lost flag */ +#define I2C_OUF_FLAG ((uint32_t)0x00000400) /*!< i2c overflow or underflow flag */ +#define I2C_PECERR_FLAG ((uint32_t)0x00000800) /*!< i2c pec receive error flag */ +#define I2C_TMOUT_FLAG ((uint32_t)0x00001000) /*!< i2c smbus timeout flag */ +#define I2C_ALERTF_FLAG ((uint32_t)0x00002000) /*!< i2c smbus alert flag */ +#define I2C_BUSYF_FLAG ((uint32_t)0x00008000) /*!< i2c bus busy flag transmission mode */ +#define I2C_SDIR_FLAG ((uint32_t)0x00010000) /*!< i2c slave data transmit direction */ + +/** + * @} + */ + +/** @defgroup I2C_exported_types + * @{ + */ + +/** + * @brief i2c smbus mode set + */ +typedef enum +{ + I2C_SMBUS_MODE_DEVICE = 0x00, /*!< smbus device mode */ + I2C_SMBUS_MODE_HOST = 0x01 /*!< smbus host mode */ +} i2c_smbus_mode_type; + +/** + * @brief i2c address mode + */ +typedef enum +{ + I2C_ADDRESS_MODE_7BIT = 0x00, /*!< 7bit address mode */ + I2C_ADDRESS_MODE_10BIT = 0x01 /*!< 10bit address mode */ +} i2c_address_mode_type; + +/** + * @brief i2c transfer direction + */ +typedef enum +{ + I2C_DIR_TRANSMIT = 0x00, /*!< master request a write transfer */ + I2C_DIR_RECEIVE = 0x01 /*!< master request a read transfer */ +} i2c_transfer_dir_type; + +/** + * @brief i2c dma requests direction + */ +typedef enum +{ + I2C_DMA_REQUEST_TX = 0x00, /*!< dma transmit request */ + I2C_DMA_REQUEST_RX = 0x01 /*!< dma receive request */ +} i2c_dma_request_type; + +/** + * @brief i2c smbus alert pin set + */ +typedef enum +{ + I2C_SMBUS_ALERT_HIGH = 0x00, /*!< smbus alert pin set high */ + I2C_SMBUS_ALERT_LOW = 0x01 /*!< smbus alert pin set low */ +} i2c_smbus_alert_set_type; + +/** + * @brief i2c clock timeout detection mode + */ +typedef enum +{ + I2C_TIMEOUT_DETCET_LOW = 0x00, /*!< detect low level timeout */ + I2C_TIMEOUT_DETCET_HIGH = 0x01 /*!< detect high level timeout */ +} i2c_timeout_detcet_type; + +/** + * @brief i2c own address2 mask + */ +typedef enum +{ + I2C_ADDR2_NOMASK = 0x00, /*!< compare bit [7:1] */ + I2C_ADDR2_MASK01 = 0x01, /*!< only compare bit [7:2] */ + I2C_ADDR2_MASK02 = 0x02, /*!< only compare bit [7:3] */ + I2C_ADDR2_MASK03 = 0x03, /*!< only compare bit [7:4] */ + I2C_ADDR2_MASK04 = 0x04, /*!< only compare bit [7:5] */ + I2C_ADDR2_MASK05 = 0x05, /*!< only compare bit [7:6] */ + I2C_ADDR2_MASK06 = 0x06, /*!< only compare bit [7] */ + I2C_ADDR2_MASK07 = 0x07 /*!< response all addresses other than those reserved for i2c */ +} i2c_addr2_mask_type; + +/** + * @brief i2c reload end mode + */ +typedef enum +{ + I2C_AUTO_STOP_MODE = 0x02000000, /*!< auto generate stop mode */ + I2C_SOFT_STOP_MODE = 0x00000000, /*!< soft generate stop mode */ + I2C_RELOAD_MODE = 0x01000000 /*!< reload mode */ +} i2c_reload_stop_mode_type; + +/** + * @brief i2c start mode + */ +typedef enum +{ + I2C_WITHOUT_START = 0x00000000, /*!< transfer data without start condition */ + I2C_GEN_START_READ = 0x00002400, /*!< read data and generate start */ + I2C_GEN_START_WRITE = 0x00002000 /*!< send data and generate start */ +} i2c_start_mode_type; + +/** + * @brief type define i2c register all + */ +typedef struct +{ + /** + * @brief i2c ctrl1 register, offset:0x00 + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t i2cen : 1; /* [0] */ + __IO uint32_t tdien : 1; /* [1] */ + __IO uint32_t rdien : 1; /* [2] */ + __IO uint32_t addrien : 1; /* [3] */ + __IO uint32_t ackfailien : 1; /* [4] */ + __IO uint32_t stopien : 1; /* [5] */ + __IO uint32_t tdcien : 1; /* [6] */ + __IO uint32_t errien : 1; /* [7] */ + __IO uint32_t dflt : 4; /* [11:8] */ + __IO uint32_t reserved1 : 2; /* [13:12] */ + __IO uint32_t dmaten : 1; /* [14] */ + __IO uint32_t dmaren : 1; /* [15] */ + __IO uint32_t sctrl : 1; /* [16] */ + __IO uint32_t stretch : 1; /* [17] */ + __IO uint32_t reserved2 : 1; /* [18] */ + __IO uint32_t gcaen : 1; /* [19] */ + __IO uint32_t haddren : 1; /* [20] */ + __IO uint32_t devaddren : 1; /* [21] */ + __IO uint32_t smbalert : 1; /* [22] */ + __IO uint32_t pecen : 1; /* [23] */ + __IO uint32_t reserved3 : 8; /* [31:24] */ + } ctrl1_bit; + }; + + /** + * @brief i2c ctrl2 register, offset:0x04 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t saddr : 10;/* [9:0] */ + __IO uint32_t dir : 1; /* [10] */ + __IO uint32_t addr10 : 1; /* [11] */ + __IO uint32_t readh10 : 1; /* [12] */ + __IO uint32_t genstart : 1; /* [13] */ + __IO uint32_t genstop : 1; /* [14] */ + __IO uint32_t nacken : 1; /* [15] */ + __IO uint32_t cnt : 8; /* [23:16] */ + __IO uint32_t rlden : 1; /* [24] */ + __IO uint32_t astopen : 1; /* [25] */ + __IO uint32_t pecten : 1; /* [26] */ + __IO uint32_t reserved1 : 5; /* [31:27] */ + } ctrl2_bit; + }; + + /** + * @brief i2c oaddr1 register, offset:0x08 + */ + union + { + __IO uint32_t oaddr1; + struct + { + __IO uint32_t addr1 : 10;/* [9:0] */ + __IO uint32_t addr1mode : 1; /* [10] */ + __IO uint32_t reserved1 : 4; /* [14:11] */ + __IO uint32_t addr1en : 1; /* [15] */ + __IO uint32_t reserved2 : 16;/* [31:16] */ + } oaddr1_bit; + }; + + /** + * @brief i2c oaddr2 register, offset:0x0c + */ + union + { + __IO uint32_t oaddr2; + struct + { + __IO uint32_t reserved1 : 1; /* [0] */ + __IO uint32_t addr2 : 7; /* [7:1] */ + __IO uint32_t addr2mask : 3; /* [10:8] */ + __IO uint32_t reserved2 : 4; /* [14:11] */ + __IO uint32_t addr2en : 1; /* [15] */ + __IO uint32_t reserved3 : 16;/* [31:16] */ + } oaddr2_bit; + }; + + /** + * @brief i2c clkctrl register, offset:0x10 + */ + union + { + __IO uint32_t clkctrl; + struct + { + __IO uint32_t scll : 8; /* [7:0] */ + __IO uint32_t sclh : 8; /* [15:8] */ + __IO uint32_t sdad : 4; /* [19:16] */ + __IO uint32_t scld : 4; /* [23:20] */ + __IO uint32_t divh : 4; /* [27:24] */ + __IO uint32_t divl : 4; /* [31:28] */ + } clkctrl_bit; + }; + + /** + * @brief i2c timeout register, offset:0x14 + */ + union + { + __IO uint32_t timeout; + struct + { + __IO uint32_t totime : 12;/* [11:0] */ + __IO uint32_t tomode : 1; /* [12] */ + __IO uint32_t reserved1 : 2; /* [14:13] */ + __IO uint32_t toen : 1; /* [15] */ + __IO uint32_t exttime : 12;/* [27:16] */ + __IO uint32_t reserved2 : 3; /* [30:28] */ + __IO uint32_t exten : 1; /* [31] */ + } timeout_bit; + }; + + /** + * @brief i2c sts register, offset:0x18 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t tdbe : 1; /* [0] */ + __IO uint32_t tdis : 1; /* [1] */ + __IO uint32_t rdbf : 1; /* [2] */ + __IO uint32_t addrf : 1; /* [3] */ + __IO uint32_t ackfail : 1; /* [4] */ + __IO uint32_t stopf : 1; /* [5] */ + __IO uint32_t tdc : 1; /* [6] */ + __IO uint32_t tcrld : 1; /* [7] */ + __IO uint32_t buserr : 1; /* [8] */ + __IO uint32_t arlost : 1; /* [9] */ + __IO uint32_t ouf : 1; /* [10] */ + __IO uint32_t pecerr : 1; /* [11] */ + __IO uint32_t tmout : 1; /* [12] */ + __IO uint32_t alertf : 1; /* [13] */ + __IO uint32_t reserved1 : 1; /* [14] */ + __IO uint32_t busyf : 1; /* [15] */ + __IO uint32_t sdir : 1; /* [16] */ + __IO uint32_t addr : 7; /* [23:17] */ + __IO uint32_t reserved2 : 8; /* [31:24] */ + } sts_bit; + }; + + /** + * @brief i2c clr register, offset:0x1c + */ + union + { + __IO uint32_t clr; + struct + { + __IO uint32_t reserved1 : 3; /* [2:0] */ + __IO uint32_t addrc : 1; /* [3] */ + __IO uint32_t ackfailc : 1; /* [4] */ + __IO uint32_t stopc : 1; /* [5] */ + __IO uint32_t reserved2 : 2; /* [6:7] */ + __IO uint32_t buserrc : 1; /* [8] */ + __IO uint32_t arlostc : 1; /* [9] */ + __IO uint32_t oufc : 1; /* [10] */ + __IO uint32_t pecerrc : 1; /* [11] */ + __IO uint32_t tmoutc : 1; /* [12] */ + __IO uint32_t alertc : 1; /* [13] */ + __IO uint32_t reserved3 : 18;/* [31:14] */ + } clr_bit; + }; + + /** + * @brief i2c pec register, offset:0x20 + */ + union + { + __IO uint32_t pec; + struct + { + __IO uint32_t pecval : 8; /* [7:0] */ + __IO uint32_t reserved1 : 24;/* [31:8] */ + } pec_bit; + }; + + /** + * @brief i2c rxdt register, offset:0x20 + */ + union + { + __IO uint32_t rxdt; + struct + { + __IO uint32_t dt : 8; /* [7:0] */ + __IO uint32_t reserved1 : 24;/* [31:8] */ + } rxdt_bit; + }; + + /** + * @brief i2c txdt register, offset:0x20 + */ + union + { + __IO uint32_t txdt; + struct + { + __IO uint32_t dt : 8; /* [7:0] */ + __IO uint32_t reserved1 : 24;/* [31:8] */ + } txdt_bit; + }; + +} i2c_type; + +/** + * @} + */ + +#define I2C1 ((i2c_type *) I2C1_BASE) +#define I2C2 ((i2c_type *) I2C2_BASE) + +/** @defgroup I2C_exported_functions + * @{ + */ + +void i2c_reset(i2c_type *i2c_x); +void i2c_init(i2c_type *i2c_x, uint8_t dfilters, uint32_t clk); +void i2c_own_address1_set(i2c_type *i2c_x, i2c_address_mode_type mode, uint16_t address); +void i2c_own_address2_set(i2c_type *i2c_x, uint8_t address, i2c_addr2_mask_type mask); +void i2c_own_address2_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_smbus_enable(i2c_type *i2c_x, i2c_smbus_mode_type mode, confirm_state new_state); +void i2c_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_clock_stretch_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_ack_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_addr10_mode_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_transfer_addr_set(i2c_type *i2c_x, uint16_t address); +uint16_t i2c_transfer_addr_get(i2c_type *i2c_x); +void i2c_transfer_dir_set(i2c_type *i2c_x, i2c_transfer_dir_type i2c_direction); +i2c_transfer_dir_type i2c_transfer_dir_get(i2c_type *i2c_x); +uint8_t i2c_matched_addr_get(i2c_type *i2c_x); +void i2c_auto_stop_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_reload_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_cnt_set(i2c_type *i2c_x, uint8_t cnt); +void i2c_addr10_header_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_general_call_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_smbus_alert_set(i2c_type *i2c_x, i2c_smbus_alert_set_type level); +void i2c_slave_data_ctrl_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_pec_calculate_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_pec_transmit_enable(i2c_type *i2c_x, confirm_state new_state); +uint8_t i2c_pec_value_get(i2c_type *i2c_x); +void i2c_timeout_set(i2c_type *i2c_x, uint16_t timeout); +void i2c_timeout_detcet_set(i2c_type *i2c_x, i2c_timeout_detcet_type mode); +void i2c_timeout_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_ext_timeout_set(i2c_type *i2c_x, uint16_t timeout); +void i2c_ext_timeout_enable(i2c_type *i2c_x, confirm_state new_state); +void i2c_interrupt_enable(i2c_type *i2c_x, uint32_t source, confirm_state new_state); +flag_status i2c_interrupt_get(i2c_type *i2c_x, uint16_t source); +void i2c_dma_enable(i2c_type *i2c_x, i2c_dma_request_type dma_req, confirm_state new_state); +void i2c_transmit_set(i2c_type *i2c_x, uint16_t address, uint8_t cnt, i2c_reload_stop_mode_type rld_stop, i2c_start_mode_type start); +void i2c_start_generate(i2c_type *i2c_x); +void i2c_stop_generate(i2c_type *i2c_x); +void i2c_data_send(i2c_type *i2c_x, uint8_t data); +uint8_t i2c_data_receive(i2c_type *i2c_x); +flag_status i2c_flag_get(i2c_type *i2c_x, uint32_t flag); +flag_status i2c_interrupt_flag_get(i2c_type *i2c_x, uint32_t flag); +void i2c_flag_clear(i2c_type *i2c_x, uint32_t flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_misc.h b/libraries/drivers/inc/at32f425_misc.h new file mode 100644 index 0000000..7876e8f --- /dev/null +++ b/libraries/drivers/inc/at32f425_misc.h @@ -0,0 +1,123 @@ +/** + ************************************************************************** + * @file at32f425_misc.h + * @brief at32f425 misc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_MISC_H +#define __AT32F425_MISC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup MISC + * @{ + */ + +/** @defgroup MISC_vector_table_base_address + * @{ + */ + +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< nvic vector table based ram address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< nvic vector table based flash address */ + +/** + * @} + */ + +/** @defgroup MISC_exported_types + * @{ + */ + +/** + * @brief nvic interrupt priority group + */ +typedef enum +{ + NVIC_PRIORITY_GROUP_0 = ((uint32_t)0x7), /*!< 0 bits for preemption priority, 4 bits for subpriority */ + NVIC_PRIORITY_GROUP_1 = ((uint32_t)0x6), /*!< 1 bits for preemption priority, 3 bits for subpriority */ + NVIC_PRIORITY_GROUP_2 = ((uint32_t)0x5), /*!< 2 bits for preemption priority, 2 bits for subpriority */ + NVIC_PRIORITY_GROUP_3 = ((uint32_t)0x4), /*!< 3 bits for preemption priority, 1 bits for subpriority */ + NVIC_PRIORITY_GROUP_4 = ((uint32_t)0x3) /*!< 4 bits for preemption priority, 0 bits for subpriority */ +} nvic_priority_group_type; + +/** + * @brief nvic low power mode + */ +typedef enum +{ + NVIC_LP_SLEEPONEXIT = 0x02, /*!< enable sleep-on-exit feature */ + NVIC_LP_SLEEPDEEP = 0x04, /*!< enable sleep-deep output signal when entering sleep mode */ + NVIC_LP_SEVONPEND = 0x10 /*!< send event on pending */ +} nvic_lowpower_mode_type; + +/** + * @brief systick clock source + */ +typedef enum +{ + SYSTICK_CLOCK_SOURCE_AHBCLK_DIV8 = ((uint32_t)0x00000000), /*!< systick clock source from core clock div8 */ + SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV = ((uint32_t)0x00000004) /*!< systick clock source from core clock */ +} systick_clock_source_type; + +/** + * @} + */ + +/** @defgroup MISC_exported_functions + * @{ + */ + +void nvic_system_reset(void); +void nvic_irq_enable(IRQn_Type irqn, uint32_t preempt_priority, uint32_t sub_priority); +void nvic_irq_disable(IRQn_Type irqn); +void nvic_priority_group_config(nvic_priority_group_type priority_group); +void nvic_vector_table_set(uint32_t base, uint32_t offset); +void nvic_lowpower_mode_config(nvic_lowpower_mode_type lp_mode, confirm_state new_state); +void systick_clock_source_config(systick_clock_source_type source); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_pwc.h b/libraries/drivers/inc/at32f425_pwc.h new file mode 100644 index 0000000..907a0ac --- /dev/null +++ b/libraries/drivers/inc/at32f425_pwc.h @@ -0,0 +1,218 @@ +/** + ************************************************************************** + * @file at32f425_pwc.h + * @brief at32f425 pwc header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_PWC_H +#define __AT32F425_PWC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup PWC + * @{ + */ + +/** @defgroup PWC_flags_definition + * @brief pwc flag + * @{ + */ + +#define PWC_WAKEUP_FLAG ((uint32_t)0x00000001) /*!< wakeup flag */ +#define PWC_STANDBY_FLAG ((uint32_t)0x00000002) /*!< standby flag */ +#define PWC_PVM_OUTPUT_FLAG ((uint32_t)0x00000004) /*!< pvm output flag */ + +/** + * @} + */ + +/** + * @brief pwc wakeup pin num definition + */ +#define PWC_WAKEUP_PIN_1 ((uint32_t)0x00000100) /*!< standby wake-up pin1(pa0) */ +#define PWC_WAKEUP_PIN_2 ((uint32_t)0x00000200) /*!< standby wake-up pin2(pc13) */ +#define PWC_WAKEUP_PIN_4 ((uint32_t)0x00000800) /*!< standby wake-up pin4(pa2) */ +#define PWC_WAKEUP_PIN_5 ((uint32_t)0x00001000) /*!< standby wake-up pin5(pc5) */ +#define PWC_WAKEUP_PIN_6 ((uint32_t)0x00002000) /*!< standby wake-up pin6(pb5) */ +#define PWC_WAKEUP_PIN_7 ((uint32_t)0x00004000) /*!< standby wake-up pin7(pb15) */ + +/** @defgroup PWC_exported_types + * @{ + */ + +/** + * @brief pwc pvm voltage type + */ +typedef enum +{ + PWC_PVM_VOLTAGE_2V3 = 0x01, /*!< power voltage monitoring boundary 2.3v */ + PWC_PVM_VOLTAGE_2V4 = 0x02, /*!< power voltage monitoring boundary 2.4v */ + PWC_PVM_VOLTAGE_2V5 = 0x03, /*!< power voltage monitoring boundary 2.5v */ + PWC_PVM_VOLTAGE_2V6 = 0x04, /*!< power voltage monitoring boundary 2.6v */ + PWC_PVM_VOLTAGE_2V7 = 0x05, /*!< power voltage monitoring boundary 2.7v */ + PWC_PVM_VOLTAGE_2V8 = 0x06, /*!< power voltage monitoring boundary 2.8v */ + PWC_PVM_VOLTAGE_2V9 = 0x07 /*!< power voltage monitoring boundary 2.9v */ +} pwc_pvm_voltage_type; + +/** + * @brief pwc sleep enter type + */ +typedef enum +{ + PWC_SLEEP_ENTER_WFI = 0x00, /*!< use wfi enter sleep mode */ + PWC_SLEEP_ENTER_WFE = 0x01 /*!< use wfe enter sleep mode */ +} pwc_sleep_enter_type; + +/** + * @brief pwc deep sleep enter type + */ +typedef enum +{ + PWC_DEEP_SLEEP_ENTER_WFI = 0x00, /*!< use wfi enter deepsleep mode */ + PWC_DEEP_SLEEP_ENTER_WFE = 0x01 /*!< use wfe enter deepsleep mode */ +} pwc_deep_sleep_enter_type; + +/** + * @brief pwc regulator type + */ +typedef enum +{ + PWC_REGULATOR_ON = 0x00, /*!< voltage regulator state on when deepsleep mode */ + PWC_REGULATOR_LOW_POWER = 0x01, /*!< voltage regulator state low power when deepsleep mode */ + PWC_REGULATOR_EXTRA_LOW_POWER = 0x02 /*!< voltage regulator state extra low power when deepsleep mode */ +} pwc_regulator_type; + +/** + * @brief type define pwc register all + */ +typedef struct +{ + /** + * @brief pwc ctrl register, offset:0x00 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t vrsel : 1; /* [0] */ + __IO uint32_t lpsel : 1; /* [1] */ + __IO uint32_t clswef : 1; /* [2] */ + __IO uint32_t clsef : 1; /* [3] */ + __IO uint32_t pvmen : 1; /* [4] */ + __IO uint32_t pvmsel : 3; /* [7:5] */ + __IO uint32_t bpwen : 1; /* [8] */ + __IO uint32_t reserved1 : 23;/* [31:9] */ + } ctrl_bit; + }; + + /** + * @brief pwc ctrlsts register, offset:0x04 + */ + union + { + __IO uint32_t ctrlsts; + struct + { + __IO uint32_t swef : 1; /* [0] */ + __IO uint32_t sef : 1; /* [1] */ + __IO uint32_t pvmof : 1; /* [2] */ + __IO uint32_t reserved1 : 5; /* [7:3] */ + __IO uint32_t swpen1 : 1; /* [8] */ + __IO uint32_t swpen2 : 1; /* [9] */ + __IO uint32_t reserved2 : 3; /* [12:10] */ + __IO uint32_t swpen6 : 1; /* [13] */ + __IO uint32_t swpen7 : 1; /* [14] */ + __IO uint32_t reserved3 : 17;/* [31:15] */ + } ctrlsts_bit; + }; + + /** + * @brief pwc reserved register, offset:0x08~0x1C + */ + __IO uint32_t reserved1[6]; + + /** + * @brief pwc ctrl2 register, offset:0x20 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t reserved1 : 5;/* [4:0] */ + __IO uint32_t vrexlpen : 1; /* [5] */ + __IO uint32_t reserved2 : 26;/* [31:6] */ + } ctrl2_bit; + }; + +} pwc_type; + +/** + * @} + */ + +#define PWC ((pwc_type *) PWC_BASE) + +/** @defgroup PWC_exported_functions + * @{ + */ + +void pwc_reset(void); +void pwc_battery_powered_domain_access(confirm_state new_state); +void pwc_pvm_level_select(pwc_pvm_voltage_type pvm_voltage); +void pwc_power_voltage_monitor_enable(confirm_state new_state); +void pwc_wakeup_pin_enable(uint32_t pin_num, confirm_state new_state); +void pwc_flag_clear(uint32_t pwc_flag); +flag_status pwc_flag_get(uint32_t pwc_flag); +void pwc_sleep_mode_enter(pwc_sleep_enter_type pwc_sleep_enter); +void pwc_deep_sleep_mode_enter(pwc_deep_sleep_enter_type pwc_deep_sleep_enter); +void pwc_voltage_regulate_set(pwc_regulator_type pwc_regulator); +void pwc_standby_mode_enter(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_scfg.h b/libraries/drivers/inc/at32f425_scfg.h new file mode 100644 index 0000000..fc124fc --- /dev/null +++ b/libraries/drivers/inc/at32f425_scfg.h @@ -0,0 +1,292 @@ +/** + ************************************************************************** + * @file at32f425_scfg.h + * @brief at32f425 system config header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_SCFG_H +#define __AT32F425_SCFG_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup SCFG + * @{ + */ + +#define SCFG_REG(value) PERIPH_REG(SCFG_CMP_BASE, value) +#define SCFG_REG_BIT(value) PERIPH_REG_BIT(value) + +/** @defgroup SCFG_exported_types + * @{ + */ + +/** + * @brief scfg ultra high sourcing/sinking strength pins type + */ +typedef enum +{ + SCFG_ULTRA_DRIVEN_PB14 = 0x00010000, + SCFG_ULTRA_DRIVEN_PB13 = 0x00020000, + SCFG_ULTRA_DRIVEN_PB9 = 0x00040000, + SCFG_ULTRA_DRIVEN_PB8 = 0x00080000, +} scfg_ultra_driven_pins_type; + +/** + * @brief scfg infrared modulation signal source selecting type + */ +typedef enum +{ + SCFG_IR_SOURCE_TMR16 = 0x00 /* infrared signal source select tmr16 */ +} scfg_ir_source_type; + +/** + * @brief scfg pa11 pa12 pin remap type + */ +typedef enum +{ + SCFG_PA11PA12_NO_REMAP = 0x00, /* pa11 pa12 pin no remap */ + SCFG_PA11PA12_TO_PA9PA10 = 0x01, /* pa11 pa12 pin remap pa9 pa10*/ +} scfg_pa11pa12_remap_type; + +/** + * @brief scfg infrared output polarity selecting type + */ +typedef enum +{ + SCFG_IR_POLARITY_NO_AFFECTE = 0x00, /* infrared output polarity no affecte */ + SCFG_IR_POLARITY_REVERSE = 0x01 /* infrared output polarity reverse */ +} scfg_ir_polarity_type; + +/** + * @brief scfg memory address mapping selecting type + */ +typedef enum +{ + SCFG_MEM_MAP_MAIN_MEMORY = 0x00, /* 0x00000000 address mapping from main memory */ + SCFG_MEM_MAP_BOOT_MEMORY = 0x01, /* 0x00000000 address mapping from boot memory */ + SCFG_MEM_MAP_INTERNAL_SRAM = 0x03, /* 0x00000000 address mapping from internal sram */ +} scfg_mem_map_type; + +/** + * @brief scfg i2s full duplex type + */ +typedef enum +{ + SCFG_FULL_DUPLEX_I2S_NONE = 0x00, /* no i2s full duplex */ + SCFG_FULL_DUPLEX_I2S1_I2S3 = 0x01, /* i2s full duplex with i2s1 and i2s3 */ + SCFG_FULL_DUPLEX_I2S2_I2S3 = 0x02, /* i2s full duplex with i2s2 and i2s3 */ + SCFG_FULL_DUPLEX_I2S1_I2S2 = 0x03, /* i2s full duplex with i2s1 and i2s2 */ +} scfg_i2s_type; + +/** + * @brief scfg pin source type + */ +typedef enum +{ + SCFG_PINS_SOURCE0 = 0x00, + SCFG_PINS_SOURCE1 = 0x01, + SCFG_PINS_SOURCE2 = 0x02, + SCFG_PINS_SOURCE3 = 0x03, + SCFG_PINS_SOURCE4 = 0x04, + SCFG_PINS_SOURCE5 = 0x05, + SCFG_PINS_SOURCE6 = 0x06, + SCFG_PINS_SOURCE7 = 0x07, + SCFG_PINS_SOURCE8 = 0x08, + SCFG_PINS_SOURCE9 = 0x09, + SCFG_PINS_SOURCE10 = 0x0A, + SCFG_PINS_SOURCE11 = 0x0B, + SCFG_PINS_SOURCE12 = 0x0C, + SCFG_PINS_SOURCE13 = 0x0D, + SCFG_PINS_SOURCE14 = 0x0E, + SCFG_PINS_SOURCE15 = 0x0F +} scfg_pins_source_type; + +/** + * @brief gpio port source type + */ +typedef enum +{ + SCFG_PORT_SOURCE_GPIOA = 0x00, + SCFG_PORT_SOURCE_GPIOB = 0x01, + SCFG_PORT_SOURCE_GPIOC = 0x02, + SCFG_PORT_SOURCE_GPIOD = 0x03, + SCFG_PORT_SOURCE_GPIOF = 0x05, +} scfg_port_source_type; + +/** + * @brief type define system config register all + */ +typedef struct +{ + /** + * @brief scfg cfg1 register, offset:0x00 + */ + union + { + __IO uint32_t cfg1; + struct + { + __IO uint32_t mem_map_sel : 2; /* [1:0] */ + __IO uint32_t reserved1 : 2; /* [3:2] */ + __IO uint32_t pa11_12_rmp : 1; /* [4] */ + __IO uint32_t ir_pol : 1; /* [5] */ + __IO uint32_t ir_src_sel : 2; /* [7:6] */ + __IO uint32_t reserved2 : 8; /* [15:8] */ + __IO uint32_t pb14_uh : 1; /* [16] */ + __IO uint32_t pb13_uh : 1; /* [17] */ + __IO uint32_t pb9_uh : 1; /* [18] */ + __IO uint32_t pb8_uh : 1; /* [19] */ + __IO uint32_t reserved3 : 12;/* [31:20] */ + } cfg1_bit; + }; + + /** + * @brief scfg reserved1 register, offset:0x04 + */ + __IO uint32_t reserved1; + + /** + * @brief scfg exintc1 register, offset:0x08 + */ + union + { + __IO uint32_t exintc1; + struct + { + __IO uint32_t exint0 : 4; /* [3:0] */ + __IO uint32_t exint1 : 4; /* [7:4] */ + __IO uint32_t exint2 : 4; /* [11:8] */ + __IO uint32_t exint3 : 4; /* [15:12] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } exintc1_bit; + }; + + /** + * @brief scfg exintc2 register, offset:0x0C + */ + union + { + __IO uint32_t exintc2; + struct + { + __IO uint32_t exint4 : 4; /* [3:0] */ + __IO uint32_t exint5 : 4; /* [7:4] */ + __IO uint32_t exint6 : 4; /* [11:8] */ + __IO uint32_t exint7 : 4; /* [15:12] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } exintc2_bit; + }; + + /** + * @brief scfg exintc3 register, offset:0x10 + */ + union + { + __IO uint32_t exintc3; + struct + { + __IO uint32_t exint8 : 4; /* [3:0] */ + __IO uint32_t exint9 : 4; /* [7:4] */ + __IO uint32_t exint10 : 4; /* [11:8] */ + __IO uint32_t exint11 : 4; /* [15:12] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } exintc3_bit; + }; + + /** + * @brief scfg exintc4 register, offset:0x14 + */ + union + { + __IO uint32_t exintc4; + struct + { + __IO uint32_t exint12 : 4; /* [3:0] */ + __IO uint32_t exint13 : 4; /* [7:4] */ + __IO uint32_t exint14 : 4; /* [11:8] */ + __IO uint32_t exint15 : 4; /* [15:12] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } exintc4_bit; + }; + + /** + * @brief scfg cfg2 register, offset:0x18 + */ + union + { + __IO uint32_t cfg2; + struct + { + __IO uint32_t reserved1 : 2; /* [1:0] */ + __IO uint32_t pvm_lk : 1; /* [2] */ + __IO uint32_t reserved2 : 27;/* [29:3] */ + __IO uint32_t i2s_fd : 2; /* [31:30] */ + } cfg2_bit; + }; +} scfg_type; + +/** + * @} + */ + +#define SCFG ((scfg_type *) SCFG_BASE) + +/** @defgroup SCFG_exported_functions + * @{ + */ + +void scfg_reset(void); +void scfg_infrared_config(scfg_ir_source_type source, scfg_ir_polarity_type polarity); +scfg_mem_map_type scfg_mem_map_get(void); +void scfg_pa11pa12_pin_remap(scfg_pa11pa12_remap_type pin_remap); +void scfg_exint_line_config(scfg_port_source_type port_source, scfg_pins_source_type pin_source); +void scfg_pins_ultra_driven_enable(scfg_ultra_driven_pins_type value, confirm_state new_state); +void scfg_i2s_full_duplex_config(scfg_i2s_type i2s_full_duplex); +void scfg_pvm_lock_enable(confirm_state new_state); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_spi.h b/libraries/drivers/inc/at32f425_spi.h new file mode 100644 index 0000000..6249f42 --- /dev/null +++ b/libraries/drivers/inc/at32f425_spi.h @@ -0,0 +1,504 @@ +/** + ************************************************************************** + * @file at32f425_spi.h + * @brief at32f425 spi header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_SPI_H +#define __AT32F425_SPI_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup SPI + * @{ + */ + +/** + * @defgroup SPI_I2S_flags_definition + * @brief spi i2s flag + * @{ + */ + +#define SPI_I2S_RDBF_FLAG 0x0001 /*!< spi or i2s receive data buffer full flag */ +#define SPI_I2S_TDBE_FLAG 0x0002 /*!< spi or i2s transmit data buffer empty flag */ +#define I2S_ACS_FLAG 0x0004 /*!< i2s audio channel state flag */ +#define I2S_TUERR_FLAG 0x0008 /*!< i2s transmitter underload error flag */ +#define SPI_CCERR_FLAG 0x0010 /*!< spi crc calculation error flag */ +#define SPI_MMERR_FLAG 0x0020 /*!< spi master mode error flag */ +#define SPI_I2S_ROERR_FLAG 0x0040 /*!< spi or i2s receiver overflow error flag */ +#define SPI_I2S_BF_FLAG 0x0080 /*!< spi or i2s busy flag */ +#define SPI_CSPAS_FLAG 0x0100 /*!< spi cs pulse abnormal setting fiag */ + +/** + * @} + */ + +/** + * @defgroup SPI_I2S_interrupts_definition + * @brief spi i2s interrupt + * @{ + */ + +#define SPI_I2S_ERROR_INT 0x0020 /*!< error interrupt */ +#define SPI_I2S_RDBF_INT 0x0040 /*!< receive data buffer full interrupt */ +#define SPI_I2S_TDBE_INT 0x0080 /*!< transmit data buffer empty interrupt */ + +/** + * @} + */ + +/** @defgroup SPI_exported_types + * @{ + */ + +/** + * @brief spi frame bit num type + */ +typedef enum +{ + SPI_FRAME_8BIT = 0x00, /*!< 8-bit data frame format */ + SPI_FRAME_16BIT = 0x01 /*!< 16-bit data frame format */ +} spi_frame_bit_num_type; + +/** + * @brief spi master/slave mode type + */ +typedef enum +{ + SPI_MODE_SLAVE = 0x00, /*!< select as slave mode */ + SPI_MODE_MASTER = 0x01 /*!< select as master mode */ +} spi_master_slave_mode_type; + +/** + * @brief spi clock polarity (clkpol) type + */ +typedef enum +{ + SPI_CLOCK_POLARITY_LOW = 0x00, /*!< sck keeps low at idle state */ + SPI_CLOCK_POLARITY_HIGH = 0x01 /*!< sck keeps high at idle state */ +} spi_clock_polarity_type; + +/** + * @brief spi clock phase (clkpha) type + */ +typedef enum +{ + SPI_CLOCK_PHASE_1EDGE = 0x00, /*!< data capture start from the first clock edge */ + SPI_CLOCK_PHASE_2EDGE = 0x01 /*!< data capture start from the second clock edge */ +} spi_clock_phase_type; + +/** + * @brief spi cs mode type + */ +typedef enum +{ + SPI_CS_HARDWARE_MODE = 0x00, /*!< cs is hardware mode */ + SPI_CS_SOFTWARE_MODE = 0x01 /*!< cs is software mode */ +} spi_cs_mode_type; + +/** + * @brief spi master clock frequency division type + */ +typedef enum +{ + SPI_MCLK_DIV_2 = 0x00, /*!< master clock frequency division 2 */ + SPI_MCLK_DIV_3 = 0x0A, /*!< master clock frequency division 3 */ + SPI_MCLK_DIV_4 = 0x01, /*!< master clock frequency division 4 */ + SPI_MCLK_DIV_8 = 0x02, /*!< master clock frequency division 8 */ + SPI_MCLK_DIV_16 = 0x03, /*!< master clock frequency division 16 */ + SPI_MCLK_DIV_32 = 0x04, /*!< master clock frequency division 32 */ + SPI_MCLK_DIV_64 = 0x05, /*!< master clock frequency division 64 */ + SPI_MCLK_DIV_128 = 0x06, /*!< master clock frequency division 128 */ + SPI_MCLK_DIV_256 = 0x07, /*!< master clock frequency division 256 */ + SPI_MCLK_DIV_512 = 0x08, /*!< master clock frequency division 512 */ + SPI_MCLK_DIV_1024 = 0x09 /*!< master clock frequency division 1024 */ +} spi_mclk_freq_div_type; + +/** + * @brief spi transmit first bit (lsb/msb) type + */ +typedef enum +{ + SPI_FIRST_BIT_MSB = 0x00, /*!< the frame format is msb first */ + SPI_FIRST_BIT_LSB = 0x01 /*!< the frame format is lsb first */ +} spi_first_bit_type; + +/** + * @brief spi transmission mode type + */ +typedef enum +{ + SPI_TRANSMIT_FULL_DUPLEX = 0x00, /*!< dual line unidirectional full-duplex mode(slben = 0 and ora = 0) */ + SPI_TRANSMIT_SIMPLEX_RX = 0x01, /*!< dual line unidirectional simplex receive-only mode(slben = 0 and ora = 1) */ + SPI_TRANSMIT_HALF_DUPLEX_RX = 0x02, /*!< single line bidirectional half duplex mode-receiving(slben = 1 and slbtd = 0) */ + SPI_TRANSMIT_HALF_DUPLEX_TX = 0x03 /*!< single line bidirectional half duplex mode-transmitting(slben = 1 and slbtd = 1) */ +} spi_transmission_mode_type; + +/** + * @brief spi crc direction type + */ +typedef enum +{ + SPI_CRC_RX = 0x0014, /*!< crc direction is rx */ + SPI_CRC_TX = 0x0018 /*!< crc direction is tx */ +} spi_crc_direction_type; + +/** + * @brief spi single line bidirectional direction type + */ +typedef enum +{ + SPI_HALF_DUPLEX_DIRECTION_RX = 0x00, /*!< single line bidirectional half duplex mode direction: receive(slbtd = 0) */ + SPI_HALF_DUPLEX_DIRECTION_TX = 0x01 /*!< single line bidirectional half duplex mode direction: transmit(slbtd = 1) */ +} spi_half_duplex_direction_type; + +/** + * @brief spi software cs internal level type + */ +typedef enum +{ + SPI_SWCS_INTERNAL_LEVEL_LOW = 0x00, /*!< internal level low */ + SPI_SWCS_INTERNAL_LEVEL_HIGHT = 0x01 /*!< internal level high */ +} spi_software_cs_level_type; + +/** + * @brief i2s audio protocol type + */ +typedef enum +{ + I2S_AUDIO_PROTOCOL_PHILLIPS = 0x00, /*!< i2s philip standard */ + I2S_AUDIO_PROTOCOL_MSB = 0x01, /*!< msb-justified standard */ + I2S_AUDIO_PROTOCOL_LSB = 0x02, /*!< lsb-justified standard */ + I2S_AUDIO_PROTOCOL_PCM_SHORT = 0x03, /*!< pcm standard-short frame */ + I2S_AUDIO_PROTOCOL_PCM_LONG = 0x04 /*!< pcm standard-long frame */ +} i2s_audio_protocol_type; + +/** + * @brief i2s audio frequency type + */ +typedef enum +{ + I2S_AUDIO_FREQUENCY_DEFAULT = 2, /*!< i2s audio sampling frequency default */ + I2S_AUDIO_FREQUENCY_8K = 8000, /*!< i2s audio sampling frequency 8k */ + I2S_AUDIO_FREQUENCY_11_025K = 11025, /*!< i2s audio sampling frequency 11.025k */ + I2S_AUDIO_FREQUENCY_16K = 16000, /*!< i2s audio sampling frequency 16k */ + I2S_AUDIO_FREQUENCY_22_05K = 22050, /*!< i2s audio sampling frequency 22.05k */ + I2S_AUDIO_FREQUENCY_32K = 32000, /*!< i2s audio sampling frequency 32k */ + I2S_AUDIO_FREQUENCY_44_1K = 44100, /*!< i2s audio sampling frequency 44.1k */ + I2S_AUDIO_FREQUENCY_48K = 48000, /*!< i2s audio sampling frequency 48k */ + I2S_AUDIO_FREQUENCY_96K = 96000, /*!< i2s audio sampling frequency 96k */ + I2S_AUDIO_FREQUENCY_192K = 192000 /*!< i2s audio sampling frequency 192k */ +} i2s_audio_sampling_freq_type; + +/** + * @brief i2s data bit num and channel bit num type + */ +typedef enum +{ + I2S_DATA_16BIT_CHANNEL_16BIT = 0x01, /*!< 16-bit data packed in 16-bit channel frame */ + I2S_DATA_16BIT_CHANNEL_32BIT = 0x02, /*!< 16-bit data packed in 32-bit channel frame */ + I2S_DATA_24BIT_CHANNEL_32BIT = 0x03, /*!< 24-bit data packed in 32-bit channel frame */ + I2S_DATA_32BIT_CHANNEL_32BIT = 0x04 /*!< 32-bit data packed in 32-bit channel frame */ +} i2s_data_channel_format_type; + +/** + * @brief i2s operation mode type + */ +typedef enum +{ + I2S_MODE_SLAVE_TX = 0x00, /*!< slave transmission mode */ + I2S_MODE_SLAVE_RX = 0x01, /*!< slave reception mode */ + I2S_MODE_MASTER_TX = 0x02, /*!< master transmission mode */ + I2S_MODE_MASTER_RX = 0x03 /*!< master reception mode */ +} i2s_operation_mode_type; + +/** + * @brief i2s clock polarity type + */ +typedef enum +{ + I2S_CLOCK_POLARITY_LOW = 0x00, /*!< i2s clock steady state is low level */ + I2S_CLOCK_POLARITY_HIGH = 0x01 /*!< i2s clock steady state is high level */ +} i2s_clock_polarity_type; + +/** + * @brief spi init type + */ +typedef struct +{ + spi_transmission_mode_type transmission_mode; /*!< transmission mode selection */ + spi_master_slave_mode_type master_slave_mode; /*!< master or slave mode selection */ + spi_mclk_freq_div_type mclk_freq_division; /*!< master clock frequency division selection */ + spi_first_bit_type first_bit_transmission;/*!< transmit lsb or msb selection */ + spi_frame_bit_num_type frame_bit_num; /*!< frame bit num 8 or 16 bit selection */ + spi_clock_polarity_type clock_polarity; /*!< clock polarity selection */ + spi_clock_phase_type clock_phase; /*!< clock phase selection */ + spi_cs_mode_type cs_mode_selection; /*!< hardware or software cs mode selection */ +} spi_init_type; + +/** + * @brief i2s init type + */ +typedef struct +{ + i2s_operation_mode_type operation_mode; /*!< operation mode selection */ + i2s_audio_protocol_type audio_protocol; /*!< audio protocol selection */ + i2s_audio_sampling_freq_type audio_sampling_freq; /*!< audio frequency selection */ + i2s_data_channel_format_type data_channel_format; /*!< data bit num and channel bit num selection */ + i2s_clock_polarity_type clock_polarity; /*!< clock polarity selection */ + confirm_state mclk_output_enable; /*!< mclk_output selection */ +} i2s_init_type; + +/** + * @brief type define spi register all + */ +typedef struct +{ + + /** + * @brief spi ctrl1 register, offset:0x00 + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t clkpha : 1; /* [0] */ + __IO uint32_t clkpol : 1; /* [1] */ + __IO uint32_t msten : 1; /* [2] */ + __IO uint32_t mdiv_l : 3; /* [5:3] */ + __IO uint32_t spien : 1; /* [6] */ + __IO uint32_t ltf : 1; /* [7] */ + __IO uint32_t swcsil : 1; /* [8] */ + __IO uint32_t swcsen : 1; /* [9] */ + __IO uint32_t ora : 1; /* [10] */ + __IO uint32_t fbn : 1; /* [11] */ + __IO uint32_t ntc : 1; /* [12] */ + __IO uint32_t ccen : 1; /* [13] */ + __IO uint32_t slbtd : 1; /* [14] */ + __IO uint32_t slben : 1; /* [15] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } ctrl1_bit; + }; + + /** + * @brief spi ctrl2 register, offset:0x04 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t dmaren : 1; /* [0] */ + __IO uint32_t dmaten : 1; /* [1] */ + __IO uint32_t hwcsoe : 1; /* [2] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t tien : 1; /* [4] */ + __IO uint32_t errie : 1; /* [5] */ + __IO uint32_t rdbfie : 1; /* [6] */ + __IO uint32_t tdbeie : 1; /* [7] */ + __IO uint32_t mdiv_h : 1; /* [8] */ + __IO uint32_t mdiv3en : 1; /* [9] */ + __IO uint32_t reserved2 : 22;/* [31:10] */ + } ctrl2_bit; + }; + + /** + * @brief spi sts register, offset:0x08 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t rdbf : 1; /* [0] */ + __IO uint32_t tdbe : 1; /* [1] */ + __IO uint32_t acs : 1; /* [2] */ + __IO uint32_t tuerr : 1; /* [3] */ + __IO uint32_t ccerr : 1; /* [4] */ + __IO uint32_t mmerr : 1; /* [5] */ + __IO uint32_t roerr : 1; /* [6] */ + __IO uint32_t bf : 1; /* [7] */ + __IO uint32_t cspas : 1; /* [8] */ + __IO uint32_t reserved1 : 23;/* [31:9] */ + } sts_bit; + }; + + /** + * @brief spi dt register, offset:0x0C + */ + union + { + __IO uint32_t dt; + struct + { + __IO uint32_t dt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } dt_bit; + }; + + /** + * @brief spi cpoly register, offset:0x10 + */ + union + { + __IO uint32_t cpoly; + struct + { + __IO uint32_t cpoly : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } cpoly_bit; + }; + + /** + * @brief spi rcrc register, offset:0x14 + */ + union + { + __IO uint32_t rcrc; + struct + { + __IO uint32_t rcrc : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } rcrc_bit; + }; + + /** + * @brief spi tcrc register, offset:0x18 + */ + union + { + __IO uint32_t tcrc; + struct + { + __IO uint32_t tcrc : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } tcrc_bit; + }; + + /** + * @brief spi i2sctrl register, offset:0x1C + */ + union + { + __IO uint32_t i2sctrl; + struct + { + __IO uint32_t i2scbn : 1; /* [0] */ + __IO uint32_t i2sdbn : 2; /* [2:1] */ + __IO uint32_t i2sclkpol : 1; /* [3] */ + __IO uint32_t stdsel : 2; /* [5:4] */ + __IO uint32_t reserved1 : 1; /* [6] */ + __IO uint32_t pcmfssel : 1; /* [7] */ + __IO uint32_t opersel : 2; /* [9:8] */ + __IO uint32_t i2sen : 1; /* [10] */ + __IO uint32_t i2smsel : 1; /* [11] */ + __IO uint32_t reserved2 : 20;/* [31:12] */ + } i2sctrl_bit; + }; + + /** + * @brief spi i2sclk register, offset:0x20 + */ + union + { + __IO uint32_t i2sclk; + struct + { + __IO uint32_t i2sdiv_l : 8; /* [7:0] */ + __IO uint32_t i2sodd : 1; /* [8] */ + __IO uint32_t i2smclkoe : 1; /* [9] */ + __IO uint32_t i2sdiv_h : 2; /* [11:10] */ + __IO uint32_t reserved1 : 20;/* [31:12] */ + } i2sclk_bit; + }; + +} spi_type; + +/** + * @} + */ + +#define SPI1 ((spi_type *) SPI1_BASE) +#define SPI2 ((spi_type *) SPI2_BASE) +#if defined (AT32F425Rx) || defined (AT32F425Cx) || defined (AT32F425Kx) || \ + defined (AT32F425Gx) +#define SPI3 ((spi_type *) SPI3_BASE) +#endif + +/** @defgroup SPI_exported_functions + * @{ + */ + +void spi_i2s_reset(spi_type *spi_x); +void spi_default_para_init(spi_init_type* spi_init_struct); +void spi_init(spi_type* spi_x, spi_init_type* spi_init_struct); +void spi_ti_mode_enable(spi_type* spi_x, confirm_state new_state); +void spi_crc_next_transmit(spi_type* spi_x); +void spi_crc_polynomial_set(spi_type* spi_x, uint16_t crc_poly); +uint16_t spi_crc_polynomial_get(spi_type* spi_x); +void spi_crc_enable(spi_type* spi_x, confirm_state new_state); +uint16_t spi_crc_value_get(spi_type* spi_x, spi_crc_direction_type crc_direction); +void spi_hardware_cs_output_enable(spi_type* spi_x, confirm_state new_state); +void spi_software_cs_internal_level_set(spi_type* spi_x, spi_software_cs_level_type level); +void spi_frame_bit_num_set(spi_type* spi_x, spi_frame_bit_num_type bit_num); +void spi_half_duplex_direction_set(spi_type* spi_x, spi_half_duplex_direction_type direction); +void spi_enable(spi_type* spi_x, confirm_state new_state); +void i2s_default_para_init(i2s_init_type* i2s_init_struct); +void i2s_init(spi_type* spi_x, i2s_init_type* i2s_init_struct); +void i2s_enable(spi_type* spi_x, confirm_state new_state); +void spi_i2s_interrupt_enable(spi_type* spi_x, uint32_t spi_i2s_int, confirm_state new_state); +void spi_i2s_dma_transmitter_enable(spi_type* spi_x, confirm_state new_state); +void spi_i2s_dma_receiver_enable(spi_type* spi_x, confirm_state new_state); +void spi_i2s_data_transmit(spi_type* spi_x, uint16_t tx_data); +uint16_t spi_i2s_data_receive(spi_type* spi_x); +flag_status spi_i2s_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag); +flag_status spi_i2s_interrupt_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag); +void spi_i2s_flag_clear(spi_type* spi_x, uint32_t spi_i2s_flag); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_tmr.h b/libraries/drivers/inc/at32f425_tmr.h new file mode 100644 index 0000000..68dd04f --- /dev/null +++ b/libraries/drivers/inc/at32f425_tmr.h @@ -0,0 +1,962 @@ +/** + ************************************************************************** + * @file at32f425_tmr.h + * @brief at32f425 tmr header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_TMR_H +#define __AT32F425_TMR_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup TMR + * @{ + */ + +/** @defgroup TMR_flags_definition + * @brief tmr flag + * @{ + */ + +#define TMR_OVF_FLAG ((uint32_t)0x000001) /*!< tmr flag overflow */ +#define TMR_C1_FLAG ((uint32_t)0x000002) /*!< tmr flag channel 1 */ +#define TMR_C2_FLAG ((uint32_t)0x000004) /*!< tmr flag channel 2 */ +#define TMR_C3_FLAG ((uint32_t)0x000008) /*!< tmr flag channel 3 */ +#define TMR_C4_FLAG ((uint32_t)0x000010) /*!< tmr flag channel 4 */ +#define TMR_HALL_FLAG ((uint32_t)0x000020) /*!< tmr flag hall */ +#define TMR_TRIGGER_FLAG ((uint32_t)0x000040) /*!< tmr flag trigger */ +#define TMR_BRK_FLAG ((uint32_t)0x000080) /*!< tmr flag brake */ +#define TMR_C1_RECAPTURE_FLAG ((uint32_t)0x000200) /*!< tmr flag channel 1 recapture */ +#define TMR_C2_RECAPTURE_FLAG ((uint32_t)0x000400) /*!< tmr flag channel 2 recapture */ +#define TMR_C3_RECAPTURE_FLAG ((uint32_t)0x000800) /*!< tmr flag channel 3 recapture */ +#define TMR_C4_RECAPTURE_FLAG ((uint32_t)0x001000) /*!< tmr flag channel 4 recapture */ + +/** + * @} + */ + +/** @defgroup TMR_interrupt_select_type_definition + * @brief tmr interrupt select type + * @{ + */ + +#define TMR_OVF_INT ((uint32_t)0x000001) /*!< tmr interrupt overflow */ +#define TMR_C1_INT ((uint32_t)0x000002) /*!< tmr interrupt channel 1 */ +#define TMR_C2_INT ((uint32_t)0x000004) /*!< tmr interrupt channel 2 */ +#define TMR_C3_INT ((uint32_t)0x000008) /*!< tmr interrupt channel 3 */ +#define TMR_C4_INT ((uint32_t)0x000010) /*!< tmr interrupt channel 4 */ +#define TMR_HALL_INT ((uint32_t)0x000020) /*!< tmr interrupt hall */ +#define TMR_TRIGGER_INT ((uint32_t)0x000040) /*!< tmr interrupt trigger */ +#define TMR_BRK_INT ((uint32_t)0x000080) /*!< tmr interrupt brake */ + +/** + * @} + */ + +/** @defgroup TMR_exported_types + * @{ + */ + +/** + * @brief tmr clock division type + */ +typedef enum +{ + TMR_CLOCK_DIV1 = 0x00, /*!< tmr clock division 1 */ + TMR_CLOCK_DIV2 = 0x01, /*!< tmr clock division 2 */ + TMR_CLOCK_DIV4 = 0x02 /*!< tmr clock division 4 */ +} tmr_clock_division_type; + +/** + * @brief tmr counter mode type + */ +typedef enum +{ + TMR_COUNT_UP = 0x00, /*!< tmr counter mode up */ + TMR_COUNT_DOWN = 0x01, /*!< tmr counter mode down */ + TMR_COUNT_TWO_WAY_1 = 0x02, /*!< tmr counter mode two way 1 */ + TMR_COUNT_TWO_WAY_2 = 0x04, /*!< tmr counter mode two way 2 */ + TMR_COUNT_TWO_WAY_3 = 0x06 /*!< tmr counter mode two way 3 */ +} tmr_count_mode_type; + +/** + * @brief tmr primary mode select type + */ +typedef enum +{ + TMR_PRIMARY_SEL_RESET = 0x00, /*!< tmr primary mode select reset */ + TMR_PRIMARY_SEL_ENABLE = 0x01, /*!< tmr primary mode select enable */ + TMR_PRIMARY_SEL_OVERFLOW = 0x02, /*!< tmr primary mode select overflow */ + TMR_PRIMARY_SEL_COMPARE = 0x03, /*!< tmr primary mode select compare */ + TMR_PRIMARY_SEL_C1ORAW = 0x04, /*!< tmr primary mode select c1oraw */ + TMR_PRIMARY_SEL_C2ORAW = 0x05, /*!< tmr primary mode select c2oraw */ + TMR_PRIMARY_SEL_C3ORAW = 0x06, /*!< tmr primary mode select c3oraw */ + TMR_PRIMARY_SEL_C4ORAW = 0x07 /*!< tmr primary mode select c4oraw */ +} tmr_primary_select_type; + +/** + * @brief tmr subordinate mode input select type + */ +typedef enum +{ + TMR_SUB_INPUT_SEL_IS0 = 0x00, /*!< subordinate mode input select is0 */ + TMR_SUB_INPUT_SEL_IS1 = 0x01, /*!< subordinate mode input select is1 */ + TMR_SUB_INPUT_SEL_IS2 = 0x02, /*!< subordinate mode input select is2 */ + TMR_SUB_INPUT_SEL_IS3 = 0x03, /*!< subordinate mode input select is3 */ + TMR_SUB_INPUT_SEL_C1INC = 0x04, /*!< subordinate mode input select c1inc */ + TMR_SUB_INPUT_SEL_C1DF1 = 0x05, /*!< subordinate mode input select c1df1 */ + TMR_SUB_INPUT_SEL_C2DF2 = 0x06, /*!< subordinate mode input select c2df2 */ + TMR_SUB_INPUT_SEL_EXTIN = 0x07 /*!< subordinate mode input select extin */ +} sub_tmr_input_sel_type; + +/** + * @brief tmr subordinate mode select type + */ +typedef enum +{ + TMR_SUB_MODE_DIABLE = 0x00, /*!< subordinate mode disable */ + TMR_SUB_ENCODER_MODE_A = 0x01, /*!< subordinate mode select encoder mode a */ + TMR_SUB_ENCODER_MODE_B = 0x02, /*!< subordinate mode select encoder mode b */ + TMR_SUB_ENCODER_MODE_C = 0x03, /*!< subordinate mode select encoder mode c */ + TMR_SUB_RESET_MODE = 0x04, /*!< subordinate mode select reset */ + TMR_SUB_HANG_MODE = 0x05, /*!< subordinate mode select hang */ + TMR_SUB_TRIGGER_MODE = 0x06, /*!< subordinate mode select trigger */ + TMR_SUB_EXTERNAL_CLOCK_MODE_A = 0x07 /*!< subordinate mode external clock mode a */ +} tmr_sub_mode_select_type; + +/** + * @brief tmr encoder mode type + */ +typedef enum +{ + TMR_ENCODER_MODE_A = TMR_SUB_ENCODER_MODE_A, /*!< tmr encoder mode a */ + TMR_ENCODER_MODE_B = TMR_SUB_ENCODER_MODE_B, /*!< tmr encoder mode b */ + TMR_ENCODER_MODE_C = TMR_SUB_ENCODER_MODE_C /*!< tmr encoder mode c */ +} tmr_encoder_mode_type; + +/** + * @brief tmr output control mode type + */ +typedef enum +{ + TMR_OUTPUT_CONTROL_OFF = 0x00, /*!< tmr output control mode off */ + TMR_OUTPUT_CONTROL_HIGH = 0x01, /*!< tmr output control mode high */ + TMR_OUTPUT_CONTROL_LOW = 0x02, /*!< tmr output control mode low */ + TMR_OUTPUT_CONTROL_SWITCH = 0x03, /*!< tmr output control mode switch */ + TMR_OUTPUT_CONTROL_FORCE_LOW = 0x04, /*!< tmr output control mode force low */ + TMR_OUTPUT_CONTROL_FORCE_HIGH = 0x05, /*!< tmr output control mode force high */ + TMR_OUTPUT_CONTROL_PWM_MODE_A = 0x06, /*!< tmr output control mode pwm a */ + TMR_OUTPUT_CONTROL_PWM_MODE_B = 0x07 /*!< tmr output control mode pwm b */ +} tmr_output_control_mode_type; + +/** + * @brief tmr force output type + */ +typedef enum +{ + TMR_FORCE_OUTPUT_HIGH = TMR_OUTPUT_CONTROL_FORCE_HIGH, /*!< tmr force output high */ + TMR_FORCE_OUTPUT_LOW = TMR_OUTPUT_CONTROL_FORCE_LOW /*!< tmr force output low */ +} tmr_force_output_type; + +/** + * @brief tmr output channel polarity type + */ +typedef enum +{ + TMR_OUTPUT_ACTIVE_HIGH = 0x00, /*!< tmr output channel polarity high */ + TMR_OUTPUT_ACTIVE_LOW = 0x01 /*!< tmr output channel polarity low */ +} tmr_output_polarity_type; + +/** + * @brief tmr input channel polarity type + */ +typedef enum +{ + TMR_INPUT_RISING_EDGE = 0x00, /*!< tmr input channel polarity rising */ + TMR_INPUT_FALLING_EDGE = 0x01, /*!< tmr input channel polarity falling */ + TMR_INPUT_BOTH_EDGE = 0x03 /*!< tmr input channel polarity both edge */ +} tmr_input_polarity_type; + +/** + * @brief tmr channel select type + */ +typedef enum +{ + TMR_SELECT_CHANNEL_1 = 0x00, /*!< tmr channel select channel 1 */ + TMR_SELECT_CHANNEL_1C = 0x01, /*!< tmr channel select channel 1 complementary */ + TMR_SELECT_CHANNEL_2 = 0x02, /*!< tmr channel select channel 2 */ + TMR_SELECT_CHANNEL_2C = 0x03, /*!< tmr channel select channel 2 complementary */ + TMR_SELECT_CHANNEL_3 = 0x04, /*!< tmr channel select channel 3 */ + TMR_SELECT_CHANNEL_3C = 0x05, /*!< tmr channel select channel 3 complementary */ + TMR_SELECT_CHANNEL_4 = 0x06 /*!< tmr channel select channel 4 */ +} tmr_channel_select_type; + +/** + * @brief tmr channel1 input connected type + */ +typedef enum +{ + TMR_CHANEL1_CONNECTED_C1IRAW = 0x00, /*!< channel1 pins is only connected to C1IRAW input */ + TMR_CHANEL1_2_3_CONNECTED_C1IRAW_XOR = 0x01 /*!< channel1/2/3 pins are connected to C1IRAW input after xored */ +} tmr_channel1_input_connected_type; + +/** + * @brief tmr input channel mapped type channel direction + */ +typedef enum +{ + TMR_CC_CHANNEL_MAPPED_DIRECT = 0x01, /*!< channel is configured as input, mapped direct */ + TMR_CC_CHANNEL_MAPPED_INDIRECT = 0x02, /*!< channel is configured as input, mapped indirect */ + TMR_CC_CHANNEL_MAPPED_STI = 0x03 /*!< channel is configured as input, mapped sti */ +} tmr_input_direction_mapped_type; + +/** + * @brief tmr input divider type + */ +typedef enum +{ + TMR_CHANNEL_INPUT_DIV_1 = 0x00, /*!< tmr channel input divider 1 */ + TMR_CHANNEL_INPUT_DIV_2 = 0x01, /*!< tmr channel input divider 2 */ + TMR_CHANNEL_INPUT_DIV_4 = 0x02, /*!< tmr channel input divider 4 */ + TMR_CHANNEL_INPUT_DIV_8 = 0x03 /*!< tmr channel input divider 8 */ +} tmr_channel_input_divider_type; + +/** + * @brief tmr dma request source select type + */ +typedef enum +{ + TMR_DMA_REQUEST_BY_CHANNEL = 0x00, /*!< tmr dma request source select channel */ + TMR_DMA_REQUEST_BY_OVERFLOW = 0x01 /*!< tmr dma request source select overflow */ +} tmr_dma_request_source_type; + +/** + * @brief tmr dma request type + */ +typedef enum +{ + TMR_OVERFLOW_DMA_REQUEST = 0x00000100, /*!< tmr dma request select overflow */ + TMR_C1_DMA_REQUEST = 0x00000200, /*!< tmr dma request select channel 1 */ + TMR_C2_DMA_REQUEST = 0x00000400, /*!< tmr dma request select channel 2 */ + TMR_C3_DMA_REQUEST = 0x00000800, /*!< tmr dma request select channel 3 */ + TMR_C4_DMA_REQUEST = 0x00001000, /*!< tmr dma request select channel 4 */ + TMR_HALL_DMA_REQUEST = 0x00002000, /*!< tmr dma request select hall */ + TMR_TRIGGER_DMA_REQUEST = 0x00004000 /*!< tmr dma request select trigger */ +} tmr_dma_request_type; + +/** + * @brief tmr event triggered by software type + */ +typedef enum +{ + TMR_OVERFLOW_SWTRIG = 0x00000001, /*!< tmr event triggered by software of overflow */ + TMR_C1_SWTRIG = 0x00000002, /*!< tmr event triggered by software of channel 1 */ + TMR_C2_SWTRIG = 0x00000004, /*!< tmr event triggered by software of channel 2 */ + TMR_C3_SWTRIG = 0x00000008, /*!< tmr event triggered by software of channel 3 */ + TMR_C4_SWTRIG = 0x00000010, /*!< tmr event triggered by software of channel 4 */ + TMR_HALL_SWTRIG = 0x00000020, /*!< tmr event triggered by software of hall */ + TMR_TRIGGER_SWTRIG = 0x00000040, /*!< tmr event triggered by software of trigger */ + TMR_BRK_SWTRIG = 0x00000080 /*!< tmr event triggered by software of brake */ +}tmr_event_trigger_type; + +/** + * @brief tmr polarity active type + */ +typedef enum +{ + TMR_POLARITY_ACTIVE_HIGH = 0x00, /*!< tmr polarity active high */ + TMR_POLARITY_ACTIVE_LOW = 0x01, /*!< tmr polarity active low */ + TMR_POLARITY_ACTIVE_BOTH = 0x02 /*!< tmr polarity active both high ande low */ +}tmr_polarity_active_type; + +/** + * @brief tmr external signal divider type + */ +typedef enum +{ + TMR_ES_FREQUENCY_DIV_1 = 0x00, /*!< tmr external signal frequency divider 1 */ + TMR_ES_FREQUENCY_DIV_2 = 0x01, /*!< tmr external signal frequency divider 2 */ + TMR_ES_FREQUENCY_DIV_4 = 0x02, /*!< tmr external signal frequency divider 4 */ + TMR_ES_FREQUENCY_DIV_8 = 0x03 /*!< tmr external signal frequency divider 8 */ +}tmr_external_signal_divider_type; + +/** + * @brief tmr external signal polarity type + */ +typedef enum +{ + TMR_ES_POLARITY_NON_INVERTED = 0x00, /*!< tmr external signal polarity non-inerted */ + TMR_ES_POLARITY_INVERTED = 0x01 /*!< tmr external signal polarity inerted */ +}tmr_external_signal_polarity_type; + +/** + * @brief tmr dma transfer length type + */ +typedef enum +{ + TMR_DMA_TRANSFER_1BYTE = 0x00, /*!< tmr dma transfer length 1 byte */ + TMR_DMA_TRANSFER_2BYTES = 0x01, /*!< tmr dma transfer length 2 bytes */ + TMR_DMA_TRANSFER_3BYTES = 0x02, /*!< tmr dma transfer length 3 bytes */ + TMR_DMA_TRANSFER_4BYTES = 0x03, /*!< tmr dma transfer length 4 bytes */ + TMR_DMA_TRANSFER_5BYTES = 0x04, /*!< tmr dma transfer length 5 bytes */ + TMR_DMA_TRANSFER_6BYTES = 0x05, /*!< tmr dma transfer length 6 bytes */ + TMR_DMA_TRANSFER_7BYTES = 0x06, /*!< tmr dma transfer length 7 bytes */ + TMR_DMA_TRANSFER_8BYTES = 0x07, /*!< tmr dma transfer length 8 bytes */ + TMR_DMA_TRANSFER_9BYTES = 0x08, /*!< tmr dma transfer length 9 bytes */ + TMR_DMA_TRANSFER_10BYTES = 0x09, /*!< tmr dma transfer length 10 bytes */ + TMR_DMA_TRANSFER_11BYTES = 0x0A, /*!< tmr dma transfer length 11 bytes */ + TMR_DMA_TRANSFER_12BYTES = 0x0B, /*!< tmr dma transfer length 12 bytes */ + TMR_DMA_TRANSFER_13BYTES = 0x0C, /*!< tmr dma transfer length 13 bytes */ + TMR_DMA_TRANSFER_14BYTES = 0x0D, /*!< tmr dma transfer length 14 bytes */ + TMR_DMA_TRANSFER_15BYTES = 0x0E, /*!< tmr dma transfer length 15 bytes */ + TMR_DMA_TRANSFER_16BYTES = 0x0F, /*!< tmr dma transfer length 16 bytes */ + TMR_DMA_TRANSFER_17BYTES = 0x10, /*!< tmr dma transfer length 17 bytes */ + TMR_DMA_TRANSFER_18BYTES = 0x11 /*!< tmr dma transfer length 18 bytes */ +}tmr_dma_transfer_length_type; + +/** + * @brief tmr dma base address type + */ +typedef enum +{ + TMR_CTRL1_ADDRESS = 0x0000, /*!< tmr dma base address ctrl1 */ + TMR_CTRL2_ADDRESS = 0x0001, /*!< tmr dma base address ctrl2 */ + TMR_STCTRL_ADDRESS = 0x0002, /*!< tmr dma base address stctrl */ + TMR_IDEN_ADDRESS = 0x0003, /*!< tmr dma base address iden */ + TMR_ISTS_ADDRESS = 0x0004, /*!< tmr dma base address ists */ + TMR_SWEVT_ADDRESS = 0x0005, /*!< tmr dma base address swevt */ + TMR_CM1_ADDRESS = 0x0006, /*!< tmr dma base address cm1 */ + TMR_CM2_ADDRESS = 0x0007, /*!< tmr dma base address cm2 */ + TMR_CCTRL_ADDRESS = 0x0008, /*!< tmr dma base address cctrl */ + TMR_CVAL_ADDRESS = 0x0009, /*!< tmr dma base address cval */ + TMR_DIV_ADDRESS = 0x000A, /*!< tmr dma base address div */ + TMR_PR_ADDRESS = 0x000B, /*!< tmr dma base address pr */ + TMR_RPR_ADDRESS = 0x000C, /*!< tmr dma base address rpr */ + TMR_C1DT_ADDRESS = 0x000D, /*!< tmr dma base address c1dt */ + TMR_C2DT_ADDRESS = 0x000E, /*!< tmr dma base address c2dt */ + TMR_C3DT_ADDRESS = 0x000F, /*!< tmr dma base address c3dt */ + TMR_C4DT_ADDRESS = 0x0010, /*!< tmr dma base address c4dt */ + TMR_BRK_ADDRESS = 0x0011, /*!< tmr dma base address brake */ + TMR_DMACTRL_ADDRESS = 0x0012 /*!< tmr dma base address dmactrl */ +}tmr_dma_address_type; + +/** + * @brief tmr brk polarity type + */ +typedef enum +{ + TMR_BRK_INPUT_ACTIVE_LOW = 0x00, /*!< tmr brk input channel active low */ + TMR_BRK_INPUT_ACTIVE_HIGH = 0x01 /*!< tmr brk input channel active high */ +}tmr_brk_polarity_type; + +/** + * @brief tmr write protect level type + */ +typedef enum +{ + TMR_WP_OFF = 0x00, /*!< tmr write protect off */ + TMR_WP_LEVEL_3 = 0x01, /*!< tmr write protect level 3 */ + TMR_WP_LEVEL_2 = 0x02, /*!< tmr write protect level 2 */ + TMR_WP_LEVEL_1 = 0x03 /*!< tmr write protect level 1 */ +}tmr_wp_level_type; + +/** + * @brief tmr input remap type + */ +typedef enum +{ + TMR14_GPIO = 0x00, /*!< tmr14 input remap to gpio */ + TMR14_ERTCCLK = 0x01, /*!< tmr14 input remap to ertc clock */ + TMR14_HEXT_DIV32 = 0x02, /*!< tmr14 input remap to hext div32*/ + TMR14_CLKOUT = 0x03 /*!< tmr14 input remap to clkout */ +}tmr_input_remap_type ; + +/** + * @brief tmr output config type + */ +typedef struct +{ + tmr_output_control_mode_type oc_mode; /*!< output channel mode */ + confirm_state oc_idle_state; /*!< output channel idle state */ + confirm_state occ_idle_state; /*!< output channel complementary idle state */ + tmr_output_polarity_type oc_polarity; /*!< output channel polarity */ + tmr_output_polarity_type occ_polarity; /*!< output channel complementary polarity */ + confirm_state oc_output_state; /*!< output channel enable */ + confirm_state occ_output_state; /*!< output channel complementary enable */ +} tmr_output_config_type; + +/** + * @brief tmr input capture config type + */ +typedef struct +{ + tmr_channel_select_type input_channel_select; /*!< tmr input channel select */ + tmr_input_polarity_type input_polarity_select; /*!< tmr input polarity select */ + tmr_input_direction_mapped_type input_mapped_select; /*!< tmr channel mapped direct or indirect */ + uint8_t input_filter_value; /*!< tmr channel filter value */ +} tmr_input_config_type; + +/** + * @brief tmr brkdt config type + */ +typedef struct +{ + uint8_t deadtime; /*!< dead-time generator setup */ + tmr_brk_polarity_type brk_polarity; /*!< tmr brake polarity */ + tmr_wp_level_type wp_level; /*!< write protect configuration */ + confirm_state auto_output_enable; /*!< automatic output enable */ + confirm_state fcsoen_state; /*!< frozen channel status when output enable */ + confirm_state fcsodis_state; /*!< frozen channel status when output disable */ + confirm_state brk_enable; /*!< tmr brk enale */ +} tmr_brkdt_config_type; + +/** + * @brief type define tmr register all + */ +typedef struct +{ + /** + * @brief tmr ctrl1 register, offset:0x00 + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t tmren : 1; /* [0] */ + __IO uint32_t ovfen : 1; /* [1] */ + __IO uint32_t ovfs : 1; /* [2] */ + __IO uint32_t ocmen : 1; /* [3] */ + __IO uint32_t cnt_dir : 3; /* [6:4] */ + __IO uint32_t prben : 1; /* [7] */ + __IO uint32_t clkdiv : 2; /* [9:8] */ + __IO uint32_t pmen : 1; /* [10] */ + __IO uint32_t reserved1 : 21;/* [31:11] */ + } ctrl1_bit; + }; + + /** + * @brief tmr ctrl2 register, offset:0x04 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t cbctrl : 1; /* [0] */ + __IO uint32_t reserved1 : 1; /* [1] */ + __IO uint32_t ccfs : 1; /* [2] */ + __IO uint32_t drs : 1; /* [3] */ + __IO uint32_t ptos : 3; /* [6:4] */ + __IO uint32_t c1insel : 1; /* [7] */ + __IO uint32_t c1ios : 1; /* [8] */ + __IO uint32_t c1cios : 1; /* [9] */ + __IO uint32_t c2ios : 1; /* [10] */ + __IO uint32_t c2cios : 1; /* [11] */ + __IO uint32_t c3ios : 1; /* [12] */ + __IO uint32_t c3cios : 1; /* [13] */ + __IO uint32_t c4ios : 1; /* [14] */ + __IO uint32_t reserved2 : 17;/* [31:15] */ + } ctrl2_bit; + }; + + /** + * @brief tmr smc register, offset:0x08 + */ + union + { + __IO uint32_t stctrl; + struct + { + __IO uint32_t smsel : 3; /* [2:0] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t stis : 3; /* [6:4] */ + __IO uint32_t sts : 1; /* [7] */ + __IO uint32_t esf : 4; /* [11:8] */ + __IO uint32_t esdiv : 2; /* [13:12] */ + __IO uint32_t ecmben : 1; /* [14] */ + __IO uint32_t esp : 1; /* [15] */ + __IO uint32_t reserved2 : 16;/* [31:16] */ + } stctrl_bit; + }; + + /** + * @brief tmr die register, offset:0x0C + */ + union + { + __IO uint32_t iden; + struct + { + __IO uint32_t ovfien : 1; /* [0] */ + __IO uint32_t c1ien : 1; /* [1] */ + __IO uint32_t c2ien : 1; /* [2] */ + __IO uint32_t c3ien : 1; /* [3] */ + __IO uint32_t c4ien : 1; /* [4] */ + __IO uint32_t hallien : 1; /* [5] */ + __IO uint32_t tien : 1; /* [6] */ + __IO uint32_t brkie : 1; /* [7] */ + __IO uint32_t ovfden : 1; /* [8] */ + __IO uint32_t c1den : 1; /* [9] */ + __IO uint32_t c2den : 1; /* [10] */ + __IO uint32_t c3den : 1; /* [11] */ + __IO uint32_t c4den : 1; /* [12] */ + __IO uint32_t hallde : 1; /* [13] */ + __IO uint32_t tden : 1; /* [14] */ + __IO uint32_t reserved1 : 17;/* [31:15] */ + } iden_bit; + }; + + /** + * @brief tmr ists register, offset:0x10 + */ + union + { + __IO uint32_t ists; + struct + { + __IO uint32_t ovfif : 1; /* [0] */ + __IO uint32_t c1if : 1; /* [1] */ + __IO uint32_t c2if : 1; /* [2] */ + __IO uint32_t c3if : 1; /* [3] */ + __IO uint32_t c4if : 1; /* [4] */ + __IO uint32_t hallif : 1; /* [5] */ + __IO uint32_t trgif : 1; /* [6] */ + __IO uint32_t brkif : 1; /* [7] */ + __IO uint32_t reserved1 : 1; /* [8] */ + __IO uint32_t c1rf : 1; /* [9] */ + __IO uint32_t c2rf : 1; /* [10] */ + __IO uint32_t c3rf : 1; /* [11] */ + __IO uint32_t c4rf : 1; /* [12] */ + __IO uint32_t reserved2 : 19;/* [31:13] */ + } ists_bit; + }; + + /** + * @brief tmr eveg register, offset:0x14 + */ + union + { + __IO uint32_t swevt; + struct + { + __IO uint32_t ovfswtr : 1; /* [0] */ + __IO uint32_t c1swtr : 1; /* [1] */ + __IO uint32_t c2swtr : 1; /* [2] */ + __IO uint32_t c3swtr : 1; /* [3] */ + __IO uint32_t c4swtr : 1; /* [4] */ + __IO uint32_t hallswtr : 1; /* [5] */ + __IO uint32_t trgswtr : 1; /* [6] */ + __IO uint32_t brkswtr : 1; /* [7] */ + __IO uint32_t reserved : 24;/* [31:8] */ + } swevt_bit; + }; + + /** + * @brief tmr ccm1 register, offset:0x18 + */ + union + { + __IO uint32_t cm1; + + /** + * @brief channel mode + */ + struct + { + __IO uint32_t c1c : 2; /* [1:0] */ + __IO uint32_t c1oien : 1; /* [2] */ + __IO uint32_t c1oben : 1; /* [3] */ + __IO uint32_t c1octrl : 3; /* [6:4] */ + __IO uint32_t c1osen : 1; /* [7] */ + __IO uint32_t c2c : 2; /* [9:8] */ + __IO uint32_t c2oien : 1; /* [10] */ + __IO uint32_t c2oben : 1; /* [11] */ + __IO uint32_t c2octrl : 3; /* [14:12] */ + __IO uint32_t c2osen : 1; /* [15] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } cm1_output_bit; + + /** + * @brief input capture mode + */ + struct + { + __IO uint32_t c1c : 2; /* [1:0] */ + __IO uint32_t c1idiv : 2; /* [3:2] */ + __IO uint32_t c1df : 4; /* [7:4] */ + __IO uint32_t c2c : 2; /* [9:8] */ + __IO uint32_t c2idiv : 2; /* [11:10] */ + __IO uint32_t c2df : 4; /* [15:12] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } cm1_input_bit; + }; + + /** + * @brief tmr ccm2 register, offset:0x1C + */ + union + { + __IO uint32_t cm2; + + /** + * @brief channel mode + */ + struct + { + __IO uint32_t c3c : 2; /* [1:0] */ + __IO uint32_t c3oien : 1; /* [2] */ + __IO uint32_t c3oben : 1; /* [3] */ + __IO uint32_t c3octrl : 3; /* [6:4] */ + __IO uint32_t c3osen : 1; /* [7] */ + __IO uint32_t c4c : 2; /* [9:8] */ + __IO uint32_t c4oien : 1; /* [10] */ + __IO uint32_t c4oben : 1; /* [11] */ + __IO uint32_t c4octrl : 3; /* [14:12] */ + __IO uint32_t c4osen : 1; /* [15] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } cm2_output_bit; + + /** + * @brief input capture mode + */ + struct + { + __IO uint32_t c3c : 2; /* [1:0] */ + __IO uint32_t c3idiv : 2; /* [3:2] */ + __IO uint32_t c3df : 4; /* [7:4] */ + __IO uint32_t c4c : 2; /* [9:8] */ + __IO uint32_t c4idiv : 2; /* [11:10] */ + __IO uint32_t c4df : 4; /* [15:12] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } cm2_input_bit; + }; + + /** + * @brief tmr cce register, offset:0x20 + */ + union + { + uint32_t cctrl; + struct + { + __IO uint32_t c1en : 1; /* [0] */ + __IO uint32_t c1p : 1; /* [1] */ + __IO uint32_t c1cen : 1; /* [2] */ + __IO uint32_t c1cp : 1; /* [3] */ + __IO uint32_t c2en : 1; /* [4] */ + __IO uint32_t c2p : 1; /* [5] */ + __IO uint32_t c2cen : 1; /* [6] */ + __IO uint32_t c2cp : 1; /* [7] */ + __IO uint32_t c3en : 1; /* [8] */ + __IO uint32_t c3p : 1; /* [9] */ + __IO uint32_t c3cen : 1; /* [10] */ + __IO uint32_t c3cp : 1; /* [11] */ + __IO uint32_t c4en : 1; /* [12] */ + __IO uint32_t c4p : 1; /* [13] */ + __IO uint32_t reserved1 : 18;/* [31:14] */ + } cctrl_bit; + }; + + /** + * @brief tmr cnt register, offset:0x24 + */ + union + { + __IO uint32_t cval; + struct + { + __IO uint32_t cval : 32;/* [31:0] */ + } cval_bit; + }; + + /** + * @brief tmr div, offset:0x28 + */ + union + { + __IO uint32_t div; + struct + { + __IO uint32_t div : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } div_bit; + }; + + /** + * @brief tmr pr register, offset:0x2C + */ + union + { + __IO uint32_t pr; + struct + { + __IO uint32_t pr : 32;/* [31:0] */ + } pr_bit; + }; + + /** + * @brief tmr rpr register, offset:0x30 + */ + union + { + __IO uint32_t rpr; + struct + { + __IO uint32_t rpr : 8; /* [7:0] */ + __IO uint32_t reserved1 : 24;/* [31:8] */ + } rpr_bit; + }; + + /** + * @brief tmr c1dt register, offset:0x34 + */ + union + { + uint32_t c1dt; + struct + { + __IO uint32_t c1dt : 32;/* [31:0] */ + } c1dt_bit; + }; + + /** + * @brief tmr c2dt register, offset:0x38 + */ + union + { + uint32_t c2dt; + struct + { + __IO uint32_t c2dt : 32;/* [31:0] */ + } c2dt_bit; + }; + + /** + * @brief tmr c3dt register, offset:0x3C + */ + union + { + __IO uint32_t c3dt; + struct + { + __IO uint32_t c3dt : 32;/* [31:0] */ + } c3dt_bit; + }; + + /** + * @brief tmr c4dt register, offset:0x40 + */ + union + { + __IO uint32_t c4dt; + struct + { + __IO uint32_t c4dt : 32;/* [31:0] */ + } c4dt_bit; + }; + + /** + * @brief tmr brk register, offset:0x44 + */ + union + { + __IO uint32_t brk; + struct + { + __IO uint32_t dtc : 8; /* [7:0] */ + __IO uint32_t wpc : 2; /* [9:8] */ + __IO uint32_t fcsodis : 1; /* [10] */ + __IO uint32_t fcsoen : 1; /* [11] */ + __IO uint32_t brken : 1; /* [12] */ + __IO uint32_t brkv : 1; /* [13] */ + __IO uint32_t aoen : 1; /* [14] */ + __IO uint32_t oen : 1; /* [15] */ + __IO uint32_t bkf : 4; /* [19:16] */ + __IO uint32_t reserved1 : 12;/* [31:20] */ + } brk_bit; + }; + /** + * @brief tmr dmactrl register, offset:0x48 + */ + union + { + __IO uint32_t dmactrl; + struct + { + __IO uint32_t addr : 5; /* [4:0] */ + __IO uint32_t reserved1 : 3; /* [7:5] */ + __IO uint32_t dtb : 5; /* [12:8] */ + __IO uint32_t reserved2 : 19;/* [31:13] */ + } dmactrl_bit; + }; + + /** + * @brief tmr dmadt register, offset:0x4C + */ + union + { + __IO uint32_t dmadt; + struct + { + __IO uint32_t dmadt : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } dmadt_bit; + }; + + /** + * @brief tmr rmp register, offset:0x50 + */ + union + { + __IO uint32_t rmp; + struct + { + __IO uint32_t tmr14_ch1_irmp : 2; /* [1:0] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } rmp_bit; + }; + +} tmr_type; + +/** + * @} + */ + +#define TMR1 ((tmr_type *) TMR1_BASE) +#define TMR2 ((tmr_type *) TMR2_BASE) +#define TMR3 ((tmr_type *) TMR3_BASE) +#define TMR6 ((tmr_type *) TMR6_BASE) +#define TMR7 ((tmr_type *) TMR7_BASE) +#define TMR13 ((tmr_type *) TMR13_BASE) +#define TMR14 ((tmr_type *) TMR14_BASE) +#define TMR15 ((tmr_type *) TMR15_BASE) +#define TMR16 ((tmr_type *) TMR16_BASE) +#define TMR17 ((tmr_type *) TMR17_BASE) +/** @defgroup TMR_exported_functions + * @{ + */ + +void tmr_reset(tmr_type *tmr_x); +void tmr_counter_enable(tmr_type *tmr_x, confirm_state new_state); +void tmr_output_default_para_init(tmr_output_config_type *tmr_output_struct); +void tmr_input_default_para_init(tmr_input_config_type *tmr_input_struct); +void tmr_brkdt_default_para_init(tmr_brkdt_config_type *tmr_brkdt_struct); +void tmr_base_init(tmr_type* tmr_x, uint32_t tmr_pr, uint32_t tmr_div); +void tmr_clock_source_div_set(tmr_type *tmr_x, tmr_clock_division_type tmr_clock_div); +void tmr_cnt_dir_set(tmr_type *tmr_x, tmr_count_mode_type tmr_cnt_dir); +void tmr_repetition_counter_set(tmr_type *tmr_x, uint8_t tmr_rpr_value); +void tmr_counter_value_set(tmr_type *tmr_x, uint32_t tmr_cnt_value); +uint32_t tmr_counter_value_get(tmr_type *tmr_x); +void tmr_div_value_set(tmr_type *tmr_x, uint32_t tmr_div_value); +uint32_t tmr_div_value_get(tmr_type *tmr_x); +void tmr_output_channel_config(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_output_config_type *tmr_output_struct); +void tmr_output_channel_mode_select(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_output_control_mode_type oc_mode); +void tmr_period_value_set(tmr_type *tmr_x, uint32_t tmr_pr_value); +uint32_t tmr_period_value_get(tmr_type *tmr_x); +void tmr_channel_value_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + uint32_t tmr_channel_value); +uint32_t tmr_channel_value_get(tmr_type *tmr_x, tmr_channel_select_type tmr_channel); +void tmr_period_buffer_enable(tmr_type *tmr_x, confirm_state new_state); +void tmr_output_channel_buffer_enable(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + confirm_state new_state); +void tmr_output_channel_immediately_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + confirm_state new_state); +void tmr_output_channel_switch_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + confirm_state new_state); +void tmr_one_cycle_mode_enable(tmr_type *tmr_x, confirm_state new_state); +void tmr_32_bit_function_enable (tmr_type *tmr_x, confirm_state new_state); +void tmr_overflow_request_source_set(tmr_type *tmr_x, confirm_state new_state); +void tmr_overflow_event_disable(tmr_type *tmr_x, confirm_state new_state); +void tmr_input_channel_init(tmr_type *tmr_x, tmr_input_config_type *input_struct, \ + tmr_channel_input_divider_type divider_factor); +void tmr_channel_enable(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, confirm_state new_state); +void tmr_input_channel_filter_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + uint16_t filter_value); +void tmr_pwm_input_config(tmr_type *tmr_x, tmr_input_config_type *input_struct, \ + tmr_channel_input_divider_type divider_factor); +void tmr_channel1_input_select(tmr_type *tmr_x, tmr_channel1_input_connected_type ch1_connect); +void tmr_input_channel_divider_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_channel_input_divider_type divider_factor); +void tmr_primary_mode_select(tmr_type *tmr_x, tmr_primary_select_type primary_mode); +void tmr_sub_mode_select(tmr_type *tmr_x, tmr_sub_mode_select_type sub_mode); +void tmr_channel_dma_select(tmr_type *tmr_x, tmr_dma_request_source_type cc_dma_select); +void tmr_hall_select(tmr_type *tmr_x, confirm_state new_state); +void tmr_channel_buffer_enable(tmr_type *tmr_x, confirm_state new_state); +void tmr_trigger_input_select(tmr_type *tmr_x, sub_tmr_input_sel_type trigger_select); +void tmr_sub_sync_mode_set(tmr_type *tmr_x, confirm_state new_state); +void tmr_dma_request_enable(tmr_type *tmr_x, tmr_dma_request_type dma_request, confirm_state new_state); +void tmr_interrupt_enable(tmr_type *tmr_x, uint32_t tmr_interrupt, confirm_state new_state); +flag_status tmr_interrupt_flag_get(tmr_type *tmr_x, uint32_t tmr_flag); +flag_status tmr_flag_get(tmr_type *tmr_x, uint32_t tmr_flag); +void tmr_flag_clear(tmr_type *tmr_x, uint32_t tmr_flag); +void tmr_event_sw_trigger(tmr_type *tmr_x, tmr_event_trigger_type tmr_event); +void tmr_output_enable(tmr_type *tmr_x, confirm_state new_state); +void tmr_internal_clock_set(tmr_type *tmr_x); + +void tmr_output_channel_polarity_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_polarity_active_type oc_polarity); +void tmr_external_clock_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, \ + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter); +void tmr_external_clock_mode1_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, \ + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter); +void tmr_external_clock_mode2_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, \ + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter); +void tmr_encoder_mode_config(tmr_type *tmr_x, tmr_encoder_mode_type encoder_mode, tmr_input_polarity_type \ + ic1_polarity, tmr_input_polarity_type ic2_polarity); +void tmr_force_output_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_force_output_type force_output); +void tmr_dma_control_config(tmr_type *tmr_x, tmr_dma_transfer_length_type dma_length, \ + tmr_dma_address_type dma_base_address); +void tmr_brkdt_config(tmr_type *tmr_x, tmr_brkdt_config_type *brkdt_struct); +void tmr_brk_filter_value_set(tmr_type *tmr_x, uint8_t filter_value); +void tmr_iremap_config(tmr_type *tmr_x, tmr_input_remap_type input_remap); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_usart.h b/libraries/drivers/inc/at32f425_usart.h new file mode 100644 index 0000000..dc0bac3 --- /dev/null +++ b/libraries/drivers/inc/at32f425_usart.h @@ -0,0 +1,408 @@ +/** + ************************************************************************** + * @file at32f425_usart.h + * @brief at32f425 usart header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_USART_H +#define __AT32F425_USART_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup USART + * @{ + */ + +/** @defgroup USART_flags_definition + * @brief usart flag + * @{ + */ + +#define USART_PERR_FLAG ((uint32_t)0x00000001) /*!< usart parity error flag */ +#define USART_FERR_FLAG ((uint32_t)0x00000002) /*!< usart framing error flag */ +#define USART_NERR_FLAG ((uint32_t)0x00000004) /*!< usart noise error flag */ +#define USART_ROERR_FLAG ((uint32_t)0x00000008) /*!< usart receiver overflow error flag */ +#define USART_IDLEF_FLAG ((uint32_t)0x00000010) /*!< usart idle flag */ +#define USART_RDBF_FLAG ((uint32_t)0x00000020) /*!< usart receive data buffer full flag */ +#define USART_TDC_FLAG ((uint32_t)0x00000040) /*!< usart transmit data complete flag */ +#define USART_TDBE_FLAG ((uint32_t)0x00000080) /*!< usart transmit data buffer empty flag */ +#define USART_BFF_FLAG ((uint32_t)0x00000100) /*!< usart break frame flag */ +#define USART_CTSCF_FLAG ((uint32_t)0x00000200) /*!< usart cts change flag */ + +/** + * @} + */ + +/** @defgroup USART_interrupts_definition + * @brief usart interrupt + * @{ + */ + +#define USART_IDLE_INT MAKE_VALUE(0x0C,0x04) /*!< usart idle interrupt */ +#define USART_RDBF_INT MAKE_VALUE(0x0C,0x05) /*!< usart receive data buffer full interrupt */ +#define USART_TDC_INT MAKE_VALUE(0x0C,0x06) /*!< usart transmit data complete interrupt */ +#define USART_TDBE_INT MAKE_VALUE(0x0C,0x07) /*!< usart transmit data buffer empty interrupt */ +#define USART_PERR_INT MAKE_VALUE(0x0C,0x08) /*!< usart parity error interrupt */ +#define USART_BF_INT MAKE_VALUE(0x10,0x06) /*!< usart break frame interrupt */ +#define USART_ERR_INT MAKE_VALUE(0x14,0x00) /*!< usart error interrupt */ +#define USART_CTSCF_INT MAKE_VALUE(0x14,0x0A) /*!< usart cts change interrupt */ + +/** + * @} + */ + +/** @defgroup USART_exported_types + * @{ + */ + +/** + * @brief usart parity selection type + */ +typedef enum +{ + USART_PARITY_NONE = 0x00, /*!< usart no parity */ + USART_PARITY_EVEN = 0x01, /*!< usart even parity */ + USART_PARITY_ODD = 0x02 /*!< usart odd parity */ +} usart_parity_selection_type; + +/** + * @brief usart wakeup mode type + */ +typedef enum +{ + USART_WAKEUP_BY_IDLE_FRAME = 0x00, /*!< usart wakeup by idle frame */ + USART_WAKEUP_BY_MATCHING_ID = 0x01 /*!< usart wakeup by matching id */ +} usart_wakeup_mode_type; + +/** + * @brief usart data bit num type + */ +typedef enum +{ + USART_DATA_7BITS = 0x00, /*!< usart data size is 7 bits */ + USART_DATA_8BITS = 0x01, /*!< usart data size is 8 bits */ + USART_DATA_9BITS = 0x02 /*!< usart data size is 9 bits */ +} usart_data_bit_num_type; + +/** + * @brief usart break frame bit num type + */ +typedef enum +{ + USART_BREAK_10BITS = 0x00, /*!< usart lin mode berak frame detection 10 bits */ + USART_BREAK_11BITS = 0x01 /*!< usart lin mode berak frame detection 11 bits */ +} usart_break_bit_num_type; + +/** + * @brief usart phase of the clock type + */ +typedef enum +{ + USART_CLOCK_PHASE_1EDGE = 0x00, /*!< usart data capture is done on the clock leading edge */ + USART_CLOCK_PHASE_2EDGE = 0x01 /*!< usart data capture is done on the clock trailing edge */ +} usart_clock_phase_type; + +/** + * @brief usart polarity of the clock type + */ +typedef enum +{ + USART_CLOCK_POLARITY_LOW = 0x00, /*!< usart clock stay low level outside transmission window */ + USART_CLOCK_POLARITY_HIGH = 0x01 /*!< usart clock stay high level outside transmission window */ +} usart_clock_polarity_type; + +/** + * @brief usart last bit clock pulse type + */ +typedef enum +{ + USART_CLOCK_LAST_BIT_NONE = 0x00, /*!< usart clock pulse of the last data bit is not outputted */ + USART_CLOCK_LAST_BIT_OUTPUT = 0x01 /*!< usart clock pulse of the last data bit is outputted */ +} usart_lbcp_type; + +/** + * @brief usart stop bit num type + */ +typedef enum +{ + USART_STOP_1_BIT = 0x00, /*!< usart stop bits num is 1 */ + USART_STOP_0_5_BIT = 0x01, /*!< usart stop bits num is 0.5 */ + USART_STOP_2_BIT = 0x02, /*!< usart stop bits num is 2 */ + USART_STOP_1_5_BIT = 0x03 /*!< usart stop bits num is 1.5 */ +} usart_stop_bit_num_type; + +/** + * @brief usart hardware flow control type + */ +typedef enum +{ + USART_HARDWARE_FLOW_NONE = 0x00, /*!< usart without hardware flow */ + USART_HARDWARE_FLOW_RTS = 0x01, /*!< usart hardware flow only rts */ + USART_HARDWARE_FLOW_CTS = 0x02, /*!< usart hardware flow only cts */ + USART_HARDWARE_FLOW_RTS_CTS = 0x03 /*!< usart hardware flow both rts and cts */ +} usart_hardware_flow_control_type; + +/** + * @brief usart identification bit num type + */ +typedef enum +{ + USART_ID_FIXED_4_BIT = 0x00, /*!< usart id bit num fixed 4 bits */ + USART_ID_RELATED_DATA_BIT = 0x01 /*!< usart id bit num related data bits */ +} usart_identification_bit_num_type; + +/** + * @brief usart de polarity type + */ +typedef enum +{ + USART_DE_POLARITY_HIGH = 0x00, /*!< usart de polarity high */ + USART_DE_POLARITY_LOW = 0x01 /*!< usart de polarity low */ +} usart_de_polarity_type; + +/** + * @brief type define usart register all + */ +typedef struct +{ + /** + * @brief usart sts register, offset:0x00 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t perr : 1; /* [0] */ + __IO uint32_t ferr : 1; /* [1] */ + __IO uint32_t nerr : 1; /* [2] */ + __IO uint32_t roerr : 1; /* [3] */ + __IO uint32_t idlef : 1; /* [4] */ + __IO uint32_t rdbf : 1; /* [5] */ + __IO uint32_t tdc : 1; /* [6] */ + __IO uint32_t tdbe : 1; /* [7] */ + __IO uint32_t bff : 1; /* [8] */ + __IO uint32_t ctscf : 1; /* [9] */ + __IO uint32_t reserved1 : 22;/* [31:10] */ + } sts_bit; + }; + + /** + * @brief usart dt register, offset:0x04 + */ + union + { + __IO uint32_t dt; + struct + { + __IO uint32_t dt : 9; /* [8:0] */ + __IO uint32_t reserved1 : 23;/* [31:9] */ + } dt_bit; + }; + + /** + * @brief usart baudr register, offset:0x08 + */ + union + { + __IO uint32_t baudr; + struct + { + __IO uint32_t div : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } baudr_bit; + }; + + /** + * @brief usart ctrl1 register, offset:0x0C + */ + union + { + __IO uint32_t ctrl1; + struct + { + __IO uint32_t sbf : 1; /* [0] */ + __IO uint32_t rm : 1; /* [1] */ + __IO uint32_t ren : 1; /* [2] */ + __IO uint32_t ten : 1; /* [3] */ + __IO uint32_t idleien : 1; /* [4] */ + __IO uint32_t rdbfien : 1; /* [5] */ + __IO uint32_t tdcien : 1; /* [6] */ + __IO uint32_t tdbeien : 1; /* [7] */ + __IO uint32_t perrien : 1; /* [8] */ + __IO uint32_t psel : 1; /* [9] */ + __IO uint32_t pen : 1; /* [10] */ + __IO uint32_t wum : 1; /* [11] */ + __IO uint32_t dbn_l : 1; /* [12] */ + __IO uint32_t uen : 1; /* [13] */ + __IO uint32_t reserved1 : 2; /* [15:14] */ + __IO uint32_t tcdt : 5; /* [20:16] */ + __IO uint32_t tsdt : 5; /* [25:21] */ + __IO uint32_t reserved2 : 2; /* [27:26] */ + __IO uint32_t dbn_h : 1; /* [28] */ + __IO uint32_t reserved3 : 3; /* [31:29] */ + } ctrl1_bit; + }; + + /** + * @brief usart ctrl2 register, offset:0x10 + */ + union + { + __IO uint32_t ctrl2; + struct + { + __IO uint32_t id_l : 4; /* [3:0] */ + __IO uint32_t idbn : 1; /* [4] */ + __IO uint32_t bfbn : 1; /* [5] */ + __IO uint32_t bfien : 1; /* [6] */ + __IO uint32_t reserved1 : 1; /* [7] */ + __IO uint32_t lbcp : 1; /* [8] */ + __IO uint32_t clkpha : 1; /* [9] */ + __IO uint32_t clkpol : 1; /* [10] */ + __IO uint32_t clken : 1; /* [11] */ + __IO uint32_t stopbn : 2; /* [13:12] */ + __IO uint32_t linen : 1; /* [14] */ + __IO uint32_t trpswap : 1; /* [15] */ + __IO uint32_t reserved2 : 12;/* [27:16] */ + __IO uint32_t id_h : 4; /* [31:28] */ + } ctrl2_bit; + }; + + /** + * @brief usart ctrl3 register, offset:0x14 + */ + union + { + __IO uint32_t ctrl3; + struct + { + __IO uint32_t errien : 1; /* [0] */ + __IO uint32_t irdaen : 1; /* [1] */ + __IO uint32_t irdalp : 1; /* [2] */ + __IO uint32_t slben : 1; /* [3] */ + __IO uint32_t scnacken : 1; /* [4] */ + __IO uint32_t scmen : 1; /* [5] */ + __IO uint32_t dmaren : 1; /* [6] */ + __IO uint32_t dmaten : 1; /* [7] */ + __IO uint32_t rtsen : 1; /* [8] */ + __IO uint32_t ctsen : 1; /* [9] */ + __IO uint32_t ctscfien : 1; /* [10] */ + __IO uint32_t reserved1 : 3; /* [13:11] */ + __IO uint32_t rs485en : 1; /* [14] */ + __IO uint32_t dep : 1; /* [15] */ + __IO uint32_t reserved2 : 16;/* [31:16] */ + } ctrl3_bit; + }; + + /** + * @brief usart gdiv register, offset:0x18 + */ + union + { + __IO uint32_t gdiv; + struct + { + __IO uint32_t isdiv : 8; /* [7:0] */ + __IO uint32_t scgt : 8; /* [15:8] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } gdiv_bit; + }; +} usart_type; + +/** + * @} + */ + +#define USART1 ((usart_type *) USART1_BASE) +#define USART2 ((usart_type *) USART2_BASE) +#define USART3 ((usart_type *) USART3_BASE) +#define USART4 ((usart_type *) USART4_BASE) + +/** @defgroup USART_exported_functions + * @{ + */ + +void usart_reset(usart_type* usart_x); +void usart_init(usart_type* usart_x, uint32_t baud_rate, usart_data_bit_num_type data_bit, usart_stop_bit_num_type stop_bit); +void usart_parity_selection_config(usart_type* usart_x, usart_parity_selection_type parity); +void usart_enable(usart_type* usart_x, confirm_state new_state); +void usart_transmitter_enable(usart_type* usart_x, confirm_state new_state); +void usart_receiver_enable(usart_type* usart_x, confirm_state new_state); +void usart_clock_config(usart_type* usart_x, usart_clock_polarity_type clk_pol, usart_clock_phase_type clk_pha, usart_lbcp_type clk_lb); +void usart_clock_enable(usart_type* usart_x, confirm_state new_state); +void usart_interrupt_enable(usart_type* usart_x, uint32_t usart_int, confirm_state new_state); +void usart_dma_transmitter_enable(usart_type* usart_x, confirm_state new_state); +void usart_dma_receiver_enable(usart_type* usart_x, confirm_state new_state); +void usart_wakeup_id_set(usart_type* usart_x, uint8_t usart_id); +void usart_wakeup_mode_set(usart_type* usart_x, usart_wakeup_mode_type wakeup_mode); +void usart_receiver_mute_enable(usart_type* usart_x, confirm_state new_state); +void usart_break_bit_num_set(usart_type* usart_x, usart_break_bit_num_type break_bit); +void usart_lin_mode_enable(usart_type* usart_x, confirm_state new_state); +void usart_data_transmit(usart_type* usart_x, uint16_t data); +uint16_t usart_data_receive(usart_type* usart_x); +void usart_break_send(usart_type* usart_x); +void usart_smartcard_guard_time_set(usart_type* usart_x, uint8_t guard_time_val); +void usart_irda_smartcard_division_set(usart_type* usart_x, uint8_t div_val); +void usart_smartcard_mode_enable(usart_type* usart_x, confirm_state new_state); +void usart_smartcard_nack_set(usart_type* usart_x, confirm_state new_state); +void usart_single_line_halfduplex_select(usart_type* usart_x, confirm_state new_state); +void usart_irda_mode_enable(usart_type* usart_x, confirm_state new_state); +void usart_irda_low_power_enable(usart_type* usart_x, confirm_state new_state); +void usart_hardware_flow_control_set(usart_type* usart_x,usart_hardware_flow_control_type flow_state); +flag_status usart_flag_get(usart_type* usart_x, uint32_t flag); +flag_status usart_interrupt_flag_get(usart_type* usart_x, uint32_t flag); +void usart_flag_clear(usart_type* usart_x, uint32_t flag); +void usart_rs485_delay_time_config(usart_type* usart_x, uint8_t start_delay_time, uint8_t complete_delay_time); +void usart_transmit_receive_pin_swap(usart_type* usart_x, confirm_state new_state); +void usart_id_bit_num_set(usart_type* usart_x, usart_identification_bit_num_type id_bit_num); +void usart_de_polarity_set(usart_type* usart_x, usart_de_polarity_type de_polarity); +void usart_rs485_mode_enable(usart_type* usart_x, confirm_state new_state); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_usb.h b/libraries/drivers/inc/at32f425_usb.h new file mode 100644 index 0000000..b6e5d2c --- /dev/null +++ b/libraries/drivers/inc/at32f425_usb.h @@ -0,0 +1,1421 @@ +/** + ************************************************************************** + * @file at32f425_usb.h + * @brief at32f425 usb header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_USB_H +#define __AT32F425_USB_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup USB + * @{ + */ + +/** @defgroup USB_global_interrupts_definition + * @brief usb global interrupt mask + * @{ + */ + +#define USB_OTG_MODEMIS_INT ((uint32_t)0x00000002) /*!< usb otg mode mismatch interrupt */ +#define USB_OTG_OTGINT_INT ((uint32_t)0x00000004) /*!< usb otg interrupt */ +#define USB_OTG_SOF_INT ((uint32_t)0x00000008) /*!< usb otg sof interrupt */ +#define USB_OTG_RXFLVL_INT ((uint32_t)0x00000010) /*!< usb otg receive fifo non-empty interrupt */ +#define USB_OTG_NPTXFEMP_INT ((uint32_t)0x00000020) /*!< usb otg non-periodic tx fifo empty interrupt */ +#define USB_OTG_GINNAKEFF_INT ((uint32_t)0x00000040) /*!< usb otg global non-periodic in nak effective interrupt */ +#define USB_OTG_GOUTNAKEFF_INT ((uint32_t)0x00000080) /*!< usb otg global out nak effective interrupt */ +#define USB_OTG_ERLYSUSP_INT ((uint32_t)0x00000400) /*!< usb otg early suspend interrupt */ +#define USB_OTG_USBSUSP_INT ((uint32_t)0x00000800) /*!< usb otg suspend interrupt */ +#define USB_OTG_USBRST_INT ((uint32_t)0x00001000) /*!< usb otg reset interrupt */ +#define USB_OTG_ENUMDONE_INT ((uint32_t)0x00002000) /*!< usb otg enumeration done interrupt */ +#define USB_OTG_ISOOUTDROP_INT ((uint32_t)0x00004000) /*!< usb otg isochronous out packet dropped interrut */ +#define USB_OTG_EOPF_INT ((uint32_t)0x00008000) /*!< usb otg eop interrupt */ +#define USB_OTG_IEPT_INT ((uint32_t)0x00040000) /*!< usb otg in endpoint interrupt */ +#define USB_OTG_OEPT_INT ((uint32_t)0x00080000) /*!< usb otg out endpoint interrupt */ +#define USB_OTG_INCOMISOIN_INT ((uint32_t)0x00100000) /*!< usb otg incomplete isochronous in transfer interrupt */ +#define USB_OTG_INCOMPIP_INCOMPISOOUT_INT ((uint32_t)0x00200000) /*!< usb otg incomplete periodic transfer/isochronous out interrupt */ +#define USB_OTG_PRT_INT ((uint32_t)0x01000000) /*!< usb otg host port interrupt */ +#define USB_OTG_HCH_INT ((uint32_t)0x02000000) /*!< usb otg host channel interrupt */ +#define USB_OTG_PTXFEMP_INT ((uint32_t)0x04000000) /*!< usb otg periodic txfifo empty interrupt */ +#define USB_OTG_CONIDSCHG_INT ((uint32_t)0x10000000) /*!< usb otg connector id status change interrupt */ +#define USB_OTG_DISCON_INT ((uint32_t)0x20000000) /*!< usb otg disconnect detected interrupt */ +#define USB_OTG_WKUP_INT ((uint32_t)0x80000000) /*!< usb otg wakeup interrupt */ + +/** + * @} + */ + +/** @defgroup USB_global_interrupt_flags_definition + * @brief usb global interrupt flag + * @{ + */ + +#define USB_OTG_CURMODE ((uint32_t)0x00000001) /*!< usb otg current mode */ +#define USB_OTG_MODEMIS_FLAG ((uint32_t)0x00000002) /*!< usb otg mode mismatch flag */ +#define USB_OTG_OTGINT_FLAG ((uint32_t)0x00000004) /*!< usb otg flag */ +#define USB_OTG_SOF_FLAG ((uint32_t)0x00000008) /*!< usb otg sof flag */ +#define USB_OTG_RXFLVL_FLAG ((uint32_t)0x00000010) /*!< usb otg receive fifo non-empty flag */ +#define USB_OTG_NPTXFEMP_FLAG ((uint32_t)0x00000020) /*!< usb otg non-periodic tx fifo empty flag */ +#define USB_OTG_GINNAKEFF_FLAG ((uint32_t)0x00000040) /*!< usb otg global non-periodic in nak effective flag */ +#define USB_OTG_GOUTNAKEFF_FLAG ((uint32_t)0x00000080) /*!< usb otg global out nak effective flag */ +#define USB_OTG_ERLYSUSP_FLAG ((uint32_t)0x00000400) /*!< usb otg early suspend flag */ +#define USB_OTG_USBSUSP_FLAG ((uint32_t)0x00000800) /*!< usb otg suspend flag */ +#define USB_OTG_USBRST_FLAG ((uint32_t)0x00001000) /*!< usb otg reset flag */ +#define USB_OTG_ENUMDONE_FLAG ((uint32_t)0x00002000) /*!< usb otg enumeration done flag */ +#define USB_OTG_ISOOUTDROP_FLAG ((uint32_t)0x00004000) /*!< usb otg isochronous out packet dropped flag */ +#define USB_OTG_EOPF_FLAG ((uint32_t)0x00008000) /*!< usb otg eop flag */ +#define USB_OTG_IEPT_FLAG ((uint32_t)0x00040000) /*!< usb otg in endpoint flag */ +#define USB_OTG_OEPT_FLAG ((uint32_t)0x00080000) /*!< usb otg out endpoint flag */ +#define USB_OTG_INCOMISOIN_FLAG ((uint32_t)0x00100000) /*!< usb otg incomplete isochronous in transfer flag */ +#define USB_OTG_INCOMPIP_INCOMPISOOUT_FLAG ((uint32_t)0x00200000) /*!< usb otg incomplete periodic transfer/isochronous out flag */ +#define USB_OTG_PRT_FLAG ((uint32_t)0x01000000) /*!< usb otg host port flag */ +#define USB_OTG_HCH_FLAG ((uint32_t)0x02000000) /*!< usb otg host channel flag */ +#define USB_OTG_PTXFEMP_FLAG ((uint32_t)0x04000000) /*!< usb otg periodic txfifo empty flag */ +#define USB_OTG_CONIDSCHG_FLAG ((uint32_t)0x10000000) /*!< usb otg connector id status change flag */ +#define USB_OTG_DISCON_FLAG ((uint32_t)0x20000000) /*!< usb otg disconnect detected flag */ +#define USB_OTG_WKUP_FLAG ((uint32_t)0x80000000) /*!< usb otg wakeup flag */ + +/** + * @} + */ + + +/** @defgroup USB_global_setting_definition + * @brief usb global setting + * @{ + */ + +/** + * @brief usb turnaround time + */ +#define USB_TRDTIM_8 0x9 /*!< usb turn around time 8 */ +#define USB_TRDTIM_16 0x5 /*!< usb turn around time 16 */ + +/** + * @brief usb receive status + */ +#define USB_OTG_GRXSTSP_EPTNUM ((uint32_t)0x0000000F) /*!< usb device receive packet endpoint number*/ +#define USB_OTG_GRXSTSP_CHNUM ((uint32_t)0x0000000F) /*!< usb host receive packet channel number*/ +#define USB_OTG_GRXSTSP_BCNT ((uint32_t)0x00007FF0) /*!< usb receive packet byte count */ +#define USB_OTG_GRXSTSP_DPID ((uint32_t)0x00018000) /*!< usb receive packet pid */ +#define USB_OTG_GRXSTSP_PKTSTS ((uint32_t)0x001E0000) /*!< usb receive packet status */ + +/** + * @brief usb host packet status + */ +#define PKTSTS_IN_DATA_PACKET_RECV 0x2 /*!< usb host in data packet received */ +#define PKTSTS_IN_TRANSFER_COMPLETE 0x3 /*!< usb host in transfer completed */ +#define PKTSTS_DATA_BIT_ERROR 0x5 /*!< usb host data toggle error */ +#define PKTSTS_CHANNEL_STOP 0x7 /*!< usb host channel halted */ + +/** + * @brief usb device packet status + */ +#define USB_OUT_STS_NAK 0x1 /*!< usb device global out nak */ +#define USB_OUT_STS_DATA 0x2 /*!< usb device out data packet received */ +#define USB_OUT_STS_COMP 0x3 /*!< usb device out transfer completed */ +#define USB_SETUP_STS_COMP 0x4 /*!< usb device setup transcation completed */ +#define USB_SETUP_STS_DATA 0x6 /*!< usb device setup data packet received */ + +/** + * @} + */ + +/** @defgroup USB_host_config_definition + * @{ + */ + +/** + * @brief usb host phy clock + */ +#define USB_HCFG_CLK_60M 0 /*!< usb host phy clock 60mhz */ +#define USB_HCFG_CLK_48M 1 /*!< usb host phy clock 48mhz */ +#define USB_HCFG_CLK_6M 2 /*!< usb host phy clock 6mhz */ + +/** + * @brief usb host port status + */ +#define USB_OTG_HPRT_PRTCONSTS ((uint32_t)0x00000001) /*!< usb host port connect status */ +#define USB_OTG_HPRT_PRTCONDET ((uint32_t)0x00000002) /*!< usb host port connect detected */ +#define USB_OTG_HPRT_PRTENA ((uint32_t)0x00000004) /*!< usb host port enable */ +#define USB_OTG_HPRT_PRTENCHNG ((uint32_t)0x00000008) /*!< usb host port enable/disable change */ +#define USB_OTG_HPRT_PRTOVRCACT ((uint32_t)0x00000010) /*!< usb host port overcurrent active */ +#define USB_OTG_HPRT_PRTOVRCCHNG ((uint32_t)0x00000020) /*!< usb host port overcurrent change */ +#define USB_OTG_HPRT_PRTRES ((uint32_t)0x00000040) /*!< usb host port resume */ +#define USB_OTG_HPRT_PRTSUSP ((uint32_t)0x00000080) /*!< usb host port suspend */ +#define USB_OTG_HPRT_PRTRST ((uint32_t)0x00000100) /*!< usb host port reset */ +#define USB_OTG_HPRT_PRTLNSTS ((uint32_t)0x00000C00) /*!< usb host port line status */ +#define USB_OTG_HPRT_PRTPWR ((uint32_t)0x00001000) /*!< usb host port power */ +#define USB_OTG_HPRT_PRTSPD ((uint32_t)0x00060000) /*!< usb host port speed */ + +/** + * @brief usb port speed + */ +#define USB_PRTSPD_HIGH_SPEED 0 /*!< usb host port high speed */ +#define USB_PRTSPD_FULL_SPEED 1 /*!< usb host port full speed */ +#define USB_PRTSPD_LOW_SPEED 2 /*!< usb host port low speed */ + +/** + * @brief usb host register hcchar bit define + */ +#define USB_OTG_HCCHAR_MPS ((uint32_t)0x000007FF) /*!< channel maximum packet size */ +#define USB_OTG_HCCHAR_EPTNUM ((uint32_t)0x00007800) /*!< endpoint number */ +#define USB_OTG_HCCHAR_EPTDIR ((uint32_t)0x00008000) /*!< endpoint direction */ +#define USB_OTG_HCCHAR_LSPDDEV ((uint32_t)0x00020000) /*!< low speed device */ +#define USB_OTG_HCCHAR_EPTYPE ((uint32_t)0x000C0000) /*!< endpoint type */ +#define USB_OTG_HCCHAR_MC ((uint32_t)0x00300000) /*!< multi count */ +#define USB_OTG_HCCHAR_DEVADDR ((uint32_t)0x1FC00000) /*!< device address */ +#define USB_OTG_HCCHAR_ODDFRM ((uint32_t)0x20000000) /*!< odd frame */ +#define USB_OTG_HCCHAR_CHDIS ((uint32_t)0x40000000) /*!< channel disable */ +#define USB_OTG_HCCHAR_CHENA ((uint32_t)0x80000000) /*!< channel enable */ + +/** + * @brief usb host register hctsiz bit define + */ +#define USB_OTG_HCTSIZ_XFERSIZE ((uint32_t)0x0007FFFF) /*!< channel transfer size */ +#define USB_OTG_HCTSIZ_PKTCNT ((uint32_t)0x1FF80000) /*!< channel packet count */ +#define USB_OTG_HCTSIZ_PID ((uint32_t)0x60000000) /*!< channel pid */ + +/** + * @brief usb host channel interrupt mask + */ +#define USB_OTG_HC_XFERCM_INT ((uint32_t)0x00000001) /*!< channel transfer complete interrupt */ +#define USB_OTG_HC_CHHLTDM_INT ((uint32_t)0x00000002) /*!< channel halted interrupt */ +#define USB_OTG_HC_STALLM_INT ((uint32_t)0x00000008) /*!< channel stall interrupt */ +#define USB_OTG_HC_NAKM_INT ((uint32_t)0x00000010) /*!< channel nak interrupt */ +#define USB_OTG_HC_ACKM_INT ((uint32_t)0x00000020) /*!< channel ack interrupt */ +#define USB_OTG_HC_NYETM_INT ((uint32_t)0x00000040) /*!< channel nyet interrupt */ +#define USB_OTG_HC_XACTERRM_INT ((uint32_t)0x00000080) /*!< channel transaction error interrupt */ +#define USB_OTG_HC_BBLERRM_INT ((uint32_t)0x00000100) /*!< channel babble error interrupt */ +#define USB_OTG_HC_FRMOVRRUN_INT ((uint32_t)0x00000200) /*!< channel frame overrun interrupt */ +#define USB_OTG_HC_DTGLERRM_INT ((uint32_t)0x00000400) /*!< channel data toggle interrupt */ + +/** + * @brief usb host channel interrupt flag + */ +#define USB_OTG_HC_XFERC_FLAG ((uint32_t)0x00000001) /*!< channel transfer complete flag */ +#define USB_OTG_HC_CHHLTD_FLAG ((uint32_t)0x00000002) /*!< channel halted flag */ +#define USB_OTG_HC_STALL_FLAG ((uint32_t)0x00000008) /*!< channel stall flag */ +#define USB_OTG_HC_NAK_FLAG ((uint32_t)0x00000010) /*!< channel nak flag */ +#define USB_OTG_HC_ACK_FLAG ((uint32_t)0x00000020) /*!< channel ack flag */ +#define USB_OTG_HC_NYET_FLAG ((uint32_t)0x00000040) /*!< channel nyet flag */ +#define USB_OTG_HC_XACTERR_FLAG ((uint32_t)0x00000080) /*!< channel transaction error flag */ +#define USB_OTG_HC_BBLERR_FLAG ((uint32_t)0x00000100) /*!< channel babble error flag */ +#define USB_OTG_HC_FRMOVRRUN_FLAG ((uint32_t)0x00000200) /*!< channel frame overrun flag */ +#define USB_OTG_HC_DTGLERR_FLAG ((uint32_t)0x00000400) /*!< channel data toggle flag */ + +/** + * @} + */ + + +/** @defgroup USB_device_config_definition + * @{ + */ +/** + * @brief usb device periodic frame interval + */ +typedef enum +{ + DCFG_PERFRINT_80 = 0x00, /*!< periodic frame interval 80% */ + DCFG_PERFRINT_85 = 0x01, /*!< periodic frame interval 85% */ + DCFG_PERFRINT_90 = 0x02, /*!< periodic frame interval 90% */ + DCFG_PERFRINT_95 = 0x03 /*!< periodic frame interval 95% */ +} dcfg_perfrint_type; + + +/** + * @brief usb device full speed + */ +#define USB_DCFG_FULL_SPEED 3 /*!< device full speed */ + +/** + * @brief usb device ctrl define + */ +#define USB_OTG_DCTL_RWKUPSIG ((uint32_t)0x00000001) /*!< usb device remote wakeup signaling */ +#define USB_OTG_DCTL_SFTDISCON ((uint32_t)0x00000002) /*!< usb device soft disconnect */ +#define USB_OTG_DCTL_GNPINNAKSTS ((uint32_t)0x00000004) /*!< usb device global non-periodic in nak status */ +#define USB_OTG_DCTL_GOUTNAKSTS ((uint32_t)0x00000008) /*!< usb device global out nak status */ +#define USB_OTG_DCTL_SGNPINNAK ((uint32_t)0x00000080) /*!< usb device set global non-periodic in nak */ +#define USB_OTG_DCTL_CGNPINNAK ((uint32_t)0x00000100) /*!< usb device clear global non-periodic in nak */ +#define USB_OTG_DCTL_SGOUTNAK ((uint32_t)0x00000200) /*!< usb device set global out nak status */ +#define USB_OTG_DCTL_CGOUTNAK ((uint32_t)0x00000400) /*!< usb device clear global out nak status */ +#define USB_OTG_DCTL_PWROPRGDNE ((uint32_t)0x00000800) /*!< usb device power on programming done */ + +/** + * @brief usb device in endpoint flag + */ +#define USB_OTG_DIEPINT_XFERC_FLAG ((uint32_t)0x00000001) /*!< usb device in transfer completed flag */ +#define USB_OTG_DIEPINT_EPTDISD_FLAG ((uint32_t)0x00000002) /*!< usb device endpoint disable flag */ +#define USB_OTG_DIEPINT_TIMEOUT_FLAG ((uint32_t)0x00000008) /*!< usb device in timeout */ +#define USB_OTG_DIEPINT_INTKNTXFEMP_FLAG ((uint32_t)0x00000010) /*!< usb device in token received when tx fifo is empty flag */ +#define USB_OTG_DIEPINT_INEPTNAK_FLAG ((uint32_t)0x00000040) /*!< usb device in endpoint nak effective flag */ +#define USB_OTG_DIEPINT_TXFEMP_FLAG ((uint32_t)0x00000080) /*!< usb device transmit fifo empty flag */ + +/** + * @brief usb device out endpoint flag + */ +#define USB_OTG_DOEPINT_XFERC_FLAG ((uint32_t)0x00000001) /*!< usb device out transfer completed flag */ +#define USB_OTG_DOEPINT_EPTDISD_FLAG ((uint32_t)0x00000002) /*!< usb device endpoint disable flag */ +#define USB_OTG_DOEPINT_SETUP_FLAG ((uint32_t)0x00000008) /*!< usb device setup flag */ +#define USB_OTG_DOEPINT_OUTTEPD_FLAG ((uint32_t)0x00000010) /*!< usb device out token recevied when endpoint disable flag */ +#define USB_OTG_DOEPINT_B2BSTUP_FLAG ((uint32_t)0x00000040) /*!< back-to-back setup packets received */ + +/** + * @brief usb device in endpoint fifo space mask + */ +#define USB_OTG_DTXFSTS_INEPTFSAV ((uint32_t)0x0000FFFF) /*!< usb device in endpoint tx fifo space avail */ + +/** + * @brief endpoint0 maximum packet size + */ +#define USB_EPT0_MPS_64 0 /*!< usb device endpoint 0 maximum packet size 64byte */ +#define USB_EPT0_MPS_32 1 /*!< usb device endpoint 0 maximum packet size 32byte */ +#define USB_EPT0_MPS_16 2 /*!< usb device endpoint 0 maximum packet size 16byte */ +#define USB_EPT0_MPS_8 3 /*!< usb device endpoint 0 maximum packet size 8byte */ + +/** + * @} + */ + +/** + * @brief otg fifo size (word) + */ +#define OTG_FIFO_SIZE 320 /*!< otg usb total fifo size */ + +/** + * @brief otg host max buffer length (byte) + */ +#define USB_MAX_DATA_LENGTH 0x200 /*!< usb host maximum buffer size */ + +#define OTGFS_USB_GLOBAL +#define OTGFS_USB_DEVICE +#define OTGFS_USB_HOST + +/** @defgroup USB_exported_enum_types + * @{ + */ + +/** + * @brief usb mode define(device, host, drd) + */ +typedef enum +{ + OTG_DEVICE_MODE, /*!< usb device mode */ + OTG_HOST_MODE, /*!< usb host mode */ + OTG_DRD_MODE /*!< usb drd mode */ +} otg_mode_type; + +/** + * @brief endpoint type define + */ +typedef enum +{ + EPT_CONTROL_TYPE = 0x00, /*!< usb endpoint type control */ + EPT_ISO_TYPE = 0x01, /*!< usb endpoint type iso */ + EPT_BULK_TYPE = 0x02, /*!< usb endpoint type bulk */ + EPT_INT_TYPE = 0x03 /*!< usb endpoint type interrupt */ +} endpoint_trans_type; + +/** + * @brief usb endpoint number define type + */ +typedef enum +{ + USB_EPT0 = 0x00, /*!< usb endpoint 0 */ + USB_EPT1 = 0x01, /*!< usb endpoint 1 */ + USB_EPT2 = 0x02, /*!< usb endpoint 2 */ + USB_EPT3 = 0x03, /*!< usb endpoint 3 */ + USB_EPT4 = 0x04, /*!< usb endpoint 4 */ + USB_EPT5 = 0x05, /*!< usb endpoint 5 */ + USB_EPT6 = 0x06, /*!< usb endpoint 6 */ + USB_EPT7 = 0x07 /*!< usb endpoint 7 */ +} usb_endpoint_number_type; + +/** + * @brief usb endpoint max num define + */ +#ifndef USB_EPT_MAX_NUM +#define USB_EPT_MAX_NUM 8 /*!< usb device support endpoint number */ +#endif +/** + * @brief usb channel max num define + */ +#ifndef USB_HOST_CHANNEL_NUM +#define USB_HOST_CHANNEL_NUM 16 /*!< usb host support channel number */ +#endif + +/** + * @brief endpoint trans dir type + */ +typedef enum +{ + EPT_DIR_IN = 0x00, /*!< usb transfer direction in */ + EPT_DIR_OUT = 0x01 /*!< usb transfer direction out */ +} endpoint_dir_type; + +/** + * @brief otgfs1 and otgfs2 select type + */ +typedef enum +{ + USB_OTG1_ID, /*!< usb otg 1 id */ + USB_OTG2_ID /*!< usb otg 2 id */ +} otg_id_type; + +/** + * @brief usb clock select + */ +typedef enum +{ + USB_CLK_HICK, /*!< usb clock use hick */ + USB_CLK_HEXT /*!< usb clock use hext */ +}usb_clk48_s; + +/** + * @} + */ + + + +/** @defgroup USB_exported_types + * @{ + */ + +/** + * @brief usb endpoint infomation structure definition + */ +typedef struct +{ + uint8_t eptn; /*!< endpoint register number (0~7) */ + uint8_t ept_address; /*!< endpoint address */ + uint8_t inout; /*!< endpoint dir EPT_DIR_IN or EPT_DIR_OUT */ + uint8_t trans_type; /*!< endpoint type: + EPT_CONTROL_TYPE, EPT_BULK_TYPE, EPT_INT_TYPE, EPT_ISO_TYPE*/ + uint16_t tx_addr; /*!< endpoint tx buffer offset address */ + uint16_t rx_addr; /*!< endpoint rx buffer offset address */ + uint32_t maxpacket; /*!< endpoint max packet*/ + uint8_t is_double_buffer; /*!< endpoint double buffer flag */ + uint8_t stall; /*!< endpoint is stall state */ + uint32_t status; + + /* transmission buffer and count */ + uint8_t *trans_buf; /*!< endpoint transmission buffer */ + uint32_t total_len; /*!< endpoint transmission lengtg */ + uint32_t trans_len; /*!< endpoint transmission length*/ + + uint32_t last_len; /*!< last transfer length */ + uint32_t rem0_len; /*!< rem transfer length */ + uint32_t ept0_slen; /*!< endpoint 0 transfer sum length */ +} usb_ept_info; + + +/** + * @brief usb host channel infomation structure definition + */ +typedef struct +{ + uint8_t ch_num; /*!< host channel number */ + uint8_t address; /*!< device address */ + uint8_t dir; /*!< transmission direction */ + uint8_t ept_num; /*!< device endpoint number */ + uint8_t ept_type; /*!< channel transmission type */ + uint32_t maxpacket; /*!< support max packet size */ + uint8_t data_pid; /*!< data pid */ + uint8_t speed; /*!< usb speed */ + uint8_t stall; /*!< channel stall flag */ + uint32_t status; /*!< channel status */ + uint32_t state; /*!< channel state */ + uint32_t urb_sts; /*!< usb channel request block state */ + + uint8_t toggle_in; /*!< channel in transfer toggle */ + uint8_t toggle_out; /*!< channel out transfer toggle */ + + /* transmission buffer and count */ + uint8_t *trans_buf; /* host channel buffer */ + uint32_t trans_len; /* host channel transmission len */ + uint32_t trans_count; /* host channel transmission count*/ +} usb_hch_type; + + +typedef struct +{ + /** + * @brief otgfs control and status register, offset:0x00 + */ + union + { + __IO uint32_t gotgctrl; + struct + { + __IO uint32_t reserved1 : 16; /* [15:0] */ + __IO uint32_t cidsts : 1; /* [16] */ + __IO uint32_t reserved2 : 4; /* [20:17] */ + __IO uint32_t curmod : 1; /* [21] */ + __IO uint32_t reserved3 : 10; /* [31:22] */ + } gotgctrl_bit; + }; + + /** + * @brief otgfs interrupt register, offset:0x04 + */ + union + { + __IO uint32_t gotgint; + struct + { + __IO uint32_t reserved1 : 2; /* [1:0] */ + __IO uint32_t sesenddet : 1; /* [2] */ + __IO uint32_t reserved2 : 29; /* [31:3] */ + + } gotgint_bit; + }; + + /** + * @brief otgfs gahbcfg configuration register, offset:0x08 + */ + union + { + __IO uint32_t gahbcfg; + struct + { + __IO uint32_t glbintmsk : 1; /* [0] */ + __IO uint32_t reserved1 : 6; /* [6:1] */ + __IO uint32_t nptxfemplvl : 1; /* [7] */ + __IO uint32_t ptxfemplvl : 1; /* [8] */ + __IO uint32_t reserved2 : 23; /* [31:9] */ + } gahbcfg_bit; + }; + + /** + * @brief otgfs usb configuration register, offset:0x0C + */ + union + { + __IO uint32_t gusbcfg; + struct + { + __IO uint32_t toutcal : 3; /* [2:0] */ + __IO uint32_t reserved1 : 7; /* [9:3] */ + __IO uint32_t usbtrdtim : 4; /* [13:10] */ + __IO uint32_t reserved2 : 15; /* [28:14] */ + __IO uint32_t fhstmode : 1; /* [29] */ + __IO uint32_t fdevmode : 1; /* [30] */ + __IO uint32_t cotxpkt : 1; /* [31] */ + } gusbcfg_bit; + }; + + /** + * @brief otgfs reset register, offset:0x10 + */ + union + { + __IO uint32_t grstctl; + struct + { + __IO uint32_t csftrst : 1; /* [0] */ + __IO uint32_t piusftrst : 1; /* [1] */ + __IO uint32_t frmcntrst : 1; /* [2] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t rxfflsh : 1; /* [4] */ + __IO uint32_t txfflsh : 1; /* [5] */ + __IO uint32_t txfnum : 5; /* [10:6] */ + __IO uint32_t reserved2 : 20; /* [30:11] */ + __IO uint32_t ahbidle : 1; /* [31] */ + } grstctl_bit; + }; + + /** + * @brief otgfs core interrupt register, offset:0x14 + */ + union + { + __IO uint32_t gintsts; + struct + { + __IO uint32_t curmode : 1; /* [0] */ + __IO uint32_t modemis : 1; /* [1] */ + __IO uint32_t otgint : 1; /* [2] */ + __IO uint32_t sof : 1; /* [3] */ + __IO uint32_t rxflvl : 1; /* [4] */ + __IO uint32_t nptxfemp : 1; /* [5] */ + __IO uint32_t ginnakeff : 1; /* [6] */ + __IO uint32_t goutnakeff : 1; /* [7] */ + __IO uint32_t reserved1 : 2; /* [9:8]] */ + __IO uint32_t erlysusp : 1; /* [10] */ + __IO uint32_t usbsusp : 1; /* [11] */ + __IO uint32_t usbrst : 1; /* [12] */ + __IO uint32_t enumdone : 1; /* [13] */ + __IO uint32_t isooutdrop : 1; /* [14] */ + __IO uint32_t eopf : 1; /* [15] */ + __IO uint32_t reserved2 : 2; /* [17:16]] */ + __IO uint32_t ieptint : 1; /* [18] */ + __IO uint32_t oeptint : 1; /* [19] */ + __IO uint32_t incompisoin : 1; /* [20] */ + __IO uint32_t incompip_incompisoout : 1; /* [21] */ + __IO uint32_t reserved3 : 2; /* [23:22] */ + __IO uint32_t prtint : 1; /* [24] */ + __IO uint32_t hchint : 1; /* [25] */ + __IO uint32_t ptxfemp : 1; /* [26] */ + __IO uint32_t reserved4 : 1; /* [27] */ + __IO uint32_t conidschg : 1; /* [28] */ + __IO uint32_t disconint : 1; /* [29] */ + __IO uint32_t reserved5 : 1; /* [30] */ + __IO uint32_t wkupint : 1; /* [31] */ + } gintsts_bit; + }; + + /** + * @brief otgfs interrupt mask register, offset:0x18 + */ + union + { + __IO uint32_t gintmsk; + struct + { + __IO uint32_t reserved1 : 1; /* [0] */ + __IO uint32_t modemismsk : 1; /* [1] */ + __IO uint32_t otgintmsk : 1; /* [2] */ + __IO uint32_t sofmsk : 1; /* [3] */ + __IO uint32_t rxflvlmsk : 1; /* [4] */ + __IO uint32_t nptxfempmsk : 1; /* [5] */ + __IO uint32_t ginnakeffmsk : 1; /* [6] */ + __IO uint32_t goutnakeffmsk : 1; /* [7] */ + __IO uint32_t reserved2 : 2; /* [9:8]] */ + __IO uint32_t erlysuspmsk : 1; /* [10] */ + __IO uint32_t usbsuspmsk : 1; /* [11] */ + __IO uint32_t usbrstmsk : 1; /* [12] */ + __IO uint32_t enumdonemsk : 1; /* [13] */ + __IO uint32_t isooutdropmsk : 1; /* [14] */ + __IO uint32_t eopfmsk : 1; /* [15] */ + __IO uint32_t reserved3 : 2; /* [17:16]] */ + __IO uint32_t ieptintmsk : 1; /* [18] */ + __IO uint32_t oeptintmsk : 1; /* [19] */ + __IO uint32_t incompisoinmsk : 1; /* [20] */ + __IO uint32_t incompip_incompisooutmsk : 1; /* [21] */ + __IO uint32_t reserved4 : 2; /* [23:22] */ + __IO uint32_t prtintmsk : 1; /* [24] */ + __IO uint32_t hchintmsk : 1; /* [25] */ + __IO uint32_t ptxfempmsk : 1; /* [26] */ + __IO uint32_t reserved5 : 1; /* [27] */ + __IO uint32_t conidschgmsk : 1; /* [28] */ + __IO uint32_t disconintmsk : 1; /* [29] */ + __IO uint32_t reserved6 : 1; /* [30] */ + __IO uint32_t wkupintmsk : 1; /* [31] */ + } gintmsk_bit; + }; + + /** + * @brief otgfs rx status debug read register, offset:0x1C + */ + union + { + __IO uint32_t grxstsr; + struct + { + __IO uint32_t eptnum : 4; /* [3:0] */ + __IO uint32_t bcnt : 11; /* [14:4] */ + __IO uint32_t dpid : 2; /* [16:15] */ + __IO uint32_t pktsts : 4; /* [20:17] */ + __IO uint32_t fn : 4; /* [24:21] */ + __IO uint32_t reserved1 : 7; /* [31:25] */ + } grxstsr_bit; + }; + + /** + * @brief otgfs rx status read and pop register, offset:0x20 + */ + union + { + __IO uint32_t grxstsp; + struct + { + __IO uint32_t chnum : 4; /* [3:0] */ + __IO uint32_t bcnt : 11; /* [14:4] */ + __IO uint32_t dpid : 2; /* [16:15] */ + __IO uint32_t pktsts : 4; /* [20:17] */ + __IO uint32_t reserved1 : 11; /* [31:21] */ + } grxstsp_bit; + }; + + /** + * @brief otgfs rx fifo size register, offset:0x24 + */ + union + { + __IO uint32_t grxfsiz; + struct + { + __IO uint32_t rxfdep : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } grxfsiz_bit; + }; + + /** + * @brief otgfs non-periodic and ept0 tx fifo size register, offset:0x28 + */ + union + { + __IO uint32_t gnptxfsiz_ept0tx; + struct + { + __IO uint32_t nptxfstaddr : 16; /* [15:0] */ + __IO uint32_t nptxfdep : 16; /* [31:16] */ + } gnptxfsiz_ept0tx_bit; + }; + + /** + * @brief otgfs non-periodic tx fifo request queue status register, offset:0x2C + */ + union + { + __IO uint32_t gnptxsts; + struct + { + __IO uint32_t nptxfspcavail : 16; /* [15:0] */ + __IO uint32_t nptxqspcavail : 8; /* [23:16] */ + __IO uint32_t nptxqtop : 7; /* [30:24] */ + __IO uint32_t reserved1 : 1; /* [31] */ + } gnptxsts_bit; + }; + + __IO uint32_t reserved2[2]; + + /** + * @brief otgfs general core configuration register, offset:0x38 + */ + union + { + __IO uint32_t gccfg; + struct + { + __IO uint32_t reserved1 : 16; /* [15:0] */ + __IO uint32_t pwrdown : 1; /* [16] */ + __IO uint32_t lp_mode : 1; /* [17] */ + __IO uint32_t reserved2 : 2; /* [19:18] */ + __IO uint32_t sofouten : 1; /* [20] */ + __IO uint32_t vbusig : 1; /* [21] */ + __IO uint32_t reserved3 : 10; /* [31:22] */ + } gccfg_bit; + }; + + /** + * @brief otgfs core id register, offset:0x3C + */ + union + { + __IO uint32_t guid; + struct + { + __IO uint32_t userid : 32; /* [31:0] */ + } guid_bit; + }; + + __IO uint32_t reserved3[48]; + + /** + * @brief otgfs host periodic tx fifo size register, offset:0x100 + */ + union + { + __IO uint32_t hptxfsiz; + struct + { + __IO uint32_t ptxfstaddr : 16; /* [15:0] */ + __IO uint32_t ptxfsize : 16; /* [31:16] */ + } hptxfsiz_bit; + }; + + /** + * @brief otgfs host periodic tx fifo size register, offset:0x100 + */ + union + { + __IO uint32_t dieptxfn[7]; + struct + { + __IO uint32_t ineptxfstaddr : 16; /* [15:0] */ + __IO uint32_t ineptxfdep : 16; /* [31:16] */ + } dieptxfn_bit[7]; + }; +} otg_global_type; + + +typedef struct +{ + /** + * @brief otgfs host mode configuration register, offset:0x400 + */ + union + { + __IO uint32_t hcfg; + struct + { + __IO uint32_t fslspclksel : 2; /* [1:0] */ + __IO uint32_t fslssupp : 1; /* [2] */ + __IO uint32_t reserved1 : 29; /* [31:3] */ + } hcfg_bit; + }; + + /** + * @brief otgfs host frame interval register, offset:0x404 + */ + union + { + __IO uint32_t hfir; + struct + { + __IO uint32_t frint : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:15] */ + } hfir_bit; + }; + + /** + * @brief otgfs host frame number and time remaining register, offset:0x408 + */ + union + { + __IO uint32_t hfnum; + struct + { + __IO uint32_t frnum : 16; /* [15:0] */ + __IO uint32_t ftrem : 16; /* [31:15] */ + } hfnum_bit; + }; + + __IO uint32_t reserved1; + + /** + * @brief otgfs host periodic tx fifo request queue register, offset:0x410 + */ + union + { + __IO uint32_t hptxsts; + struct + { + __IO uint32_t ptxfspcavil : 16; /* [15:0] */ + __IO uint32_t ptxqspcavil : 8; /* [23:16] */ + __IO uint32_t ptxqtop : 8; /* [31:24] */ + } hptxsts_bit; + }; + + /** + * @brief otgfs host all channel interrupt register, offset:0x414 + */ + union + { + __IO uint32_t haint; + struct + { + __IO uint32_t haint : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [32:16] */ + } haint_bit; + }; + + /** + * @brief otgfs host all channel interrupt mask register, offset:0x418 + */ + union + { + __IO uint32_t haintmsk; + struct + { + __IO uint32_t haintmsk : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [32:16] */ + } haintmsk_bit; + }; + + __IO uint32_t reserved2[9]; + + /** + * @brief otgfs host port control and status register, offset:0x440 + */ + union + { + __IO uint32_t hprt; + struct + { + __IO uint32_t prtconsts : 1; /* [0] */ + __IO uint32_t prtcondet : 1; /* [1] */ + __IO uint32_t prtena : 1; /* [2] */ + __IO uint32_t prtenchng : 1; /* [3] */ + __IO uint32_t prtovrcact : 1; /* [4] */ + __IO uint32_t prtovrcchng : 1; /* [5] */ + __IO uint32_t prtres : 1; /* [6] */ + __IO uint32_t prtsusp : 1; /* [7] */ + __IO uint32_t prtrst : 1; /* [8] */ + __IO uint32_t reserved1 : 1; /* [9] */ + __IO uint32_t prtlnsts : 2; /* [11:10] */ + __IO uint32_t prtpwr : 1; /* [12] */ + __IO uint32_t prttsctl : 4; /* [16:13] */ + __IO uint32_t prtspd : 2; /* [18:17] */ + __IO uint32_t reserved2 : 13; /* [31:19] */ + + } hprt_bit; + }; +} otg_host_type; + +typedef struct +{ + /** + * @brief otgfs host channel x characterisic register, offset:0x500 + */ + union + { + __IO uint32_t hcchar; + struct + { + __IO uint32_t mps : 11; /* [10:0] */ + __IO uint32_t eptnum : 4; /* [14:11] */ + __IO uint32_t eptdir : 1; /* [15] */ + __IO uint32_t reserved1 : 1; /* [16] */ + __IO uint32_t lspddev : 1; /* [17] */ + __IO uint32_t eptype : 2; /* [19:18] */ + __IO uint32_t mc : 2; /* [21:20] */ + __IO uint32_t devaddr : 7; /* [28:22] */ + __IO uint32_t oddfrm : 1; /* [29] */ + __IO uint32_t chdis : 1; /* [30] */ + __IO uint32_t chena : 1; /* [31] */ + } hcchar_bit; + }; + + /** + * @brief otgfs host channel split control register, offset:0x504 + */ + union + { + __IO uint32_t hcsplt; + struct + { + __IO uint32_t prtaddr : 7; /* [6:0] */ + __IO uint32_t hubaddr : 7; /* [13:7] */ + __IO uint32_t xactpos : 2; /* [15:14] */ + __IO uint32_t compsplt : 1; /* [16] */ + __IO uint32_t reserved1 : 14; /* [30:17] */ + __IO uint32_t spltena : 1; /* [31] */ + } hcsplt_bit; + }; + + /** + * @brief otgfs host channel interrupt register, offset:0x508 + */ + union + { + __IO uint32_t hcint; + struct + { + __IO uint32_t xferc : 1; /* [0] */ + __IO uint32_t chhltd : 1; /* [1] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t stall : 1; /* [3] */ + __IO uint32_t nak : 1; /* [4] */ + __IO uint32_t ack : 1; /* [5] */ + __IO uint32_t reserved2 : 1; /* [6] */ + __IO uint32_t xacterr : 1; /* [7] */ + __IO uint32_t bblerr : 1; /* [8] */ + __IO uint32_t frmovrun : 1; /* [9] */ + __IO uint32_t dtglerr : 1; /* [10] */ + __IO uint32_t reserved3 : 21; /* [31:11] */ + } hcint_bit; + }; + + /** + * @brief otgfs host channel interrupt mask register, offset:0x50C + */ + union + { + __IO uint32_t hcintmsk; + struct + { + __IO uint32_t xfercmsk : 1; /* [0] */ + __IO uint32_t chhltdmsk : 1; /* [1] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t stallmsk : 1; /* [3] */ + __IO uint32_t nakmsk : 1; /* [4] */ + __IO uint32_t ackmsk : 1; /* [5] */ + __IO uint32_t reserved2 : 1; /* [6] */ + __IO uint32_t xacterrmsk : 1; /* [7] */ + __IO uint32_t bblerrmsk : 1; /* [8] */ + __IO uint32_t frmovrunmsk : 1; /* [9] */ + __IO uint32_t dtglerrmsk : 1; /* [10] */ + __IO uint32_t reserved3 : 21; /* [31:11] */ + } hcintmsk_bit; + }; + + /** + * @brief otgfs host channel transfer size register, offset:0x510 + */ + union + { + __IO uint32_t hctsiz; + struct + { + __IO uint32_t xfersize : 19; /* [18:0] */ + __IO uint32_t pktcnt : 10; /* [28:19] */ + __IO uint32_t pid : 2; /* [30:29] */ + __IO uint32_t reserved1 : 1; /* [31] */ + } hctsiz_bit; + }; + __IO uint32_t reserved3[3]; + +}otg_hchannel_type; + + +typedef struct +{ + /** + * @brief otgfs device configuration register, offset:0x800 + */ + union + { + __IO uint32_t dcfg; + struct + { + __IO uint32_t devspd : 2; /* [1:0] */ + __IO uint32_t nzstsouthshk : 1; /* [2] */ + __IO uint32_t reserved1 : 1; /* [3] */ + __IO uint32_t devaddr : 7; /* [10:4] */ + __IO uint32_t perfrint : 2; /* [12:11] */ + __IO uint32_t reserved2 : 19; /* [31:13] */ + } dcfg_bit; + }; + + /** + * @brief otgfs device controls register, offset:0x804 + */ + union + { + __IO uint32_t dctl; + struct + { + __IO uint32_t rwkupsig : 1; /* [0] */ + __IO uint32_t sftdiscon : 1; /* [1] */ + __IO uint32_t gnpinnaksts : 1; /* [2] */ + __IO uint32_t goutnaksts : 1; /* [3] */ + __IO uint32_t tstctl : 3; /* [6:4] */ + __IO uint32_t sgnpinak : 1; /* [7] */ + __IO uint32_t cgnpinak : 1; /* [8] */ + __IO uint32_t sgoutnak : 1; /* [9] */ + __IO uint32_t cgoutnak : 1; /* [10] */ + __IO uint32_t pwroprgdne : 1; /* [11] */ + __IO uint32_t reserved1 : 20; /* [31:12] */ + } dctl_bit; + }; + + /** + * @brief otgfs device status register, offset:0x80C + */ + union + { + __IO uint32_t dsts; + struct + { + __IO uint32_t suspsts : 1; /* [0] */ + __IO uint32_t enumspd : 2; /* [2:1] */ + __IO uint32_t eticerr : 1; /* [3] */ + __IO uint32_t reserved1 : 4; /* [7:4] */ + __IO uint32_t soffn : 14; /* [21:8] */ + __IO uint32_t reserved2 : 10; /* [31:22] */ + } dsts_bit; + }; + + __IO uint32_t reserved1; + /** + * @brief otgfs device in endpoint general interrupt mask register, offset:0x810 + */ + union + { + __IO uint32_t diepmsk; + struct + { + __IO uint32_t xfercmsk : 1; /* [0] */ + __IO uint32_t eptdismsk : 1; /* [1] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t timeoutmsk : 1; /* [3] */ + __IO uint32_t intkntxfempmsk : 1; /* [4] */ + __IO uint32_t intkneptmismsk : 1; /* [5] */ + __IO uint32_t ineptnakmsk : 1; /* [6] */ + __IO uint32_t reserved2 : 1; /* [7] */ + __IO uint32_t txfifoudrmsk : 1; /* [8] */ + __IO uint32_t bnainmsk : 1; /* [9] */ + __IO uint32_t reserved3 : 22; /* [31:10] */ + } diepmsk_bit; + }; + + /** + * @brief otgfs device out endpoint general interrupt mask register, offset:0x814 + */ + union + { + __IO uint32_t doepmsk; + struct + { + __IO uint32_t xfercmsk : 1; /* [0] */ + __IO uint32_t eptdismsk : 1; /* [1] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t setupmsk : 1; /* [3] */ + __IO uint32_t outtepdmsk : 1; /* [4] */ + __IO uint32_t reserved2 : 1; /* [5] */ + __IO uint32_t b2bsetupmsk : 1; /* [6] */ + __IO uint32_t reserved3 : 1; /* [7] */ + __IO uint32_t outperrmsk : 1; /* [8] */ + __IO uint32_t bnaoutmsk : 1; /* [9] */ + __IO uint32_t reserved4 : 22; /* [31:10] */ + } doepmsk_bit; + }; + + /** + * @brief otgfs device all endpoint interrupt register, offset:0x818 + */ + union + { + __IO uint32_t daint; + struct + { + __IO uint32_t ineptint : 16; /* [15:0] */ + __IO uint32_t outeptint : 16; /* [31:16] */ + } daint_bit; + }; + + /** + * @brief otgfs device all endpoint interrupt mask register, offset:0x81C + */ + union + { + __IO uint32_t daintmsk; + struct + { + __IO uint32_t ineptmsk : 16; /* [15:0] */ + __IO uint32_t outeptmsk : 16; /* [31:16] */ + } daintmsk_bit; + }; + + __IO uint32_t reserved2[5]; + + /** + * @brief otgfs device in endpoint fifo empty interrupt mask register, offset:0x834 + */ + union + { + __IO uint32_t diepempmsk; + struct + { + __IO uint32_t ineptxfemsk : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } diepempmsk_bit; + }; + +} otg_device_type; + +typedef struct +{ + /** + * @brief otgfs device out endpoint control register, offset:0x900 + */ + union + { + __IO uint32_t diepctl; + struct + { + __IO uint32_t mps : 11; /* [10:0] */ + __IO uint32_t reserved1 : 4; /* [14:11] */ + __IO uint32_t usbacept : 1; /* [15] */ + __IO uint32_t dpid : 1; /* [16] */ + __IO uint32_t naksts : 1; /* [17] */ + __IO uint32_t eptype : 2; /* [19:18] */ + __IO uint32_t reserved2 : 1; /* [20] */ + __IO uint32_t stall : 1; /* [21] */ + __IO uint32_t txfnum : 4; /* [25:22] */ + __IO uint32_t cnak : 1; /* [26] */ + __IO uint32_t snak : 1; /* [27] */ + __IO uint32_t setd0pid : 1; /* [28] */ + __IO uint32_t setd1pid : 1; /* [29] */ + __IO uint32_t eptdis : 1; /* [30] */ + __IO uint32_t eptena : 1; /* [31] */ + } diepctl_bit; + }; + __IO uint32_t reserved1; + + /** + * @brief otgfs device in endpoint interrupt register, offset:0x908 + */ + union + { + __IO uint32_t diepint; + struct + { + __IO uint32_t xferc : 1; /* [0] */ + __IO uint32_t epdisd : 1; /* [1] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t timeout : 1; /* [3] */ + __IO uint32_t intkntxfemp : 1; /* [4] */ + __IO uint32_t reserved2 : 1; /* [5] */ + __IO uint32_t ineptnak : 1; /* [6] */ + __IO uint32_t txfemp : 1; /* [7] */ + __IO uint32_t reserved3 : 24; /* [31:8] */ + } diepint_bit; + }; + __IO uint32_t reserved2; + + /** + * @brief otgfs device in endpoint transfer size register, offset:0x910 + endpoint number * 0x20 + */ + union + { + __IO uint32_t dieptsiz; + struct + { + __IO uint32_t xfersize : 19; /* [18:0] */ + __IO uint32_t pktcnt : 10; /* [28:19] */ + __IO uint32_t mc : 2; /* [30:29] */ + __IO uint32_t reserved1 : 1; /* [31] */ + } dieptsiz_bit; + }; + + __IO uint32_t reserved3; + + /** + * @brief otgfs device in endpoint tx fifo status register, offset:0x918 + endpoint number * 0x20 + */ + union + { + __IO uint32_t dtxfsts; + struct + { + __IO uint32_t ineptxfsav : 16; /* [15:0] */ + __IO uint32_t reserved1 : 16; /* [31:16] */ + } dtxfsts_bit; + }; + +} otg_eptin_type; + +typedef struct +{ + /** + * @brief otgfs device out endpoint control register, offset:0xb00 + endpoint number * 0x20 + */ + union + { + __IO uint32_t doepctl; + struct + { + __IO uint32_t mps : 11; /* [10:0] */ + __IO uint32_t reserved1 : 4; /* [14:11] */ + __IO uint32_t usbacept : 1; /* [15] */ + __IO uint32_t dpid : 1; /* [16] */ + __IO uint32_t naksts : 1; /* [17] */ + __IO uint32_t eptype : 2; /* [19:18] */ + __IO uint32_t snpm : 1; /* [20] */ + __IO uint32_t stall : 1; /* [21] */ + __IO uint32_t reserved2 : 4; /* [25:22] */ + __IO uint32_t cnak : 1; /* [26] */ + __IO uint32_t snak : 1; /* [27] */ + __IO uint32_t setd0pid : 1; /* [28] */ + __IO uint32_t setd1pid : 1; /* [29] */ + __IO uint32_t eptdis : 1; /* [30] */ + __IO uint32_t eptena : 1; /* [31] */ + } doepctl_bit; + }; + __IO uint32_t reserved1; + + /** + * @brief otgfs device out endpoint interrupt register, offset:0xb08 + endpoint number * 0x20 + */ + union + { + __IO uint32_t doepint; + struct + { + __IO uint32_t xferc : 1; /* [0] */ + __IO uint32_t epdisd : 1; /* [1] */ + __IO uint32_t reserved1 : 1; /* [2] */ + __IO uint32_t setup : 1; /* [3] */ + __IO uint32_t outtepd : 1; /* [4] */ + __IO uint32_t reserved2 : 1; /* [5] */ + __IO uint32_t b2pstup : 1; /* [6] */ + __IO uint32_t reserved3 : 25; /* [31:7] */ + } doepint_bit; + }; + __IO uint32_t reserved2; + + /** + * @brief otgfs device out endpoint transfer size register, offset:0xb10 + endpoint number * 0x20 + */ + union + { + __IO uint32_t doeptsiz; + struct + { + __IO uint32_t xfersize : 19; /* [18:0] */ + __IO uint32_t pktcnt : 10; /* [28:19] */ + __IO uint32_t rxdpid_setupcnt : 2; /* [30:29] */ + __IO uint32_t reserved1 : 1; /* [31] */ + } doeptsiz_bit; + }; +} otg_eptout_type; + +typedef struct +{ + /** + * @brief otgfs power and clock gating control registers, offset:0xe00 + */ + union + { + __IO uint32_t pcgcctl; + struct + { + __IO uint32_t stoppclk : 1; /* [0] */ + __IO uint32_t reserved1 : 3; /* [3:1] */ + __IO uint32_t suspendm : 1; /* [4] */ + __IO uint32_t reserved2 : 27; /* [31:5] */ + } pcgcctl_bit; + }; +} otg_pcgcctl_type; + +/** + * @} + */ + +/** @defgroup USB_exported_functions + * @{ + */ + +/** + * @brief usb host and device offset address + */ +#define OTG_HOST_ADDR_OFFSET 0x400 /*!< usb host register offset address */ +#define OTG_HOST_CHANNEL_ADDR_OFFSET 0x500 /*!< usb host channel register offset address */ +#define OTG_DEVICE_ADDR_OFFSET 0x800 /*!< usb device register offset address */ +#define OTG_DEVICE_EPTIN_ADDR_OFFSET 0x900 /*!< usb device endpoint in register offset address */ +#define OTG_DEVICE_EPTOUT_ADDR_OFFSET 0xB00 /*!< usb device endpoint out register offset address */ +#define OTG_PCGCCTL_ADDR_OFFSET 0xE00 /*!< usb power and clock control register offset address */ +#define OTG_FIFO_ADDR_OFFSET 0x1000 /*!< usb fifo offset address */ + +/** + * @brief usb host and device register define + */ +#define OTG1_GLOBAL ((otg_global_type *)(OTGFS1_BASE)) /*!< usb otg1 global register */ +#define OTG_PCGCCTL(usbx) ((otg_pcgcctl_type *)((uint32_t)usbx + OTG_PCGCCTL_ADDR_OFFSET)) /*!< usb power and clock control register */ +#define OTG_DEVICE(usbx) ((otg_device_type *)((uint32_t)usbx + OTG_DEVICE_ADDR_OFFSET)) /*!< usb device register */ +#define OTG_HOST(usbx) ((otg_host_type *)((uint32_t)usbx + OTG_HOST_ADDR_OFFSET)) /*!< usb host register */ +#define USB_CHL(usbx, n) ((otg_hchannel_type *)((uint32_t)usbx + OTG_HOST_CHANNEL_ADDR_OFFSET + n * 0x20)) /*!< usb channel n register */ +#define USB_INEPT(usbx, eptn) ((otg_eptin_type *)((uint32_t)usbx + OTG_DEVICE_EPTIN_ADDR_OFFSET + eptn * 0x20)) /*!< usb device endpoint in register */ +#define USB_OUTEPT(usbx, eptn) ((otg_eptout_type *)((uint32_t)usbx + OTG_DEVICE_EPTOUT_ADDR_OFFSET + eptn * 0x20)) /*!< usb device endpoint out register */ +#define USB_FIFO(usbx, eptn) *(__IO uint32_t *)((uint32_t)usbx + OTG_FIFO_ADDR_OFFSET + eptn * 0x1000) /*!< usb fifo address */ + + + +typedef otg_global_type usb_reg_type; + +/** @defgroup USB_exported_functions + * @{ + */ + +#ifdef OTGFS_USB_GLOBAL +error_status usb_global_reset(otg_global_type *usbx); +void usb_global_init(otg_global_type *usbx); +otg_global_type *usb_global_select_core(uint8_t usb_id); +void usb_flush_tx_fifo(otg_global_type *usbx, uint32_t fifo_num); +void usb_flush_rx_fifo(otg_global_type *usbx); +void usb_global_interrupt_enable(otg_global_type *usbx, uint16_t interrupt, confirm_state new_state); +uint32_t usb_global_get_all_interrupt(otg_global_type *usbx); +void usb_global_clear_interrupt(otg_global_type *usbx, uint32_t flag); +void usb_interrupt_enable(otg_global_type *usbx); +void usb_interrupt_disable(otg_global_type *usbx); +void usb_set_rx_fifo(otg_global_type *usbx, uint16_t size); +void usb_set_tx_fifo(otg_global_type *usbx, uint8_t txfifo, uint16_t size); +void usb_global_set_mode(otg_global_type *usbx, uint32_t mode); +void usb_global_power_on(otg_global_type *usbx); +void usb_write_packet(otg_global_type *usbx, uint8_t *pusr_buf, uint16_t num, uint16_t nbytes); +void usb_read_packet(otg_global_type *usbx, uint8_t *pusr_buf, uint16_t num, uint16_t nbytes); +void usb_stop_phy_clk(otg_global_type *usbx); +void usb_open_phy_clk(otg_global_type *usbx); +#endif + +#ifdef OTGFS_USB_DEVICE +void usb_ept_open(otg_global_type *usbx, usb_ept_info *ept_info); +void usb_ept_close(otg_global_type *usbx, usb_ept_info *ept_info); +void usb_ept_stall(otg_global_type *usbx, usb_ept_info *ept_info); +void usb_ept_clear_stall(otg_global_type *usbx, usb_ept_info *ept_info); +uint32_t usb_get_all_out_interrupt(otg_global_type *usbx); +uint32_t usb_get_all_in_interrupt(otg_global_type *usbx); +uint32_t usb_ept_out_interrupt(otg_global_type *usbx, uint32_t eptn); +uint32_t usb_ept_in_interrupt(otg_global_type *usbx, uint32_t eptn); +void usb_ept_out_clear(otg_global_type *usbx, uint32_t eptn, uint32_t flag); +void usb_ept_in_clear(otg_global_type *usbx, uint32_t eptn, uint32_t flag); +void usb_set_address(otg_global_type *usbx, uint8_t address); +void usb_ept0_start(otg_global_type *usbx); +void usb_ept0_setup(otg_global_type *usbx); +void usb_connect(otg_global_type *usbx); +void usb_disconnect(otg_global_type *usbx); +void usb_remote_wkup_set(otg_global_type *usbx); +void usb_remote_wkup_clear(otg_global_type *usbx); +uint8_t usb_suspend_status_get(otg_global_type *usbx); +#endif + +#ifdef OTGFS_USB_HOST +void usb_port_power_on(otg_global_type *usbx, confirm_state state); +uint32_t usbh_get_frame(otg_global_type *usbx); +void usb_hc_enable(otg_global_type *usbx, + uint8_t chn, + uint8_t ept_num, + uint8_t dev_address, + uint8_t type, + uint16_t maxpacket, + uint8_t speed); +uint32_t usb_hch_read_interrupt(otg_global_type *usbx); +void usb_host_disable(otg_global_type *usbx); +void usb_hch_halt(otg_global_type *usbx, uint8_t chn); +void usbh_fsls_clksel(otg_global_type *usbx, uint8_t clk); +#endif +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_wdt.h b/libraries/drivers/inc/at32f425_wdt.h new file mode 100644 index 0000000..336f171 --- /dev/null +++ b/libraries/drivers/inc/at32f425_wdt.h @@ -0,0 +1,195 @@ +/** + ************************************************************************** + * @file at32f425_wdt.h + * @brief at32f425 wdt header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_WDT_H +#define __AT32F425_WDT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup WDT + * @{ + */ + + +/** @defgroup WDT_flags_definition + * @brief wdt flag + * @{ + */ + +#define WDT_DIVF_UPDATE_FLAG ((uint16_t)0x0001) /*!< wdt division value update complete flag */ +#define WDT_RLDF_UPDATE_FLAG ((uint16_t)0x0002) /*!< wdt reload value update complete flag */ +#define WDT_WINF_UPDATE_FLAG ((uint16_t)0x0004) /*!< wdt window value update complete flag */ + +/** + * @} + */ + +/** @defgroup WDT_exported_types + * @{ + */ + +/** + * @brief wdt division value type + */ +typedef enum +{ + WDT_CLK_DIV_4 = 0x00, /*!< wdt clock divider value is 4 */ + WDT_CLK_DIV_8 = 0x01, /*!< wdt clock divider value is 8 */ + WDT_CLK_DIV_16 = 0x02, /*!< wdt clock divider value is 16 */ + WDT_CLK_DIV_32 = 0x03, /*!< wdt clock divider value is 32 */ + WDT_CLK_DIV_64 = 0x04, /*!< wdt clock divider value is 64 */ + WDT_CLK_DIV_128 = 0x05, /*!< wdt clock divider value is 128 */ + WDT_CLK_DIV_256 = 0x06 /*!< wdt clock divider value is 256 */ +} wdt_division_type; + +/** + * @brief wdt cmd value type + */ +typedef enum +{ + WDT_CMD_LOCK = 0x0000, /*!< disable write protection command */ + WDT_CMD_UNLOCK = 0x5555, /*!< enable write protection command */ + WDT_CMD_ENABLE = 0xCCCC, /*!< enable wdt command */ + WDT_CMD_RELOAD = 0xAAAA /*!< reload command */ +} wdt_cmd_value_type; + +/** + * @brief type define wdt register all + */ +typedef struct +{ + + /** + * @brief wdt cmd register, offset:0x00 + */ + union + { + __IO uint32_t cmd; + struct + { + __IO uint32_t cmd : 16;/* [15:0] */ + __IO uint32_t reserved1 : 16;/* [31:16] */ + } cmd_bit; + }; + + /** + * @brief wdt div register, offset:0x04 + */ + union + { + __IO uint32_t div; + struct + { + __IO uint32_t div : 3; /* [2:0] */ + __IO uint32_t reserved1 : 29;/* [31:3] */ + } div_bit; + }; + + /** + * @brief wdt rld register, offset:0x08 + */ + union + { + __IO uint32_t rld; + struct + { + __IO uint32_t rld : 12;/* [11:0] */ + __IO uint32_t reserved1 : 20;/* [31:12] */ + } rld_bit; + }; + + /** + * @brief wdt sts register, offset:0x0C + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t divf : 1; /* [0] */ + __IO uint32_t rldf : 1; /* [1] */ + __IO uint32_t reserved1 : 30;/* [31:2] */ + } sts_bit; + }; + + /** + * @brief wdt win register, offset:0x10 + */ + union + { + __IO uint32_t win; + struct + { + __IO uint32_t win : 12;/* [11:0] */ + __IO uint32_t reserved1 : 20;/* [31:12] */ + } win_bit; + }; +} wdt_type; + +/** + * @} + */ + +#define WDT ((wdt_type *) WDT_BASE) + +/** @defgroup WDT_exported_functions + * @{ + */ + +void wdt_enable(void); +void wdt_counter_reload(void); +void wdt_reload_value_set(uint16_t reload_value); +void wdt_divider_set(wdt_division_type division); +void wdt_register_write_enable( confirm_state new_state); +flag_status wdt_flag_get(uint16_t wdt_flag); +void wdt_window_counter_set(uint16_t window_cnt); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/inc/at32f425_wwdt.h b/libraries/drivers/inc/at32f425_wwdt.h new file mode 100644 index 0000000..3b8364e --- /dev/null +++ b/libraries/drivers/inc/at32f425_wwdt.h @@ -0,0 +1,157 @@ +/** + ************************************************************************** + * @file at32f425_wwdt.h + * @brief at32f425 wwdt header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_WWDT_H +#define __AT32F425_WWDT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @addtogroup WWDT + * @{ + */ + +/** @defgroup WWDT_enable_bit_definition + * @brief wwdt enable bit + * @{ + */ + +#define WWDT_EN_BIT ((uint32_t)0x00000080) /*!< wwdt enable bit */ + +/** + * @} + */ + +/** @defgroup WWDT_exported_types + * @{ + */ + +/** + * @brief wwdt division type + */ +typedef enum +{ + WWDT_PCLK1_DIV_4096 = 0x00, /*!< wwdt counter clock = (pclk1/4096)/1) */ + WWDT_PCLK1_DIV_8192 = 0x01, /*!< wwdt counter clock = (pclk1/4096)/2) */ + WWDT_PCLK1_DIV_16384 = 0x02, /*!< wwdt counter clock = (pclk1/4096)/4) */ + WWDT_PCLK1_DIV_32768 = 0x03 /*!< wwdt counter clock = (pclk1/4096)/8) */ +} wwdt_division_type; + +/** + * @brief type define wwdt register all + */ +typedef struct +{ + + /** + * @brief wwdt ctrl register, offset:0x00 + */ + union + { + __IO uint32_t ctrl; + struct + { + __IO uint32_t cnt : 7; /* [6:0] */ + __IO uint32_t wwdten : 1; /* [7] */ + __IO uint32_t reserved1 : 24;/* [31:8] */ + } ctrl_bit; + }; + + /** + * @brief wwdt cfg register, offset:0x04 + */ + union + { + __IO uint32_t cfg; + struct + { + __IO uint32_t win : 7; /* [6:0] */ + __IO uint32_t div : 2; /* [8:7] */ + __IO uint32_t rldien : 1; /* [9] */ + __IO uint32_t reserved1 : 22;/* [31:10] */ + } cfg_bit; + }; + + /** + * @brief wwdt cfg register, offset:0x08 + */ + union + { + __IO uint32_t sts; + struct + { + __IO uint32_t rldf : 1; /* [0] */ + __IO uint32_t reserved1 : 31;/* [31:1] */ + } sts_bit; + }; + +} wwdt_type; + +/** + * @} + */ + +#define WWDT ((wwdt_type *) WWDT_BASE) + +/** @defgroup WWDT_exported_functions + * @{ + */ + +void wwdt_reset(void); +void wwdt_divider_set(wwdt_division_type division); +void wwdt_flag_clear(void); +void wwdt_enable(uint8_t wwdt_cnt); +void wwdt_interrupt_enable(void); +flag_status wwdt_flag_get(void); +flag_status wwdt_interrupt_flag_get(void); +void wwdt_counter_set(uint8_t wwdt_cnt); +void wwdt_window_counter_set(uint8_t window_cnt); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/drivers/src/at32f425_acc.c b/libraries/drivers/src/at32f425_acc.c new file mode 100644 index 0000000..afdd42b --- /dev/null +++ b/libraries/drivers/src/at32f425_acc.c @@ -0,0 +1,232 @@ +/** + ************************************************************************** + * @file at32f425_acc.c + * @brief contains all the functions for the acc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup ACC + * @brief ACC driver modules + * @{ + */ + +#ifdef ACC_MODULE_ENABLED + +/** @defgroup ACC_private_functions + * @{ + */ + +/** + * @brief enable or disable the acc calibration mode. + * @param acc_trim: specifies the acc calibration type. + * this parameter can be one of the following values: + * - ACC_CAL_HICKCAL + * - ACC_CAL_HICKTRIM + * @param new_state: specifies the acc calibration to be enabled or disabled.(TRUE or FALSE) + * @retval none + */ +void acc_calibration_mode_enable(uint16_t acc_trim, confirm_state new_state) +{ + if(acc_trim == ACC_CAL_HICKCAL) + { + ACC->ctrl1_bit.entrim = FALSE; + } + else + { + ACC->ctrl1_bit.entrim = TRUE; + } + ACC->ctrl1_bit.calon = new_state; +} + +/** + * @brief store calibration step data in acc's ctrl1 register. + * @param step_value: value to be stored in the acc's ctrl1 register + * @retval none + */ +void acc_step_set(uint8_t step_value) +{ + ACC->ctrl1_bit.step = step_value; +} + +/** + * @brief enable or disable the specified acc interrupts. + * @param acc_int: specifies the acc interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - ACC_CALRDYIEN_INT + * - ACC_EIEN_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void acc_interrupt_enable(uint16_t acc_int, confirm_state new_state) +{ + if(acc_int == ACC_CALRDYIEN_INT) + { + ACC->ctrl1_bit.calrdyien = new_state; + } + else + { + ACC->ctrl1_bit.eien = new_state; + } +} + +/** + * @brief return the current acc hicktrim value. + * @param none + * @retval 8-bit hicktrim value. + */ +uint8_t acc_hicktrim_get(void) +{ + return ((uint8_t)(ACC->ctrl2_bit.hicktrim)); +} + +/** + * @brief return the current acc hickcal value. + * @param none + * @retval 8-bit hicktrim value. + */ +uint8_t acc_hickcal_get(void) +{ + return ((uint8_t)(ACC->ctrl2_bit.hickcal)); +} + +/** + * @brief wtire the value to acc c1 register. + * @param acc_c1_value + * @retval none. + */ +void acc_write_c1(uint16_t acc_c1_value) +{ + ACC->c1 = acc_c1_value; +} + +/** + * @brief wtire the value to acc c2 register. + * @param acc_c2_value + * @retval none. + */ +void acc_write_c2(uint16_t acc_c2_value) +{ + ACC->c2 = acc_c2_value; +} + +/** + * @brief wtire the value to acc c3 register. + * @param acc_c3_value + * @retval none. + */ +void acc_write_c3(uint16_t acc_c3_value) +{ + ACC->c3 = acc_c3_value; +} + +/** + * @brief return the current acc c1 value. + * @param none + * @retval 16-bit c1 value. + */ +uint16_t acc_read_c1(void) +{ + return ((uint16_t)(ACC->c1)); +} + +/** + * @brief return the current acc c2 value. + * @param none + * @retval 16-bit c2 value. + */ +uint16_t acc_read_c2(void) +{ + return ((uint16_t)(ACC->c2)); +} + +/** + * @brief return the current acc c3 value. + * @param none + * @retval 16-bit c3 value. + */ +uint16_t acc_read_c3(void) +{ + return ((uint16_t)(ACC->c3)); +} + +/** + * @brief check whether the specified acc flag is set or not. + * @param acc_flag: specifies the flag to check. + * this parameter can be one of the following values: + * - ACC_RSLOST_FLAG + * - ACC_CALRDY_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status acc_flag_get(uint16_t acc_flag) +{ + if(acc_flag == ACC_CALRDY_FLAG) + return (flag_status)(ACC->sts_bit.calrdy); + else + return (flag_status)(ACC->sts_bit.rslost); +} + +/** + * @brief check whether the specified acc interrupt flag is set or not. + * @param acc_flag: specifies the flag to check. + * this parameter can be one of the following values: + * - ACC_RSLOST_FLAG + * - ACC_CALRDY_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status acc_interrupt_flag_get(uint16_t acc_flag) +{ + if(acc_flag == ACC_CALRDY_FLAG) + return (flag_status)(ACC->sts_bit.calrdy && ACC->ctrl1_bit.calrdyien); + else + return (flag_status)(ACC->sts_bit.rslost && ACC->ctrl1_bit.eien); +} + +/** + * @brief clear the specified acc flag is set or not. + * @param acc_flag: specifies the flag to check. + * this parameter can be any combination of the following values: + * - ACC_RSLOST_FLAG + * - ACC_CALRDY_FLAG + * @retval none + */ +void acc_flag_clear(uint16_t acc_flag) +{ + ACC->sts = ~acc_flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_adc.c b/libraries/drivers/src/at32f425_adc.c new file mode 100644 index 0000000..6364518 --- /dev/null +++ b/libraries/drivers/src/at32f425_adc.c @@ -0,0 +1,909 @@ +/** + ************************************************************************** + * @file at32f425_adc.c + * @brief contains all the functions for the adc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup ADC + * @brief ADC driver modules + * @{ + */ + +#ifdef ADC_MODULE_ENABLED + +/** @defgroup ADC_private_functions + * @{ + */ + +/** + * @brief deinitialize the adc peripheral registers to their default reset values. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @retval none + */ +void adc_reset(adc_type *adc_x) +{ + if(adc_x == ADC1) + { + crm_periph_reset(CRM_ADC1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_ADC1_PERIPH_RESET, FALSE); + } +} + +/** + * @brief enable or disable the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param new_state: new state of a/d converter. + * this parameter can be: TRUE or FALSE. + * note:after adc ready,user set adcen bit will cause ordinary conversion + * @retval none + */ +void adc_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl2_bit.adcen = new_state; +} + +/** + * @brief adc base default para init. + * @param sequence_mode: set the state of adc sequence mode. + * this parameter can be:TRUE or FALSE + * @param repeat_mode: set the state of adc repeat conversion mode. + * this parameter can be:TRUE or FALSE + * @param data_align: set the state of adc data alignment. + * this parameter can be one of the following values: + * - ADC_RIGHT_ALIGNMENT + * - ADC_LEFT_ALIGNMENT + * @param ordinary_channel_length: configure the adc ordinary channel sequence length. + * this parameter can be: + * - (0x1~0x10) + * @retval none + */ +void adc_base_default_para_init(adc_base_config_type *adc_base_struct) +{ + adc_base_struct->sequence_mode = FALSE; + adc_base_struct->repeat_mode = FALSE; + adc_base_struct->data_align = ADC_RIGHT_ALIGNMENT; + adc_base_struct->ordinary_channel_length = 1; +} + +/** + * @brief initialize the adc peripheral according to the specified parameters. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param sequence_mode: set the state of adc sequence mode. + * this parameter can be:TRUE or FALSE + * @param repeat_mode: set the state of adc repeat conversion mode. + * this parameter can be:TRUE or FALSE + * @param data_align: set the state of adc data alignment. + * this parameter can be one of the following values: + * - ADC_RIGHT_ALIGNMENT + * - ADC_LEFT_ALIGNMENT + * @param ordinary_channel_length: configure the adc ordinary channel sequence length. + * this parameter can be: + * - (0x1~0x10) + * @retval none + */ +void adc_base_config(adc_type *adc_x, adc_base_config_type *adc_base_struct) +{ + adc_x->ctrl1_bit.sqen = adc_base_struct->sequence_mode; + adc_x->ctrl2_bit.rpen = adc_base_struct->repeat_mode; + adc_x->ctrl2_bit.dtalign = adc_base_struct->data_align; + adc_x->osq1_bit.oclen = adc_base_struct->ordinary_channel_length - 1; +} + +/** + * @brief enable or disable the adc dma transfer. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param new_state: new state of the adc dma transfer. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_dma_mode_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl2_bit.ocdmaen = new_state; +} + +/** + * @brief enable or disable the specified adc interrupts. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_int: specifies the adc interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - ADC_VMOR_INT + * - ADC_CCE_INT + * - ADC_PCCE_INT + * @param new_state: new state of the specified adc interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_interrupt_enable(adc_type *adc_x, uint32_t adc_int, confirm_state new_state) +{ + if(new_state == TRUE) + { + adc_x->ctrl1 |= adc_int; + } + else if(new_state == FALSE) + { + adc_x->ctrl1 &= ~adc_int; + } +} + +/** + * @brief initialize calibration register of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @retval none + */ +void adc_calibration_init(adc_type *adc_x) +{ + adc_x->ctrl2_bit.adcalinit = TRUE; +} + +/** + * @brief get calibration register's initialize status of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @retval the new state of reset calibration register status(SET or RESET). + */ +flag_status adc_calibration_init_status_get(adc_type *adc_x) +{ + if(adc_x->ctrl2_bit.adcalinit) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief start calibration process of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @retval none + */ +void adc_calibration_start(adc_type *adc_x) +{ + adc_x->ctrl2_bit.adcal = TRUE; +} + +/** + * @brief get calibration status of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @retval the new state of calibration status(SET or RESET). + */ +flag_status adc_calibration_status_get(adc_type *adc_x) +{ + if(adc_x->ctrl2_bit.adcal) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief enable or disable the voltage monitoring on single/all ordinary or preempt channels of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_voltage_monitoring: choose the adc_voltage_monitoring config. + * this parameter can be one of the following values: + * - ADC_VMONITOR_SINGLE_ORDINARY + * - ADC_VMONITOR_SINGLE_PREEMPT + * - ADC_VMONITOR_SINGLE_ORDINARY_PREEMPT + * - ADC_VMONITOR_ALL_ORDINARY + * - ADC_VMONITOR_ALL_PREEMPT + * - ADC_VMONITOR_ALL_ORDINARY_PREEMPT + * - ADC_VMONITOR_NONE + * @retval none + */ +void adc_voltage_monitor_enable(adc_type *adc_x, adc_voltage_monitoring_type adc_voltage_monitoring) +{ + adc_x->ctrl1_bit.ocvmen = FALSE; + adc_x->ctrl1_bit.pcvmen = FALSE; + adc_x->ctrl1_bit.vmsgen = FALSE; + adc_x->ctrl1 |= adc_voltage_monitoring; +} + +/** + * @brief set voltage monitoring's high and low thresholds value of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_high_threshold: voltage monitoring's high thresholds value. + * this parameter can be: + * - (0x000~0xFFF) + * @param adc_low_threshold: voltage monitoring's low thresholds value. + * this parameter can be: + * - (0x000~0xFFF) + * @retval none + */ +void adc_voltage_monitor_threshold_value_set(adc_type *adc_x, uint16_t adc_high_threshold, uint16_t adc_low_threshold) +{ + adc_x->vmhb_bit.vmhb = adc_high_threshold; + adc_x->vmlb_bit.vmlb = adc_low_threshold; +} + +/** + * @brief select the voltage monitoring's channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_channel: select the channel. + * this parameter can be one of the following values: + * - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3 + * - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7 + * - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11 + * - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15 + * - ADC_CHANNEL_16 - ADC_CHANNEL_17 + * @retval none + */ +void adc_voltage_monitor_single_channel_select(adc_type *adc_x, adc_channel_select_type adc_channel) +{ + adc_x->ctrl1_bit.vmcsel = adc_channel; +} + +/** + * @brief set ordinary channel's corresponding rank in the sequencer and sample time of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_channel: select the channel. + * this parameter can be one of the following values: + * - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3 + * - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7 + * - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11 + * - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15 + * - ADC_CHANNEL_16 - ADC_CHANNEL_17 + * @param adc_sequence: set rank in the ordinary group sequencer. + * this parameter must be: + * - between 1 to 16 + * @param adc_sampletime: set the sampletime of adc channel. + * this parameter can be one of the following values: + * - ADC_SAMPLETIME_1_5 + * - ADC_SAMPLETIME_7_5 + * - ADC_SAMPLETIME_13_5 + * - ADC_SAMPLETIME_28_5 + * - ADC_SAMPLETIME_41_5 + * - ADC_SAMPLETIME_55_5 + * - ADC_SAMPLETIME_71_5 + * - ADC_SAMPLETIME_239_5 + * @retval none + */ +void adc_ordinary_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime) +{ + uint32_t tmp_reg; + if(adc_channel < ADC_CHANNEL_10) + { + tmp_reg = adc_x->spt2; + tmp_reg &= ~(0x07 << 3 * adc_channel); + tmp_reg |= adc_sampletime << 3 * adc_channel; + adc_x->spt2 = tmp_reg; + } + else + { + tmp_reg = adc_x->spt1; + tmp_reg &= ~(0x07 << 3 * (adc_channel - ADC_CHANNEL_10)); + tmp_reg |= adc_sampletime << 3 * (adc_channel - ADC_CHANNEL_10); + adc_x->spt1 = tmp_reg; + } + + if(adc_sequence >= 13) + { + tmp_reg = adc_x->osq1; + tmp_reg &= ~(0x01F << 5 * (adc_sequence - 13)); + tmp_reg |= adc_channel << 5 * (adc_sequence - 13); + adc_x->osq1 = tmp_reg; + } + else if(adc_sequence >= 7) + { + tmp_reg = adc_x->osq2; + tmp_reg &= ~(0x01F << 5 * (adc_sequence - 7)); + tmp_reg |= adc_channel << 5 * (adc_sequence - 7); + adc_x->osq2 = tmp_reg; + } + else + { + tmp_reg = adc_x->osq3; + tmp_reg &= ~(0x01F << 5 * (adc_sequence - 1)); + tmp_reg |= adc_channel << 5 * (adc_sequence - 1); + adc_x->osq3 = tmp_reg; + } +} + +/** + * @brief set preempt channel lenghth of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_channel_lenght: set the adc preempt channel lenghth. + * this parameter can be: + * - (0x1~0x4) + * @retval none + */ +void adc_preempt_channel_length_set(adc_type *adc_x, uint8_t adc_channel_lenght) +{ + adc_x->psq_bit.pclen = adc_channel_lenght - 1; +} + +/** + * @brief configure preempt channel's corresponding rank in the sequencer and sample time of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_channel: select the channel. + * this parameter can be one of the following values: + * - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3 + * - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7 + * - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11 + * - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15 + * - ADC_CHANNEL_16 - ADC_CHANNEL_17 + * @param adc_sequence: set rank in the preempt group sequencer. + * this parameter must be: + * - between 1 to 4 + * @param adc_sampletime: config the sampletime of adc channel. + * this parameter can be one of the following values: + * - ADC_SAMPLETIME_1_5 + * - ADC_SAMPLETIME_7_5 + * - ADC_SAMPLETIME_13_5 + * - ADC_SAMPLETIME_28_5 + * - ADC_SAMPLETIME_41_5 + * - ADC_SAMPLETIME_55_5 + * - ADC_SAMPLETIME_71_5 + * - ADC_SAMPLETIME_239_5 + * @retval none + */ +void adc_preempt_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime) +{ + uint32_t tmp_reg; + uint8_t sequence_index; + if(adc_channel < ADC_CHANNEL_10) + { + tmp_reg = adc_x->spt2; + tmp_reg &= ~(0x07 << 3 * adc_channel); + tmp_reg |= adc_sampletime << 3 * adc_channel; + adc_x->spt2 = tmp_reg; + } + else + { + tmp_reg = adc_x->spt1; + tmp_reg &= ~(0x07 << 3 * (adc_channel - ADC_CHANNEL_10)); + tmp_reg |= adc_sampletime << 3 * (adc_channel - ADC_CHANNEL_10); + adc_x->spt1 = tmp_reg; + } + + sequence_index = adc_sequence + 3 - adc_x->psq_bit.pclen; + switch(sequence_index) + { + case 1: + adc_x->psq_bit.psn1 = adc_channel; + break; + case 2: + adc_x->psq_bit.psn2 = adc_channel; + break; + case 3: + adc_x->psq_bit.psn3 = adc_channel; + break; + case 4: + adc_x->psq_bit.psn4 = adc_channel; + break; + default: + break; + } +} + +/** + * @brief enable or disable the ordinary channel's external trigger and + * set external trigger event of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_ordinary_trig: select the external trigger event. + * this parameter can be one of the following values: + * adc1 + * - ADC12_ORDINARY_TRIG_TMR1CH1 - ADC12_ORDINARY_TRIG_TMR1CH2 - ADC12_ORDINARY_TRIG_TMR1CH3 + * - ADC12_ORDINARY_TRIG_TMR3TRGOUT - ADC12_ORDINARY_TRIG_TMR15CH1 - ADC12_ORDINARY_TRIG_EXINT11 - ADC12_ORDINARY_TRIG_SOFTWARE + * @param new_state: new state of ordinary channel's external trigger. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_ordinary_conversion_trigger_set(adc_type *adc_x, adc_ordinary_trig_select_type adc_ordinary_trig, confirm_state new_state) +{ + if(adc_ordinary_trig > 7) + { + adc_x->ctrl2_bit.octesel_h = 1; + adc_x->ctrl2_bit.octesel_l = adc_ordinary_trig & 0x7; + } + else + { + adc_x->ctrl2_bit.octesel_h = 0; + adc_x->ctrl2_bit.octesel_l = adc_ordinary_trig & 0x7; + } + adc_x->ctrl2_bit.octen = new_state; +} + +/** + * @brief enable or disable the preempt channel's external trigger and + * set external trigger event of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_preempt_trig: select the external trigger event. + * this parameter can be one of the following values: + * adc1 + * - ADC12_PREEMPT_TRIG_TMR1TRGOUT - ADC12_PREEMPT_TRIG_TMR1CH4 + * - ADC12_PREEMPT_TRIG_TMR3CH4 - ADC12_PREEMPT_TRIG_TMR15TRGOUT - ADC12_PREEMPT_TRIG_EXINT15 - ADC12_PREEMPT_TRIG_SOFTWARE + * @param new_state: new state of preempt channel's external trigger. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_conversion_trigger_set(adc_type *adc_x, adc_preempt_trig_select_type adc_preempt_trig, confirm_state new_state) +{ + if(adc_preempt_trig > 7) + { + adc_x->ctrl2_bit.pctesel_h = 1; + adc_x->ctrl2_bit.pctesel_l = adc_preempt_trig & 0x7; + } + else + { + adc_x->ctrl2_bit.pctesel_h = 0; + adc_x->ctrl2_bit.pctesel_l = adc_preempt_trig & 0x7; + } + adc_x->ctrl2_bit.pcten = new_state; +} + + +/** + * @brief set preempt channel's conversion value offset of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_preempt_channel: select the preempt channel. + * this parameter can be one of the following values: + * - ADC_PREEMPT_CHANNEL_1 + * - ADC_PREEMPT_CHANNEL_2 + * - ADC_PREEMPT_CHANNEL_3 + * - ADC_PREEMPT_CHANNEL_4 + * @param adc_offset_value: set the adc preempt channel's conversion value offset. + * this parameter can be: + * - (0x000~0xFFF) + * @retval none + */ +void adc_preempt_offset_value_set(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel, uint16_t adc_offset_value) +{ + switch(adc_preempt_channel) + { + case ADC_PREEMPT_CHANNEL_1: + adc_x->pcdto1_bit.pcdto1 = adc_offset_value; + break; + case ADC_PREEMPT_CHANNEL_2: + adc_x->pcdto2_bit.pcdto2 = adc_offset_value; + break; + case ADC_PREEMPT_CHANNEL_3: + adc_x->pcdto3_bit.pcdto3 = adc_offset_value; + break; + case ADC_PREEMPT_CHANNEL_4: + adc_x->pcdto4_bit.pcdto4 = adc_offset_value; + break; + default: + break; + } +} + +/** + * @brief set partitioned mode channel count of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_channel_count: configure the adc partitioned mode channel count. + * this parameter can be: + * - (0x1~0x8) + * @retval none + */ +void adc_ordinary_part_count_set(adc_type *adc_x, uint8_t adc_channel_count) +{ + + adc_x->ctrl1_bit.ocpcnt = adc_channel_count - 1; +} + +/** + * @brief enable or disable the partitioned mode on ordinary channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param new_state: new state of ordinary channel's partitioned mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_ordinary_part_mode_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl1_bit.ocpen = new_state; +} + +/** + * @brief enable or disable the partitioned mode on preempt channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param new_state: new state of preempt channel's partitioned mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_part_mode_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl1_bit.pcpen = new_state; +} + +/** + * @brief enable or disable automatic preempt group conversion of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param new_state: new state of automatic preempt group conversion. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_auto_mode_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl1_bit.pcautoen = new_state; +} + +/** + * @brief enable or disable the temperature sensor and vintrv channel. + * @param new_state: new state of Internal temperature sensor and vintrv. + * this parameter can be: TRUE or FALSE. + * note:this bit is present only in adc1 + * @retval none + */ +void adc_tempersensor_vintrv_enable(confirm_state new_state) +{ + ADC1->ctrl2_bit.itsrven = new_state; +} + +/** + * @brief enable or disable ordinary software start conversion of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param new_state: new state of ordinary software start conversion. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_ordinary_software_trigger_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl2_bit.ocswtrg = new_state; +} + +/** + * @brief get ordinary software start conversion status of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @retval the new state of ordinary software start conversion status(SET or RESET). + */ +flag_status adc_ordinary_software_trigger_status_get(adc_type *adc_x) +{ + if(adc_x->ctrl2_bit.ocswtrg) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief enable or disable preempt software start conversion of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param new_state: new state of preempt software start conversion. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_software_trigger_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ctrl2_bit.pcswtrg = new_state; +} + +/** + * @brief get preempt software start conversion status of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @retval the new state of preempt software start conversion status(SET or RESET). + */ +flag_status adc_preempt_software_trigger_status_get(adc_type *adc_x) +{ + if(adc_x->ctrl2_bit.pcswtrg) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief return the last conversion data for ordinary channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @retval the last conversion data for ordinary channel. + */ +uint16_t adc_ordinary_conversion_data_get(adc_type *adc_x) +{ + return (uint16_t)(adc_x->odt_bit.odt); +} + +/** + * @brief return the conversion data for selection preempt channel of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_preempt_channel: select the preempt channel. + * this parameter can be one of the following values: + * - ADC_PREEMPT_CHANNEL_1 + * - ADC_PREEMPT_CHANNEL_2 + * - ADC_PREEMPT_CHANNEL_3 + * - ADC_PREEMPT_CHANNEL_4 + * @retval the conversion data for selection preempt channel. + */ +uint16_t adc_preempt_conversion_data_get(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel) +{ + uint16_t preempt_conv_data_index = 0; + switch(adc_preempt_channel) + { + case ADC_PREEMPT_CHANNEL_1: + preempt_conv_data_index = (uint16_t)(adc_x->pdt1_bit.pdt1); + break; + case ADC_PREEMPT_CHANNEL_2: + preempt_conv_data_index = (uint16_t)(adc_x->pdt2_bit.pdt2); + break; + case ADC_PREEMPT_CHANNEL_3: + preempt_conv_data_index = (uint16_t)(adc_x->pdt3_bit.pdt3); + break; + case ADC_PREEMPT_CHANNEL_4: + preempt_conv_data_index = (uint16_t)(adc_x->pdt4_bit.pdt4); + break; + default: + break; + } + return preempt_conv_data_index; +} + +/** + * @brief get flag of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_flag: select the adc flag. + * this parameter can be one of the following values: + * - ADC_VMOR_FLAG + * - ADC_CCE_FLAG + * - ADC_PCCE_FLAG + * - ADC_PCCS_FLAG(no interrupt associated) + * - ADC_OCCS_FLAG(no interrupt associated) + * @retval the new state of adc flag status(SET or RESET). + */ +flag_status adc_flag_get(adc_type *adc_x, uint8_t adc_flag) +{ + flag_status status = RESET; + + if((adc_x->sts & adc_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief get interrupt flag of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_flag: select the adc flag. + * this parameter can be one of the following values: + * - ADC_VMOR_FLAG + * - ADC_CCE_FLAG + * - ADC_PCCE_FLAG + * @retval the new state of adc flag status(SET or RESET). + */ +flag_status adc_interrupt_flag_get(adc_type *adc_x, uint8_t adc_flag) +{ + flag_status status = RESET; + switch(adc_flag) + { + case ADC_VMOR_FLAG: + if(adc_x->sts_bit.vmor && adc_x->ctrl1_bit.vmorien) + { + status = SET; + } + break; + case ADC_CCE_FLAG: + if(adc_x->sts_bit.cce && adc_x->ctrl1_bit.cceien) + { + status = SET; + } + break; + case ADC_PCCE_FLAG: + if(adc_x->sts_bit.pcce && adc_x->ctrl1_bit.pcceien) + { + status = SET; + } + break; + default: + break; + } + return status; +} + +/** + * @brief clear flag of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * ADC1. + * @param adc_flag: select the adc flag. + * this parameter can be any combination of the following values: + * - ADC_VMOR_FLAG + * - ADC_CCE_FLAG(also can clear by reading the adc_x->odt) + * - ADC_PCCE_FLAG + * - ADC_PCCS_FLAG + * - ADC_OCCS_FLAG + * @retval none + */ +void adc_flag_clear(adc_type *adc_x, uint32_t adc_flag) +{ + adc_x->sts = ~adc_flag; +} + +/** + * @brief enable or disable the ordinary oversampling of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * - ADC1. + * @param new_state: new state of ordinary oversampling. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_ordinary_oversample_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ovsp_bit.oosen = new_state; +} + +/** + * @brief enable or disable the preempt oversampling of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * - ADC1. + * @param new_state: new state of preempt oversampling. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_preempt_oversample_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ovsp_bit.posen = new_state; +} + +/** + * @brief config the oversampling ratio and shift of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * - ADC1. + * @param adc_oversample_ratio: set the oversample ratio. + * this parameter can be one of the following values: + * - ADC_OVERSAMPLE_RATIO_2 + * - ADC_OVERSAMPLE_RATIO_4 + * - ADC_OVERSAMPLE_RATIO_8 + * - ADC_OVERSAMPLE_RATIO_16 + * - ADC_OVERSAMPLE_RATIO_32 + * - ADC_OVERSAMPLE_RATIO_64 + * - ADC_OVERSAMPLE_RATIO_128 + * - ADC_OVERSAMPLE_RATIO_256 + * @param adc_oversample_shift: set the oversample shift. + * this parameter can be one of the following values: + * - ADC_OVERSAMPLE_SHIFT_0 + * - ADC_OVERSAMPLE_SHIFT_1 + * - ADC_OVERSAMPLE_SHIFT_2 + * - ADC_OVERSAMPLE_SHIFT_3 + * - ADC_OVERSAMPLE_SHIFT_4 + * - ADC_OVERSAMPLE_SHIFT_5 + * - ADC_OVERSAMPLE_SHIFT_6 + * - ADC_OVERSAMPLE_SHIFT_7 + * - ADC_OVERSAMPLE_SHIFT_8 + * @retval none + */ +void adc_oversample_ratio_shift_set(adc_type *adc_x, adc_oversample_ratio_type adc_oversample_ratio, adc_oversample_shift_type adc_oversample_shift) +{ + adc_x->ovsp_bit.osrsel = adc_oversample_ratio; + adc_x->ovsp_bit.osssel = adc_oversample_shift; +} + +/** + * @brief enable or disable the ordinary oversampling trigger mode of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * - ADC1. + * @param new_state: new state of ordinary oversampling trigger mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void adc_ordinary_oversample_trig_enable(adc_type *adc_x, confirm_state new_state) +{ + adc_x->ovsp_bit.oostren = new_state; +} + +/** + * @brief set ordinary oversample restart mode of the specified adc peripheral. + * @param adc_x: select the adc peripheral. + * this parameter can be one of the following values: + * - ADC1. + * @param adc_or_oversample_restart: ordinary oversample restart mode. + * this parameter can be one of the following values: + * - ADC_OVERSAMPLE_CONTINUE + * - ADC_OVERSAMPLE_RESTART + * @retval none + */ +void adc_ordinary_oversample_restart_set(adc_type *adc_x, adc_ordinary_oversample_restart_type adc_ordinary_oversample_restart) +{ + adc_x->ovsp_bit.oosrsel = adc_ordinary_oversample_restart; +} +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_can.c b/libraries/drivers/src/at32f425_can.c new file mode 100644 index 0000000..69cfc0e --- /dev/null +++ b/libraries/drivers/src/at32f425_can.c @@ -0,0 +1,1234 @@ +/** + ************************************************************************** + * @file at32f425_can.c + * @brief contains all the functions for the can firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup CAN + * @brief CAN driver modules + * @{ + */ + +#ifdef CAN_MODULE_ENABLED + +/** @defgroup CAN_private_functions + * @{ + */ + +/** + * @brief deinitialize the can peripheral registers to their default reset values. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @retval none. + */ +void can_reset(can_type* can_x) +{ + crm_periph_reset(CRM_CAN1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_CAN1_PERIPH_RESET, FALSE); +} + +/** + * @brief fill each can_baudrate_struct member with its default value. + * @param can_baudrate_struct: pointer to a can_baudrate_type structure which will be initialized. + * @retval none. + */ +void can_baudrate_default_para_init(can_baudrate_type* can_baudrate_struct) +{ + /* reset can baudrate structure parameters values */ + + /* baud rate division */ + can_baudrate_struct->baudrate_div = 1; + + /* resynchronization adjust width */ + can_baudrate_struct->rsaw_size = CAN_RSAW_2TQ; + + /* bit time segment 1 */ + can_baudrate_struct->bts1_size = CAN_BTS1_4TQ; + + /* bit time segment 2 */ + can_baudrate_struct->bts2_size = CAN_BTS2_3TQ; +} + +/** + * @brief set the baudrate of the can peripheral + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param can_baudrate_struct: pointer to a can_baudrate_type structure which will be set. + * @note baudrate calculate method is: + * baudrate = fpclk/(baudrate_div *(3 + bts1_size + bts2_size)) + * @retval the result of baudrate set + * this parameter can be one of the following values: + * SUCCESS or ERROR + */ +error_status can_baudrate_set(can_type* can_x, can_baudrate_type* can_baudrate_struct) +{ + error_status status_index = ERROR; + uint32_t wait_ack_index = 0x00000000; + /* exit from doze mode */ + can_x->mctrl_bit.dzen = FALSE; + + /* request freeze mode */ + can_x->mctrl_bit.fzen = TRUE; + + /* wait the acknowledge */ + while((!can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT)) + { + wait_ack_index++; + } + + /* check acknowledge */ + if(can_x->msts_bit.fzc) + { + can_x->btmg_bit.brdiv = can_baudrate_struct->baudrate_div - 1; + can_x->btmg_bit.rsaw = can_baudrate_struct->rsaw_size; + can_x->btmg_bit.bts1 = can_baudrate_struct->bts1_size; + can_x->btmg_bit.bts2 = can_baudrate_struct->bts2_size; + + /* request leave freeze mode */ + can_x->mctrl_bit.fzen = FALSE; + + /* wait the acknowledge */ + wait_ack_index = 0; + while((can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT)) + { + wait_ack_index++; + } + + /* check acknowledged */ + if(can_x->msts_bit.fzc) + { + status_index = ERROR; + } + else + { + status_index = SUCCESS ; + } + } + else + { + status_index = ERROR; + } + + /* return the status of baudrate set */ + return status_index; +} + +/** + * @brief fill each can_init_struct member with its default value. + * @param can_base_struct: pointer to a can_base_type structure which will be initialized. + * @retval none. + */ +void can_default_para_init(can_base_type* can_base_struct) +{ + /* reset can init structure parameters values */ + + /* initialize the time triggered communication mode */ + can_base_struct->ttc_enable = FALSE; + + /* initialize the automatic exit bus-off management */ + can_base_struct->aebo_enable = FALSE; + + /* initialize the automatic exit doze mode */ + can_base_struct->aed_enable = FALSE; + + /* initialize the prohibit retransmission when sending fails */ + can_base_struct->prsf_enable = FALSE; + + /* initialize the message discarding rule select when overflow */ + can_base_struct->mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED; + + /* initialize the multiple message sending sequence rule */ + can_base_struct->mmssr_selection = CAN_SENDING_BY_ID; + + /* initialize the can_mode */ + can_base_struct->mode_selection = CAN_MODE_COMMUNICATE; +} + +/** + * @brief initialize the can peripheral according to the specified + * parameters in the can_init_struct. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param can_base_struct: pointer to a can_base_struct structure that contains the configuration information for the can peripheral. + * @retval the status of initialization + * this parameter can be one of the following values: + * SUCCESS or ERROR + */ +error_status can_base_init(can_type* can_x, can_base_type* can_base_struct) +{ + error_status init_status_index = ERROR; + uint32_t wait_ack_index = 0x00000000; + /* exit from doze mode */ + can_x->mctrl_bit.dzen = FALSE; + + /* request freeze mode */ + can_x->mctrl_bit.fzen = TRUE; + + /* wait the acknowledge */ + while((!can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT)) + { + wait_ack_index++; + } + + /* check acknowledge */ + if(can_x->msts_bit.fzc) + { + /* set the time triggered communication mode */ + can_x->mctrl_bit.ttcen = can_base_struct->ttc_enable; + + /* set the automatic exit bus-off management */ + can_x->mctrl_bit.aeboen = can_base_struct->aebo_enable; + + /* set the automatic automatic exit doze mode */ + can_x->mctrl_bit.aeden = can_base_struct->aed_enable; + + /* set the prohibit retransmission when sending fails */ + can_x->mctrl_bit.prsfen = can_base_struct->prsf_enable; + + /* set the message discarding rule select when overflow */ + can_x->mctrl_bit.mdrsel = can_base_struct->mdrsel_selection; + + /* set the multiple message sending sequence rule */ + can_x->mctrl_bit.mmssr = can_base_struct->mmssr_selection; + + /* set the test mode */ + can_x->btmg_bit.lben = can_base_struct->mode_selection & 0x01; + can_x->btmg_bit.loen = (can_base_struct->mode_selection >> 1) & 0x01; + + /* request leave freeze mode */ + can_x->mctrl_bit.fzen = FALSE; + + /* wait the acknowledge */ + wait_ack_index = 0; + while((can_x->msts_bit.fzc) && (wait_ack_index != FZC_TIMEOUT)) + { + wait_ack_index++; + } + + /* check acknowledged */ + if(can_x->msts_bit.fzc) + { + init_status_index = ERROR; + } + else + { + init_status_index = SUCCESS ; + } + } + else + { + init_status_index = ERROR; + } + + /* return the status of initialization */ + return init_status_index; +} + +/** + * @brief fill each can_filter_init_struct member with its default value. + * @param can_filter_init_struct: pointer to a can_filter_init_type structure which will be initialized. + * @retval none. + */ +void can_filter_default_para_init(can_filter_init_type* can_filter_init_struct) +{ + /* reset can filter init structure parameters values */ + + /* initialize the filter activate state */ + can_filter_init_struct->filter_activate_enable = FALSE; + + /* filter mode */ + can_filter_init_struct->filter_mode = CAN_FILTER_MODE_ID_MASK; + + /* filter relation fifo select */ + can_filter_init_struct->filter_fifo = CAN_FILTER_FIFO0; + + /* filter number select */ + can_filter_init_struct->filter_number = 0; + + /* initialize the filter bit width */ + can_filter_init_struct->filter_bit = CAN_FILTER_16BIT; + + /* initialize the filters filter data bit */ + can_filter_init_struct->filter_id_high = 0; + can_filter_init_struct->filter_id_low = 0; + can_filter_init_struct->filter_mask_high = 0; + can_filter_init_struct->filter_mask_low = 0; +} + +/** + * @brief initialize the can peripheral according to the specified + * parameters in the can_filter_init_struct. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param can_filter_init_struct: pointer to a can_filter_init_type structure that contains the configuration information. + * @retval none. + */ +void can_filter_init(can_type* can_x, can_filter_init_type* can_filter_init_struct) +{ + uint32_t filter_number_bit_pos = 0; + filter_number_bit_pos = ((uint32_t)1) << can_filter_init_struct->filter_number; + /* set the filter turn into configuration condition */ + can_x->fctrl_bit.fcs = TRUE; + + /* filter activate disable */ + can_x->facfg &= ~(uint32_t)filter_number_bit_pos; + + /* filter bit width */ + switch(can_filter_init_struct->filter_bit) + { + case CAN_FILTER_16BIT: + can_x->fbwcfg &= ~(uint32_t)filter_number_bit_pos; + /* first 16-bit identifier and first 16-bit mask or first 16-bit identifier and second 16-bit identifier */ + can_x->ffb[can_filter_init_struct->filter_number].ffdb1 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_low) << 16); + can_x->ffb[can_filter_init_struct->filter_number].ffdb1 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_low); + + /* second 16-bit identifier and second 16-bit mask or third 16-bit identifier and fourth 16-bit identifier */ + can_x->ffb[can_filter_init_struct->filter_number].ffdb2 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_high) << 16); + can_x->ffb[can_filter_init_struct->filter_number].ffdb2 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_high); + + break; + case CAN_FILTER_32BIT: + can_x->fbwcfg |= filter_number_bit_pos; + /* 32-bit identifier or first 32-bit identifier */ + can_x->ffb[can_filter_init_struct->filter_number].ffdb1 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_high) << 16); + can_x->ffb[can_filter_init_struct->filter_number].ffdb1 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_id_low); + + /* 32-bit mask or second 32-bit identifier */ + can_x->ffb[can_filter_init_struct->filter_number].ffdb2 = ((0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_high) << 16); + can_x->ffb[can_filter_init_struct->filter_number].ffdb2 |= (0x0000FFFF & (uint32_t)can_filter_init_struct->filter_mask_low); + + break; + default: + break; + } + + /* filter mode */ + switch(can_filter_init_struct->filter_mode) + { + case CAN_FILTER_MODE_ID_MASK: + can_x->fmcfg &= ~(uint32_t)filter_number_bit_pos; + break; + case CAN_FILTER_MODE_ID_LIST: + can_x->fmcfg |= (uint32_t)filter_number_bit_pos; + break; + default: + break; + } + + /* filter relation fifo select */ + switch(can_filter_init_struct->filter_fifo) + { + case CAN_FILTER_FIFO0: + can_x->frf &= ~(uint32_t)filter_number_bit_pos; + break; + case CAN_FILTER_FIFO1: + can_x->frf |= (uint32_t)filter_number_bit_pos; + break; + default: + break; + } + + /* filter activate enable */ + switch(can_filter_init_struct->filter_activate_enable) + { + case TRUE: + can_x->facfg |= (uint32_t)filter_number_bit_pos; + break; + case FALSE: + can_x->facfg &= ~(uint32_t)filter_number_bit_pos; + break; + default: + break; + } + + /* set the filter turn into working condition */ + can_x->fctrl_bit.fcs = FALSE; +} + +/** + * @brief enable or disable the debug transmission prohibit of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param new_state: new state of debug transmission prohibit. + * this parameter can be: TRUE or FALSE. + * @retval none. + */ +void can_debug_transmission_prohibit(can_type* can_x, confirm_state new_state) +{ + can_x->mctrl_bit.ptd = new_state; +} + +/** + * @brief enable or disable time trigger operation communication mode of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param new_state : new state of time trigger operation communication mode. + * this parameter can be: TRUE or FALSE. + * @note + * note1: + * when enabled, transmit mailbox time stamp(tmts[15:0]) value is sent in the last two data bytes of + * the 8-byte message: tmts[7:0] in data byte 6 and tmts[15:8] in data byte 7 + * @note + * note2: + * tmdtbl must be programmed as 8 in order time stamp (2 bytes) to be sent over the can bus. + * @retval none + */ +void can_ttc_mode_enable(can_type* can_x, confirm_state new_state) +{ + /* config the ttc mode new_state */ + can_x->mctrl_bit.ttcen = new_state; + + /* config tmtsten bits new_state */ + can_x->tx_mailbox[0].tmc_bit.tmtsten = new_state; + can_x->tx_mailbox[1].tmc_bit.tmtsten = new_state; + can_x->tx_mailbox[2].tmc_bit.tmtsten = new_state; +} + +/** + * @brief fill the transmission message and transmit of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param tx_message_struct: pointer to a structure which contains the message to be trans. + * @retval the number of the mailbox that is used for transmission: + * this parameter can be one of the following values: + * - CAN_TX_MAILBOX0 + * - CAN_TX_MAILBOX1 + * - CAN_TX_MAILBOX2 + * - CAN_TX_STATUS_NO_EMPTY + */ +uint8_t can_message_transmit(can_type* can_x, can_tx_message_type* tx_message_struct) +{ + uint8_t transmit_mailbox = CAN_TX_STATUS_NO_EMPTY; + + /* select one empty transmit mailbox */ + if(can_x->tsts_bit.tm0ef) + { + transmit_mailbox = CAN_TX_MAILBOX0; + } + else if(can_x->tsts_bit.tm1ef) + { + transmit_mailbox = CAN_TX_MAILBOX1; + } + else if(can_x->tsts_bit.tm2ef) + { + transmit_mailbox = CAN_TX_MAILBOX2; + } + else + { + transmit_mailbox = CAN_TX_STATUS_NO_EMPTY; + } + + if(transmit_mailbox != CAN_TX_STATUS_NO_EMPTY) + { + /* set up the id */ + can_x->tx_mailbox[transmit_mailbox].tmi &= 0x00000001; + can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmidsel = tx_message_struct->id_type; + switch(tx_message_struct->id_type) + { + case CAN_ID_STANDARD: + can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmsid = tx_message_struct->standard_id; + break; + case CAN_ID_EXTENDED: + can_x->tx_mailbox[transmit_mailbox].tmi |= (tx_message_struct->extended_id << 3); + break; + default: + break; + } + can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmfrsel = tx_message_struct->frame_type; + /* set up the dlc */ + can_x->tx_mailbox[transmit_mailbox].tmc_bit.tmdtbl = (tx_message_struct->dlc & ((uint8_t)0x0F)); + + /* set up the data field */ + can_x->tx_mailbox[transmit_mailbox].tmdtl = (((uint32_t)tx_message_struct->data[3] << 24) | + ((uint32_t)tx_message_struct->data[2] << 16) | + ((uint32_t)tx_message_struct->data[1] << 8) | + ((uint32_t)tx_message_struct->data[0])); + can_x->tx_mailbox[transmit_mailbox].tmdth = (((uint32_t)tx_message_struct->data[7] << 24) | + ((uint32_t)tx_message_struct->data[6] << 16) | + ((uint32_t)tx_message_struct->data[5] << 8) | + ((uint32_t)tx_message_struct->data[4])); + + /* request transmission */ + can_x->tx_mailbox[transmit_mailbox].tmi_bit.tmsr = TRUE; + } + return transmit_mailbox; +} + +/** + * @brief check the transmission state of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param transmit_mailbox: the number of the mailbox that is used for transmission. + * this parameter can be one of the following values: + * - CAN_TX_MAILBOX0 + * - CAN_TX_MAILBOX1 + * - CAN_TX_MAILBOX2 + * @retval can transmit status + * this parameter can be one of the following values: + * - CAN_TX_STATUS_SUCCESSFUL + * - CAN_TX_STATUS_FAILED + * - CAN_TX_STATUS_PENDING + */ +can_transmit_status_type can_transmit_status_get(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox) +{ + can_transmit_status_type state_index = CAN_TX_STATUS_FAILED; + switch(transmit_mailbox) + { + case CAN_TX_MAILBOX0: + if(can_x->tsts_bit.tm0tcf != RESET) + { + if(can_x->tsts_bit.tm0tsf != RESET) + { + state_index = CAN_TX_STATUS_SUCCESSFUL; + } + else + { + state_index = CAN_TX_STATUS_FAILED; + } + } + else + { + state_index = CAN_TX_STATUS_PENDING; + } + break; + case CAN_TX_MAILBOX1: + if(can_x->tsts_bit.tm1tcf != RESET) + { + if(can_x->tsts_bit.tm1tsf != RESET) + { + state_index = CAN_TX_STATUS_SUCCESSFUL; + } + else + { + state_index = CAN_TX_STATUS_FAILED; + } + } + else + { + state_index = CAN_TX_STATUS_PENDING; + } + break; + case CAN_TX_MAILBOX2: + if(can_x->tsts_bit.tm2tcf != RESET) + { + if(can_x->tsts_bit.tm2tsf != RESET) + { + state_index = CAN_TX_STATUS_SUCCESSFUL; + } + else + { + state_index = CAN_TX_STATUS_FAILED; + } + } + else + { + state_index = CAN_TX_STATUS_PENDING; + } + break; + default: + state_index = CAN_TX_STATUS_FAILED; + break; + } + return state_index; +} + +/** + * @brief cancel a transmit request of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param mailbox: mailbox number. + * this parameter can be one of the following values: + * - CAN_TX_MAILBOX0 + * - CAN_TX_MAILBOX1 + * - CAN_TX_MAILBOX2 + * @retval none. + */ +void can_transmit_cancel(can_type* can_x, can_tx_mailbox_num_type transmit_mailbox) +{ + switch (transmit_mailbox) + { + case CAN_TX_MAILBOX0: + can_x->tsts = CAN_TSTS_TM0CT_VAL; + break; + case CAN_TX_MAILBOX1: + can_x->tsts = CAN_TSTS_TM1CT_VAL; + break; + case CAN_TX_MAILBOX2: + can_x->tsts = CAN_TSTS_TM2CT_VAL; + break; + default: + break; + } +} + +/** + * @brief receive message of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param fifo_number: receive fifo number. + * this parameter can be one of the following values: + * - CAN_RX_FIFO0 + * - CAN_RX_FIFO1 + * @param rx_message_struct: pointer to a structure which store the receive message. + * @retval none. + */ +void can_message_receive(can_type* can_x, can_rx_fifo_num_type fifo_number, can_rx_message_type* rx_message_struct) +{ + /* get the id type */ + rx_message_struct->id_type = (can_identifier_type)can_x->fifo_mailbox[fifo_number].rfi_bit.rfidi; + switch (rx_message_struct->id_type) + { + case CAN_ID_STANDARD: + rx_message_struct->standard_id = can_x->fifo_mailbox[fifo_number].rfi_bit.rfsid; + break; + case CAN_ID_EXTENDED: + rx_message_struct->extended_id = 0x1FFFFFFF & (can_x->fifo_mailbox[fifo_number].rfi >> 3); + break; + default: + break; + } + rx_message_struct->frame_type = (can_trans_frame_type)can_x->fifo_mailbox[fifo_number].rfi_bit.rffri; + /* get the dlc */ + rx_message_struct->dlc = can_x->fifo_mailbox[fifo_number].rfc_bit.rfdtl; + + /* get the filter match number */ + rx_message_struct->filter_index = can_x->fifo_mailbox[fifo_number].rfc_bit.rffmn; + + /* get the data field */ + rx_message_struct->data[0] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt0; + rx_message_struct->data[1] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt1; + rx_message_struct->data[2] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt2; + rx_message_struct->data[3] = can_x->fifo_mailbox[fifo_number].rfdtl_bit.rfdt3; + rx_message_struct->data[4] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt4; + rx_message_struct->data[5] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt5; + rx_message_struct->data[6] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt6; + rx_message_struct->data[7] = can_x->fifo_mailbox[fifo_number].rfdth_bit.rfdt7; + + /* release the fifo */ + can_receive_fifo_release(can_x, fifo_number); +} + +/** + * @brief release the specified fifo of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param fifo_number: fifo to be release. + * this parameter can be one of the following values: + * - CAN_RX_FIFO0 + * - CAN_RX_FIFO1 + * @retval none. + */ +void can_receive_fifo_release(can_type* can_x, can_rx_fifo_num_type fifo_number) +{ + switch (fifo_number) + { + case CAN_RX_FIFO0: + can_x->rf0 = CAN_RF0_RF0R_VAL; + break; + case CAN_RX_FIFO1: + can_x->rf1 = CAN_RF1_RF1R_VAL; + break; + default: + break; + } +} + +/** + * @brief return the number of pending messages of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param fifo_number: receive fifo number. + * this parameter can be one of the following values: + * - CAN_RX_FIFO0 + * - CAN_RX_FIFO1 + * @retval the number of message pending in the receive fifo. + */ +uint8_t can_receive_message_pending_get(can_type* can_x, can_rx_fifo_num_type fifo_number) +{ + uint8_t message_pending = 0; + switch (fifo_number) + { + case CAN_RX_FIFO0: + message_pending = can_x->rf0_bit.rf0mn; + break; + case CAN_RX_FIFO1: + message_pending = can_x->rf1_bit.rf1mn; + break; + default: + break; + } + return message_pending; +} + +/** + * @brief set the operation mode of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param can_operating_mode: can operating mode. + * this parameter can be one of the following values: + * - CAN_OPERATINGMODE_FREEZE + * - CAN_OPERATINGMODE_DOZE + * - CAN_OPERATINGMODE_COMMUNICATE + * @retval status of operation mode set + * this parameter can be one of the following values: + * SUCCESS or ERROR + */ +error_status can_operating_mode_set(can_type* can_x, can_operating_mode_type can_operating_mode) +{ + error_status status = ERROR; + uint32_t time_out_index = FZC_TIMEOUT; + + if (can_operating_mode == CAN_OPERATINGMODE_FREEZE) + { + /* request enter freeze mode */ + can_x->mctrl_bit.dzen = FALSE; + can_x->mctrl_bit.fzen = TRUE; + + while(((can_x->msts_bit.dzc) || (!can_x->msts_bit.fzc)) && (time_out_index != 0)) + { + time_out_index--; + } + if((can_x->msts_bit.dzc) || (!can_x->msts_bit.fzc)) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else if(can_operating_mode == CAN_OPERATINGMODE_DOZE) + { + /* request enter doze mode */ + can_x->mctrl_bit.dzen = TRUE; + can_x->mctrl_bit.fzen = FALSE; + + while(((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0)) + { + time_out_index--; + } + if((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else if(can_operating_mode == CAN_OPERATINGMODE_COMMUNICATE) + { + /* request enter normal mode */ + can_x->mctrl_bit.dzen = FALSE; + can_x->mctrl_bit.fzen = FALSE; + + while(((can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0)) + { + time_out_index--; + } + if((can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + } + else + { + status = ERROR; + } + return status; +} + +/** + * @brief enter the low power mode of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @retval status of doze mode enter, the returned value can be: + * - CAN_ENTER_DOZE_SUCCESSFUL + * - CAN_ENTER_DOZE_FAILED + */ +can_enter_doze_status_type can_doze_mode_enter(can_type* can_x) +{ + can_enter_doze_status_type status = CAN_ENTER_DOZE_FAILED; + uint32_t time_out_index = FZC_TIMEOUT; + can_x->mctrl_bit.fzen = FALSE; + can_x->mctrl_bit.dzen = TRUE; + while(((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) && (time_out_index != 0)) + { + time_out_index--; + } + if((!can_x->msts_bit.dzc) || (can_x->msts_bit.fzc)) + { + status = CAN_ENTER_DOZE_FAILED; + } + else + { + status = CAN_ENTER_DOZE_SUCCESSFUL; + } + return status; +} + +/** + * @brief exit the doze mode of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @retval status of doze mode enter, the returned value can be: + * - CAN_QUIT_DOZE_SUCCESSFUL + * - CAN_QUIT_DOZE_FAILED + */ +can_quit_doze_status_type can_doze_mode_exit(can_type* can_x) +{ + can_quit_doze_status_type status = CAN_QUIT_DOZE_FAILED; + uint32_t time_out_index = DZC_TIMEOUT; + can_x->mctrl_bit.dzen = FALSE; + while((can_x->msts_bit.dzc) && (time_out_index != 0)) + { + time_out_index--; + } + if(!can_x->msts_bit.dzc) + { + status = CAN_QUIT_DOZE_SUCCESSFUL; + } + return status; +} + +/** + * @brief return the error type record (etr) of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @retval the value of the error code + * the return can be one of the follow values: + * - CAN_ERRORRECORD_NOERR + * - CAN_ERRORRECORD_STUFFERR, + * - CAN_ERRORRECORD_FORMERR, + * - CAN_ERRORRECORD_ACKERR, + * - CAN_ERRORRECORD_BITRECESSIVEERR, + * - CAN_ERRORRECORD_BITDOMINANTERR, + * - CAN_ERRORRECORD_CRCERR, + * - CAN_ERRORRECORD_SOFTWARESETERR + */ +can_error_record_type can_error_type_record_get(can_type* can_x) +{ + can_error_record_type error_code = CAN_ERRORRECORD_NOERR; + + error_code = (can_error_record_type)can_x->ests_bit.etr; + return error_code; +} + +/** + * @brief return the receive error counter (rec) of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @retval the value of receive error counter. + */ +uint8_t can_receive_error_counter_get(can_type* can_x) +{ + uint8_t counter = 0; + counter = can_x->ests_bit.rec; + return counter; +} + +/** + * @brief return the transmit error counter of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @retval the value of transmit error counter. + */ +uint8_t can_transmit_error_counter_get(can_type* can_x) +{ + uint8_t counter = 0; + counter = can_x->ests_bit.tec; + return counter; +} + +/** + * @brief enable or disable the interrupt of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param can_int: specifies the can interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - CAN_TCIEN_INT + * - CAN_RF0MIEN_INT + * - CAN_RF0FIEN_INT + * - CAN_RF0OIEN_INT + * - CAN_RF1MIEN_INT + * - CAN_RF1FIEN_INT + * - CAN_RF1OIEN_INT + * - CAN_EAIEN_INT + * - CAN_EPIEN_INT + * - CAN_BOIEN_INT + * - CAN_ETRIEN_INT + * - CAN_EOIEN_INT + * - CAN_QDZIEN_INT + * - CAN_EDZIEN_INT + * @param new_state: new state of the can interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none. + */ +void can_interrupt_enable(can_type* can_x, uint32_t can_int, confirm_state new_state) +{ + if (new_state != FALSE) + { + can_x->inten |= can_int; + } + else + { + can_x->inten &= ~can_int; + } +} + +/** + * @brief get interrupt flag of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param can_flag: select the flag. + * this parameter can be one of the following flags: + * - CAN_EAF_FLAG + * - CAN_EPF_FLAG + * - CAN_BOF_FLAG + * - CAN_ETR_FLAG + * - CAN_EOIF_FLAG + * - CAN_TM0TCF_FLAG + * - CAN_TM1TCF_FLAG + * - CAN_TM2TCF_FLAG + * - CAN_RF0MN_FLAG + * - CAN_RF0FF_FLAG + * - CAN_RF0OF_FLAG + * - CAN_RF1MN_FLAG + * - CAN_RF1FF_FLAG + * - CAN_RF1OF_FLAG + * - CAN_QDZIF_FLAG + * - CAN_EDZC_FLAG + * - CAN_TMEF_FLAG + * note:the state of CAN_EDZC_FLAG need to check dzc and edzif bit + * note:the state of CAN_TMEF_FLAG need to check rqc0,rqc1 and rqc2 bit + * @retval status of can_flag, the returned value can be:SET or RESET. + */ +flag_status can_interrupt_flag_get(can_type* can_x, uint32_t can_flag) +{ + flag_status bit_status = RESET; + flag_status int_status = RESET; + + switch(can_flag) + { + case CAN_EAF_FLAG: + int_status = (flag_status)(can_x->inten_bit.eoien && can_x->inten_bit.eaien); + break; + case CAN_EPF_FLAG: + int_status = (flag_status)(can_x->inten_bit.eoien && can_x->inten_bit.epien); + break; + case CAN_BOF_FLAG: + int_status = (flag_status)(can_x->inten_bit.eoien && can_x->inten_bit.boien); + break; + case CAN_ETR_FLAG: + int_status = (flag_status)(can_x->inten_bit.eoien && can_x->inten_bit.etrien); + break; + case CAN_EOIF_FLAG: + int_status = (flag_status)can_x->inten_bit.eoien; + break; + case CAN_TM0TCF_FLAG: + case CAN_TM1TCF_FLAG: + case CAN_TM2TCF_FLAG: + int_status = (flag_status)can_x->inten_bit.tcien; + break; + case CAN_RF0MN_FLAG: + int_status = (flag_status)can_x->inten_bit.rf0mien; + break; + case CAN_RF0FF_FLAG: + int_status = (flag_status)can_x->inten_bit.rf0fien; + break; + case CAN_RF0OF_FLAG: + int_status = (flag_status)can_x->inten_bit.rf0oien; + break; + case CAN_RF1MN_FLAG: + int_status = (flag_status)can_x->inten_bit.rf1mien; + break; + case CAN_RF1FF_FLAG: + int_status = (flag_status)can_x->inten_bit.rf1fien; + break; + case CAN_RF1OF_FLAG: + int_status = (flag_status)can_x->inten_bit.rf1oien; + break; + case CAN_QDZIF_FLAG: + int_status = (flag_status)can_x->inten_bit.qdzien; + break; + case CAN_EDZC_FLAG: + int_status = (flag_status)can_x->inten_bit.edzien; + break; + case CAN_TMEF_FLAG: + int_status = (flag_status)can_x->inten_bit.tcien; + break; + default: + int_status = RESET; + break; + } + + if(int_status != SET) + { + return RESET; + } + bit_status = can_flag_get(can_x, can_flag); + + return bit_status; +} + +/** + * @brief get flag of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param can_flag: select the flag. + * this parameter can be one of the following flags: + * - CAN_EAF_FLAG + * - CAN_EPF_FLAG + * - CAN_BOF_FLAG + * - CAN_ETR_FLAG + * - CAN_EOIF_FLAG + * - CAN_TM0TCF_FLAG + * - CAN_TM1TCF_FLAG + * - CAN_TM2TCF_FLAG + * - CAN_RF0MN_FLAG + * - CAN_RF0FF_FLAG + * - CAN_RF0OF_FLAG + * - CAN_RF1MN_FLAG + * - CAN_RF1FF_FLAG + * - CAN_RF1OF_FLAG + * - CAN_QDZIF_FLAG + * - CAN_EDZC_FLAG + * - CAN_TMEF_FLAG + * note:the state of CAN_EDZC_FLAG need to check dzc and edzif bit + * note:the state of CAN_TMEF_FLAG need to check rqc0,rqc1 and rqc2 bit + * @retval status of can_flag, the returned value can be:SET or RESET. + */ +flag_status can_flag_get(can_type* can_x, uint32_t can_flag) +{ + flag_status bit_status = RESET; + switch(can_flag) + { + case CAN_EAF_FLAG: + bit_status = (flag_status)can_x->ests_bit.eaf; + break; + case CAN_EPF_FLAG: + bit_status = (flag_status)can_x->ests_bit.epf; + break; + case CAN_BOF_FLAG: + bit_status = (flag_status)can_x->ests_bit.bof; + break; + case CAN_ETR_FLAG: + if(can_x->ests_bit.etr != 0) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + case CAN_EOIF_FLAG: + bit_status = (flag_status)can_x->msts_bit.eoif; + break; + case CAN_TM0TCF_FLAG: + bit_status = (flag_status)can_x->tsts_bit.tm0tcf; + break; + case CAN_TM1TCF_FLAG: + bit_status = (flag_status)can_x->tsts_bit.tm1tcf; + break; + case CAN_TM2TCF_FLAG: + bit_status = (flag_status)can_x->tsts_bit.tm2tcf; + break; + case CAN_RF0MN_FLAG: + if(can_x->rf0_bit.rf0mn != 0) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + case CAN_RF0FF_FLAG: + bit_status = (flag_status)can_x->rf0_bit.rf0ff; + break; + case CAN_RF0OF_FLAG: + bit_status = (flag_status)can_x->rf0_bit.rf0of; + break; + case CAN_RF1MN_FLAG: + if(can_x->rf1_bit.rf1mn != 0) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + case CAN_RF1FF_FLAG: + bit_status = (flag_status)can_x->rf1_bit.rf1ff; + break; + case CAN_RF1OF_FLAG: + bit_status = (flag_status)can_x->rf1_bit.rf1of; + break; + case CAN_QDZIF_FLAG: + bit_status = (flag_status)can_x->msts_bit.qdzif; + break; + case CAN_EDZC_FLAG: + if((can_x->msts_bit.dzc != RESET) ||(can_x->msts_bit.edzif != RESET)) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + case CAN_TMEF_FLAG: + if((can_x->tsts_bit.tm0ef != RESET) || (can_x->tsts_bit.tm1ef != RESET) || (can_x->tsts_bit.tm2ef != RESET)) + { + bit_status = SET; + } + else + { + bit_status = RESET; + } + break; + default: + bit_status = RESET; + break; + } + return bit_status; +} + +/** + * @brief clear flag of the specified can peripheral. + * @param can_x: select the can peripheral. + * this parameter can be one of the following values: + * CAN1. + * @param can_flag: select the flag. + * this parameter can be one of the following flags: + * - CAN_EAF_FLAG + * - CAN_EPF_FLAG + * - CAN_BOF_FLAG + * - CAN_ETR_FLAG + * - CAN_EOIF_FLAG + * - CAN_TM0TCF_FLAG + * - CAN_TM1TCF_FLAG + * - CAN_TM2TCF_FLAG + * - CAN_RF0FF_FLAG + * - CAN_RF0OF_FLAG + * - CAN_RF1FF_FLAG + * - CAN_RF1OF_FLAG + * - CAN_QDZIF_FLAG + * - CAN_EDZC_FLAG + * - CAN_TMEF_FLAG + * note:CAN_RF0MN_FLAG and CAN_RF1MN_FLAG can not clear by this function + * @retval none. + */ +void can_flag_clear(can_type* can_x, uint32_t can_flag) +{ + switch(can_flag) + { + case CAN_EAF_FLAG: + case CAN_EPF_FLAG: + case CAN_BOF_FLAG: + case CAN_EOIF_FLAG: + can_x->msts = CAN_MSTS_EOIF_VAL; + break; + case CAN_ETR_FLAG: + can_x->msts = CAN_MSTS_EOIF_VAL; + can_x->ests = 0; + break; + case CAN_TM0TCF_FLAG: + can_x->tsts = CAN_TSTS_TM0TCF_VAL; + break; + case CAN_TM1TCF_FLAG: + can_x->tsts = CAN_TSTS_TM1TCF_VAL; + break; + case CAN_TM2TCF_FLAG: + can_x->tsts = CAN_TSTS_TM2TCF_VAL; + break; + case CAN_RF0FF_FLAG: + can_x->rf0 = CAN_RF0_RF0FF_VAL; + break; + case CAN_RF0OF_FLAG: + can_x->rf0 = CAN_RF0_RF0OF_VAL; + break; + case CAN_RF1FF_FLAG: + can_x->rf1 = CAN_RF1_RF1FF_VAL; + break; + case CAN_RF1OF_FLAG: + can_x->rf1 = CAN_RF1_RF1OF_VAL; + break; + case CAN_QDZIF_FLAG: + can_x->msts = CAN_MSTS_QDZIF_VAL; + break; + case CAN_EDZC_FLAG: + can_x->msts = CAN_MSTS_EDZIF_VAL; + break; + case CAN_TMEF_FLAG: + can_x->tsts = CAN_TSTS_TM0TCF_VAL | CAN_TSTS_TM1TCF_VAL | CAN_TSTS_TM2TCF_VAL; + break; + default: + break; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_crc.c b/libraries/drivers/src/at32f425_crc.c new file mode 100644 index 0000000..7072f52 --- /dev/null +++ b/libraries/drivers/src/at32f425_crc.c @@ -0,0 +1,208 @@ +/** + ************************************************************************** + * @file at32f425_crc.c + * @brief contains all the functions for the crc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup CRC + * @brief CRC driver modules + * @{ + */ + +#ifdef CRC_MODULE_ENABLED + +/** @defgroup CRC_private_functions + * @{ + */ + +/** + * @brief reset the crc data register. + * @param none + * @retval none + */ +void crc_data_reset(void) +{ + /* reset crc generator */ + CRC->ctrl_bit.rst = 0x1; +} + +/** + * @brief compute the 32-bit crc of a given data word(32-bit). + * @param data: data word(32-bit) to compute its crc + * @retval 32-bit crc + */ +uint32_t crc_one_word_calculate(uint32_t data) +{ + CRC->dt = data; + return (CRC->dt); +} + +/** + * @brief compute the 32-bit crc of a given buffer of data word(32-bit). + * @param pbuffer: pointer to the buffer containing the data to be computed + * @param length: length of the buffer to be computed + * @retval 32-bit crc + */ +uint32_t crc_block_calculate(uint32_t *pbuffer, uint32_t length) +{ + uint32_t index = 0; + + for(index = 0; index < length; index++) + { + CRC->dt = pbuffer[index]; + } + + return (CRC->dt); +} + +/** + * @brief return the current crc value. + * @param none + * @retval 32-bit crc + */ +uint32_t crc_data_get(void) +{ + return (CRC->dt); +} + +/** + * @brief store a 8-bit data in the common data register. + * @param cdt_value: 8-bit value to be stored in the common data register + * @retval none + */ +void crc_common_data_set(uint8_t cdt_value) +{ + CRC->cdt_bit.cdt = cdt_value; +} + +/** + * @brief return the 8-bit data stored in the common data register + * @param none + * @retval 8-bit value of the common data register + */ +uint8_t crc_common_data_get(void) +{ + return (CRC->cdt_bit.cdt); +} + +/** + * @brief set the 32-bit initial data of crc + * @param value: initial data + * @retval none + */ +void crc_init_data_set(uint32_t value) +{ + CRC->idt = value; +} + +/** + * @brief control the reversal of the bit order in the input data + * @param value + * this parameter can be one of the following values: + * - CRC_REVERSE_INPUT_NO_AFFECTE + * - CRC_REVERSE_INPUT_BY_BYTE + * - CRC_REVERSE_INPUT_BY_HALFWORD + * - CRC_REVERSE_INPUT_BY_WORD + * @retval none. + */ +void crc_reverse_input_data_set(crc_reverse_input_type value) +{ + CRC->ctrl_bit.revid = value; +} + +/** + * @brief control the reversal of the bit order in the output data + * @param value + * this parameter can be one of the following values: + * - CRC_REVERSE_OUTPUT_NO_AFFECTE + * - CRC_REVERSE_OUTPUT_DATA + * @retval none. + */ +void crc_reverse_output_data_set(crc_reverse_output_type value) +{ + CRC->ctrl_bit.revod = value; +} + +/** + * @brief config crc polynomial value + * @param value + * 32-bit new data of crc poly value + * @retval none. + */ +void crc_poly_value_set(uint32_t value) +{ + CRC->poly = value; +} + +/** + * @brief return crc polynomial value + * @param none + * @retval 32-bit value of the polynomial value. + */ +uint32_t crc_poly_value_get(void) +{ + return (CRC->poly); +} + +/** + * @brief config crc polynomial data size + * @param size + * this parameter can be one of the following values: + * - CRC_POLY_SIZE_32B + * - CRC_POLY_SIZE_16B + * - CRC_POLY_SIZE_8B + * - CRC_POLY_SIZE_7B + * @retval none. + */ +void crc_poly_size_set(crc_poly_size_type size) +{ + CRC->ctrl_bit.poly_size = size; +} + +/** + * @brief return crc polynomial data size + * @param none + * @retval polynomial data size. + */ +crc_poly_size_type crc_poly_size_get(void) +{ + return (crc_poly_size_type)(CRC->ctrl_bit.poly_size); +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_crm.c b/libraries/drivers/src/at32f425_crm.c new file mode 100644 index 0000000..104eea4 --- /dev/null +++ b/libraries/drivers/src/at32f425_crm.c @@ -0,0 +1,987 @@ +/** + ************************************************************************** + * @file at32f425_crm.c + * @brief contains all the functions for the crm firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup CRM + * @brief CRM driver modules + * @{ + */ + +#ifdef CRM_MODULE_ENABLED + +/** @defgroup CRM_private_functions + * @{ + */ + +/** + * @brief reset the crm register + * @param none + * @retval none + */ +void crm_reset(void) +{ + /* reset the crm clock configuration to the default reset state(for debug purpose) */ + /* set hicken bit */ + CRM->ctrl_bit.hicken = TRUE; + + /* wait hick stable */ + while(CRM->ctrl_bit.hickstbl != SET); + + /* hick used as system clock */ + CRM->cfg_bit.sclksel = CRM_SCLK_HICK; + + /* wait sclk switch status */ + while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK); + + /* reset hexten, hextbyps, cfden and pllen bits */ + CRM->ctrl &= ~(0x010D0000U); + + /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv, + clkout pllrcs, pllhextdiv, pllmult, usbdiv and pllrange bits */ + CRM->cfg = 0; + + /* reset pllfr, pllms, pllns and pllfref bits */ + CRM->pll = (0x00001F10U); + + /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */ + CRM->misc1 = 0x00100000; + + /* disable all interrupts enable and clear pending bits */ + CRM->clkint = 0x009F0000; +} + +/** + * @brief enable or disable crm low speed external crystal bypass + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_lext_bypass(confirm_state new_state) +{ + CRM->bpdc_bit.lextbyps = new_state; +} + +/** + * @brief enable or disable crm high speed external crystal bypass + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_hext_bypass(confirm_state new_state) +{ + CRM->ctrl_bit.hextbyps = new_state; +} + +/** + * @brief get crm flag status + * @param flag + * this parameter can be one of the following values: + * - CRM_HICK_STABLE_FLAG + * - CRM_HEXT_STABLE_FLAG + * - CRM_PLL_STABLE_FLAG + * - CRM_LEXT_STABLE_FLAG + * - CRM_LICK_STABLE_FLAG + * - CRM_NRST_RESET_FLAG + * - CRM_POR_RESET_FLAG + * - CRM_SW_RESET_FLAG + * - CRM_WDT_RESET_FLAG + * - CRM_WWDT_RESET_FLAG + * - CRM_LOWPOWER_RESET_FLAG + * interrupt flag: + * - CRM_LICK_READY_INT_FLAG + * - CRM_LEXT_READY_INT_FLAG + * - CRM_HICK_READY_INT_FLAG + * - CRM_HEXT_READY_INT_FLAG + * - CRM_PLL_READY_INT_FLAG + * - CRM_CLOCK_FAILURE_INT_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status crm_flag_get(uint32_t flag) +{ + flag_status status = RESET; + if((CRM_REG(flag) & CRM_REG_BIT(flag)) != CRM_REG_BIT(flag)) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief get crm interrupt flag status + * @param flag + * this parameter can be one of the following values: + * - CRM_LICK_READY_INT_FLAG + * - CRM_LEXT_READY_INT_FLAG + * - CRM_HICK_READY_INT_FLAG + * - CRM_HEXT_READY_INT_FLAG + * - CRM_PLL_READY_INT_FLAG + * - CRM_CLOCK_FAILURE_INT_FLAG + * @retval flag_status (SET or RESET) + */ +flag_status crm_interrupt_flag_get(uint32_t flag) +{ + flag_status status = RESET; + switch(flag) + { + case CRM_LICK_READY_INT_FLAG: + if(CRM->clkint_bit.lickstblf && CRM->clkint_bit.lickstblien) + { + status = SET; + } + break; + case CRM_LEXT_READY_INT_FLAG: + if(CRM->clkint_bit.lextstblf && CRM->clkint_bit.lextstblien) + { + status = SET; + } + break; + case CRM_HICK_READY_INT_FLAG: + if(CRM->clkint_bit.hickstblf && CRM->clkint_bit.hickstblien) + { + status = SET; + } + break; + case CRM_HEXT_READY_INT_FLAG: + if(CRM->clkint_bit.hextstblf && CRM->clkint_bit.hextstblien) + { + status = SET; + } + break; + case CRM_PLL_READY_INT_FLAG: + if(CRM->clkint_bit.pllstblf && CRM->clkint_bit.pllstblien) + { + status = SET; + } + break; + case CRM_CLOCK_FAILURE_INT_FLAG: + if(CRM->clkint_bit.cfdf && CRM->ctrl_bit.cfden) + { + status = SET; + } + break; + } + + return status; +} + +/** + * @brief wait for hext stable + * @param none + * @retval error_status (ERROR or SUCCESS) + */ +error_status crm_hext_stable_wait(void) +{ + uint32_t stable_cnt = 0; + error_status status = ERROR; + + while((crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET) && (stable_cnt < HEXT_STARTUP_TIMEOUT)) + { + stable_cnt ++; + } + + if(crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET) + { + status = ERROR; + } + else + { + status = SUCCESS; + } + + return status; +} + +/** + * @brief set the hick trimming value + * @param trim_value (0x00~0x3F) + * @retval none + */ +void crm_hick_clock_trimming_set(uint8_t trim_value) +{ + CRM->ctrl_bit.hicktrim = trim_value; +} + +/** + * @brief set the crm calibration value + * @param cali_value (0x00~0xFF) + * @retval none + */ +void crm_hick_clock_calibration_set(uint8_t cali_value) +{ + /* enable write hick calibration */ + CRM->misc1_bit.hickcal_key = 0x5A; + + /* write hick calibration value */ + CRM->ctrl_bit.hickcal = cali_value; + + /* disable write hick calibration */ + CRM->misc1_bit.hickcal_key = 0x0; +} + +/** + * @brief enable or disable the peripheral clock + * @param value + * this parameter can be one of the following values: + * - CRM_DMA1_PERIPH_CLOCK - CRM_CRC_PERIPH_CLOCK - CRM_OTGFS1_PERIPH_CLOCK - CRM_GPIOA_PERIPH_CLOCK + * - CRM_GPIOB_PERIPH_CLOCK - CRM_GPIOC_PERIPH_CLOCK - CRM_GPIOD_PERIPH_CLOCK - CRM_GPIOF_PERIPH_CLOCK + * - CRM_SCFG_PERIPH_CLOCK - CRM_ADC1_PERIPH_CLOCK - CRM_TMR1_PERIPH_CLOCK - CRM_SPI1_PERIPH_CLOCK + * - CRM_USART1_PERIPH_CLOCK - CRM_TMR15_PERIPH_CLOCK - CRM_TMR16_PERIPH_CLOCK - CRM_TMR17_PERIPH_CLOCK + * - CRM_TMR2_PERIPH_CLOCK - CRM_TMR3_PERIPH_CLOCK - CRM_TMR6_PERIPH_CLOCK - CRM_TMR7_PERIPH_CLOCK + * - CRM_TMR13_PERIPH_CLOCK - CRM_TMR14_PERIPH_CLOCK - CRM_WWDT_PERIPH_CLOCK - CRM_SPI2_PERIPH_CLOCK + * - CRM_SPI3_PERIPH_CLOCK - CRM_USART2_PERIPH_CLOCK - CRM_USART3_PERIPH_CLOCK - CRM_USART4_PERIPH_CLOCK + * - CRM_I2C1_PERIPH_CLOCK - CRM_I2C2_PERIPH_CLOCK - CRM_CAN1_PERIPH_CLOCK - CRM_ACC_PERIPH_CLOCK + * - CRM_PWC_PERIPH_CLOCK + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_periph_clock_enable(crm_periph_clock_type value, confirm_state new_state) +{ + /* enable periph clock */ + if(TRUE == new_state) + { + CRM_REG(value) |= CRM_REG_BIT(value); + } + /* disable periph clock */ + else + { + CRM_REG(value) &= ~(CRM_REG_BIT(value)); + } +} + +/** + * @brief enable or disable the peripheral reset + * @param value + * this parameter can be one of the following values: + * - CRM_OTGFS1_PERIPH_RESET - CRM_GPIOA_PERIPH_RESET - CRM_GPIOB_PERIPH_RESET - CRM_GPIOC_PERIPH_RESET + * - CRM_GPIOD_PERIPH_RESET - CRM_GPIOF_PERIPH_RESET - CRM_SCFG_PERIPH_RESET - CRM_EXINT_PERIPH_RESET + * - CRM_ADC1_PERIPH_RESET - CRM_TMR1_PERIPH_RESET - CRM_SPI1_PERIPH_RESET - CRM_USART1_PERIPH_RESET + * - CRM_TMR15_PERIPH_RESET - CRM_TMR16_PERIPH_RESET - CRM_TMR17_PERIPH_RESET - CRM_TMR2_PERIPH_RESET + * - CRM_TMR3_PERIPH_RESET - CRM_TMR6_PERIPH_RESET - CRM_TMR7_PERIPH_RESET - CRM_TMR13_PERIPH_RESET + * - CRM_TMR14_PERIPH_RESET - CRM_WWDT_PERIPH_RESET - CRM_SPI2_PERIPH_RESET - CRM_SPI3_PERIPH_RESET + * - CRM_USART2_PERIPH_RESET - CRM_USART3_PERIPH_RESET - CRM_USART4_PERIPH_RESET - CRM_I2C1_PERIPH_RESET + * - CRM_I2C2_PERIPH_RESET - CRM_CAN1_PERIPH_RESET - CRM_ACC_PERIPH_RESET - CRM_PWC_PERIPH_RESET + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_periph_reset(crm_periph_reset_type value, confirm_state new_state) +{ + /* enable periph reset */ + if(new_state == TRUE) + { + CRM_REG(value) |= (CRM_REG_BIT(value)); + } + /* disable periph reset */ + else + { + CRM_REG(value) &= ~(CRM_REG_BIT(value)); + } +} + +/** + * @brief enable or disable the peripheral clock in sleep mode + * @param value + * this parameter can be one of the following values: + * - CRM_SRAM_PERIPH_CLOCK_SLEEP_MODE + * - CRM_FLASH_PERIPH_CLOCK_SLEEP_MODE + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_periph_sleep_mode_clock_enable(crm_periph_clock_sleepmd_type value, confirm_state new_state) +{ + /* enable periph clock in sleep mode */ + if(new_state == TRUE) + { + CRM_REG(value) |= (CRM_REG_BIT(value)); + } + /* disable perph clock in sleep mode */ + else + { + CRM_REG(value) &= ~(CRM_REG_BIT(value)); + } + +} + +/** + * @brief enable or disable the crm clock source + * @param source + * this parameter can be one of the following values: + * - CRM_CLOCK_SOURCE_HICK + * - CRM_CLOCK_SOURCE_HEXT + * - CRM_CLOCK_SOURCE_PLL + * - CRM_CLOCK_SOURCE_LEXT + * - CRM_CLOCK_SOURCE_LICK + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_clock_source_enable(crm_clock_source_type source, confirm_state new_state) +{ + switch(source) + { + case CRM_CLOCK_SOURCE_HICK: + CRM->ctrl_bit.hicken = new_state; + break; + case CRM_CLOCK_SOURCE_HEXT: + CRM->ctrl_bit.hexten = new_state; + break; + case CRM_CLOCK_SOURCE_PLL: + CRM->ctrl_bit.pllen = new_state; + break; + case CRM_CLOCK_SOURCE_LEXT: + CRM->bpdc_bit.lexten = new_state; + break; + case CRM_CLOCK_SOURCE_LICK: + CRM->ctrlsts_bit.licken = new_state; + break; + default: + break; + } +} + +/** + * @brief clear the crm reset flags + * @param flag + * this parameter can be one of the following values: + * reset flag: + * - CRM_NRST_RESET_FLAG + * - CRM_POR_RESET_FLAG + * - CRM_SW_RESET_FLAG + * - CRM_WDT_RESET_FLAG + * - CRM_WWDT_RESET_FLAG + * - CRM_LOWPOWER_RESET_FLAG + * - CRM_ALL_RESET_FLAG + * interrupt flag: + * - CRM_LICK_READY_INT_FLAG + * - CRM_LEXT_READY_INT_FLAG + * - CRM_HICK_READY_INT_FLAG + * - CRM_HEXT_READY_INT_FLAG + * - CRM_PLL_READY_INT_FLAG + * - CRM_CLOCK_FAILURE_INT_FLAG + * @retval none + */ +void crm_flag_clear(uint32_t flag) +{ + switch(flag) + { + case CRM_NRST_RESET_FLAG: + case CRM_POR_RESET_FLAG: + case CRM_SW_RESET_FLAG: + case CRM_WDT_RESET_FLAG: + case CRM_WWDT_RESET_FLAG: + case CRM_LOWPOWER_RESET_FLAG: + case CRM_ALL_RESET_FLAG: + CRM->ctrlsts_bit.rstfc = TRUE; + while(CRM->ctrlsts_bit.rstfc == TRUE); + break; + case CRM_LICK_READY_INT_FLAG: + CRM->clkint_bit.lickstblfc = TRUE; + break; + case CRM_LEXT_READY_INT_FLAG: + CRM->clkint_bit.lextstblfc = TRUE; + break; + case CRM_HICK_READY_INT_FLAG: + CRM->clkint_bit.hickstblfc = TRUE; + break; + case CRM_HEXT_READY_INT_FLAG: + CRM->clkint_bit.hextstblfc = TRUE; + break; + case CRM_PLL_READY_INT_FLAG: + CRM->clkint_bit.pllstblfc = TRUE; + break; + case CRM_CLOCK_FAILURE_INT_FLAG: + CRM->clkint_bit.cfdfc = TRUE; + break; + default: + break; + } +} + +/** + * @brief select ertc clock + * @param value + * this parameter can be one of the following values: + * - CRM_ERTC_CLOCK_LEXT + * - CRM_ERTC_CLOCK_LICK + * - CRM_ERTC_CLOCK_HEXT_DIV + * @retval none + */ +void crm_ertc_clock_select(crm_ertc_clock_type value) +{ + CRM->bpdc_bit.ertcsel = value; +} + +/** + * @brief enable or disable ertc + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_ertc_clock_enable(confirm_state new_state) +{ + CRM->bpdc_bit.ertcen = new_state; +} + +/** + * @brief set crm ahb division + * @param value + * this parameter can be one of the following values: + * - CRM_AHB_DIV_1 + * - CRM_AHB_DIV_2 + * - CRM_AHB_DIV_4 + * - CRM_AHB_DIV_8 + * - CRM_AHB_DIV_16 + * - CRM_AHB_DIV_64 + * - CRM_AHB_DIV_128 + * - CRM_AHB_DIV_256 + * - CRM_AHB_DIV_512 + * @retval none + */ +void crm_ahb_div_set(crm_ahb_div_type value) +{ + CRM->cfg_bit.ahbdiv = value; +} + +/** + * @brief set crm apb1 division + * @note the maximum frequency of APB1/APB2 clock is 96 MHz + * @param value + * this parameter can be one of the following values: + * - CRM_APB1_DIV_1 + * - CRM_APB1_DIV_2 + * - CRM_APB1_DIV_4 + * - CRM_APB1_DIV_8 + * - CRM_APB1_DIV_16 + * @retval none + */ +void crm_apb1_div_set(crm_apb1_div_type value) +{ + CRM->cfg_bit.apb1div = value; +} + +/** + * @brief set crm apb2 division + * @note the maximum frequency of APB1/APB2 clock is 96 MHz + * @param value + * this parameter can be one of the following values: + * - CRM_APB2_DIV_1 + * - CRM_APB2_DIV_2 + * - CRM_APB2_DIV_4 + * - CRM_APB2_DIV_8 + * - CRM_APB2_DIV_16 + * @retval none + */ +void crm_apb2_div_set(crm_apb2_div_type value) +{ + CRM->cfg_bit.apb2div = value; +} + +/** + * @brief set crm adc division + * @param value + * this parameter can be one of the following values: + * - CRM_ADC_DIV_2 + * - CRM_ADC_DIV_4 + * - CRM_ADC_DIV_6 + * - CRM_ADC_DIV_8 + * - CRM_ADC_DIV_12 + * - CRM_ADC_DIV_16 + * @retval none + */ +void crm_adc_clock_div_set(crm_adc_div_type div_value) +{ + CRM->cfg_bit.adcdiv_l = div_value & 0x03; + CRM->cfg_bit.adcdiv_h = (div_value >> 2) & 0x01; +} + +/** + * @brief set crm usb division + * @param value + * this parameter can be one of the following values: + * - CRM_USB_DIV_1_5 + * - CRM_USB_DIV_1 + * - CRM_USB_DIV_2_5 + * - CRM_USB_DIV_2 + * - CRM_USB_DIV_3_5 + * - CRM_USB_DIV_3 + * - CRM_USB_DIV_4 + * @retval none + */ +void crm_usb_clock_div_set(crm_usb_div_type div_value) +{ + CRM->cfg_bit.usbdiv_l = div_value & 0x03; + CRM->cfg_bit.usbdiv_h = (div_value >> 2) & 0x01; +} + +/** + * @brief enable or disable clock failure detection + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_clock_failure_detection_enable(confirm_state new_state) +{ + CRM->ctrl_bit.cfden = new_state; +} + +/** + * @brief battery powered domain software reset + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_battery_powered_domain_reset(confirm_state new_state) +{ + CRM->bpdc_bit.bpdrst = new_state; +} + +/** + * @brief config crm pll + * @param clock_source + * this parameter can be one of the following values: + * - CRM_PLL_SOURCE_HICK + * - CRM_PLL_SOURCE_HEXT + * - CRM_PLL_SOURCE_HEXT_DIV + * @param mult_value (CRM_PLL_MULT_2~64) + * @retval none + */ +void crm_pll_config(crm_pll_clock_source_type clock_source, crm_pll_mult_type mult_value) +{ + uint32_t pllrcfreq = 0; + crm_pll_fref_type pllfref = CRM_PLL_FREF_4M; + + /* config pll clock source */ + if(clock_source == CRM_PLL_SOURCE_HICK) + { + CRM->cfg_bit.pllrcs = FALSE; + pllrcfreq = (HICK_VALUE / 2); + CRM->misc1_bit.hickdiv = CRM_HICK48_NODIV; + } + else + { + CRM->cfg_bit.pllrcs = TRUE; + if(CRM_PLL_SOURCE_HEXT == clock_source) + { + pllrcfreq = HEXT_VALUE; + CRM->cfg_bit.pllhextdiv = FALSE; + } + else + { + pllrcfreq = (HEXT_VALUE / 2); + CRM->cfg_bit.pllhextdiv = TRUE; + } + } + + if((pllrcfreq > 3900000U) && (pllrcfreq < 5000000U)) + { + pllfref = CRM_PLL_FREF_4M; + } + else if((pllrcfreq > 5200000U) && (pllrcfreq < 6250000U)) + { + pllfref = CRM_PLL_FREF_6M; + } + else if((pllrcfreq > 7812500U) && (pllrcfreq < 8330000U)) + { + pllfref = CRM_PLL_FREF_8M; + } + else if((pllrcfreq > 8330000U) && (pllrcfreq < 12500000U)) + { + pllfref = CRM_PLL_FREF_12M; + } + else if((pllrcfreq > 15625000U) && (pllrcfreq < 20830000U)) + { + pllfref = CRM_PLL_FREF_16M; + } + else if((pllrcfreq > 20830000U) && (pllrcfreq < 31255000U)) + { + pllfref = CRM_PLL_FREF_25M; + } + + /* config pll multiplication factor */ + CRM->cfg_bit.pllmult_l = (mult_value & 0x0F); + CRM->cfg_bit.pllmult_h = ((mult_value & 0x30) >> 4); + + /* config pll fref */ + CRM->pll_bit.pllfref = pllfref; +} + +/** + * @brief config crm pll function2, another method. + * pll_rcs_freq * pll_ns + * pll clock = -------------------------------- + * pll_ms * pll_fr_n + * attemtion: + * 31 <= pll_ns <= 500 + * 1 <= pll_ms <= 15 + * + * pll_rcs_freq + * 2mhz <= ---------------------- <= 16mhz + * pll_ms + * + * pll_rcs_freq * pll_ns + * 500mhz <= -------------------------------- <= 1000mhz + * pll_ms + * @param clock_source + * this parameter can be one of the following values: + * - CRM_PLL_SOURCE_HICK + * - CRM_PLL_SOURCE_HEXT + * - CRM_PLL_SOURCE_HEXT_DIV + * @param pll_ns (31~500) + * @param pll_ms (1~15) + * @param pll_fr + * this parameter can be one of the following values: + * - CRM_PLL_FR_1 + * - CRM_PLL_FR_2 + * - CRM_PLL_FR_4 + * - CRM_PLL_FR_8 + * - CRM_PLL_FR_16 + * - CRM_PLL_FR_32 + * @retval none + */ +void crm_pll_config2(crm_pll_clock_source_type clock_source, uint16_t pll_ns, \ + uint16_t pll_ms, crm_pll_fr_type pll_fr) +{ + /* config pll clock source */ + if(clock_source == CRM_PLL_SOURCE_HICK) + { + CRM->cfg_bit.pllrcs = FALSE; + CRM->misc1_bit.hickdiv = CRM_HICK48_NODIV; + } + else + { + CRM->cfg_bit.pllrcs = TRUE; + if(clock_source == CRM_PLL_SOURCE_HEXT) + { + CRM->cfg_bit.pllhextdiv = FALSE; + } + else + { + CRM->cfg_bit.pllhextdiv = TRUE; + } + } + + /* config pll multiplication factor */ + CRM->pll_bit.pllns = pll_ns; + CRM->pll_bit.pllms = pll_ms; + CRM->pll_bit.pllfr = pll_fr; + + CRM->pll_bit.pllcfgen = TRUE; +} + +/** + * @brief select system clock source + * @param value + * this parameter can be one of the following values: + * - CRM_SCLK_HICK + * - CRM_SCLK_HEXT + * - CRM_SCLK_PLL + * @retval none + */ +void crm_sysclk_switch(crm_sclk_type value) +{ + CRM->cfg_bit.sclksel = value; +} + +/** + * @brief indicate which clock source is used as system clock + * @param none + * @retval crm_sclk + * this return can be one of the following values: + * - CRM_SCLK_HICK + * - CRM_SCLK_HEXT + * - CRM_SCLK_PLL + */ +crm_sclk_type crm_sysclk_switch_status_get(void) +{ + return (crm_sclk_type)CRM->cfg_bit.sclksts; +} + +/** + * @brief get crm clocks freqency + * @param clocks + * - pointer to the crm_clocks_freq structure + * @retval none + */ +void crm_clocks_freq_get(crm_clocks_freq_type *clocks_struct) +{ + uint32_t pll_mult = 0, pll_mult_h = 0, pll_clock_source = 0, temp = 0, div_value = 0; + uint32_t pllrcsfreq = 0, pll_ms = 0, pll_ns = 0, pll_fr = 0; + crm_sclk_type sclk_source; + + static const uint8_t sclk_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + static const uint8_t ahb_apb1_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + static const uint8_t ahb_apb2_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + static const uint8_t adc_div_table[8] = {2, 4, 6, 8, 2, 12, 8, 16}; + + /* get sclk source */ + sclk_source = crm_sysclk_switch_status_get(); + + switch(sclk_source) + { + case CRM_SCLK_HICK: + if(((CRM->misc2_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET)) + clocks_struct->sclk_freq = HICK_VALUE * 6; + else + clocks_struct->sclk_freq = HICK_VALUE; + break; + case CRM_SCLK_HEXT: + clocks_struct->sclk_freq = HEXT_VALUE; + break; + case CRM_SCLK_PLL: + pll_clock_source = CRM->cfg_bit.pllrcs; + if(CRM->pll_bit.pllcfgen == FALSE) + { + /* get multiplication factor */ + pll_mult = CRM->cfg_bit.pllmult_l; + pll_mult_h = CRM->cfg_bit.pllmult_h; + + /* process high bits */ + if((pll_mult_h != 0U) || (pll_mult == 15U)) + { + pll_mult += ((16U * pll_mult_h) + 1U); + } + else + { + pll_mult += 2U; + } + + if (pll_clock_source == 0x00) + { + /* hick divided by 2 selected as pll clock entry */ + clocks_struct->sclk_freq = (HICK_VALUE >> 1) * pll_mult; + } + else + { + /* hext selected as pll clock entry */ + if (CRM->cfg_bit.pllhextdiv != RESET) + { + /* hext clock divided by 2 */ + clocks_struct->sclk_freq = (HEXT_VALUE / 2) * pll_mult; + } + else + { + clocks_struct->sclk_freq = HEXT_VALUE * pll_mult; + } + } + } + else + { + pll_ms = CRM->pll_bit.pllms; + pll_ns = CRM->pll_bit.pllns; + pll_fr = CRM->pll_bit.pllfr; + + if (pll_clock_source == 0x00) + { + /* hick divided by 2 selected as pll clock entry */ + pllrcsfreq = (HICK_VALUE >> 1); + } + else + { + /* hext selected as pll clock entry */ + if (CRM->cfg_bit.pllhextdiv != RESET) + { + /* hext clock divided by 2 */ + pllrcsfreq = (HEXT_VALUE / 2); + } + else + { + pllrcsfreq = HEXT_VALUE; + } + } + clocks_struct->sclk_freq = (uint32_t)(((uint64_t)pllrcsfreq * pll_ns) / (pll_ms * (0x1 << pll_fr))); + } + break; + default: + clocks_struct->sclk_freq = HICK_VALUE; + break; + } + + /* compute sclk, ahbclk, abp1clk apb2clk and adcclk frequencies */ + /* get ahb division */ + temp = CRM->cfg_bit.ahbdiv; + div_value = sclk_ahb_div_table[temp]; + /* ahbclk frequency */ + clocks_struct->ahb_freq = clocks_struct->sclk_freq >> div_value; + + /* get apb1 division */ + temp = CRM->cfg_bit.apb1div; + div_value = ahb_apb1_div_table[temp]; + /* apb1clk frequency */ + clocks_struct->apb1_freq = clocks_struct->ahb_freq >> div_value; + + /* get apb2 division */ + temp = CRM->cfg_bit.apb2div; + div_value = ahb_apb2_div_table[temp]; + /* apb2clk frequency */ + clocks_struct->apb2_freq = clocks_struct->ahb_freq >> div_value; + + /* get adc division */ + temp = CRM->cfg_bit.adcdiv_h; + temp = ((temp << 2) | (CRM->cfg_bit.adcdiv_l)); + div_value = adc_div_table[temp]; + /* adcclk clock frequency */ + clocks_struct->adc_freq = clocks_struct->apb2_freq / div_value; +} + +/** + * @brief set crm clkout + * @param clkout + * this parameter can be one of the following values: + * - CRM_CLKOUT_NOCLK + * - CRM_CLKOUT_LICK + * - CRM_CLKOUT_LEXT + * - CRM_CLKOUT_SCLK + * - CRM_CLKOUT_HICK + * - CRM_CLKOUT_HEXT + * - CRM_CLKOUT_PLL_DIV_2 + * - CRM_CLKOUT_PLL_DIV_4 + * - CRM_CLKOUT_USB + * - CRM_CLKOUT_ADC + * @retval none + */ +void crm_clock_out_set(crm_clkout_select_type clkout) +{ + CRM->cfg_bit.clkout_sel = clkout & 0x7; + CRM->misc1_bit.clkout_sel = (clkout >> 3) & 0x1; +} + +/** + * @brief config crm interrupt + * @param int + * this parameter can be any combination of the following values: + * - CRM_LICK_STABLE_INT + * - CRM_LEXT_STABLE_INT + * - CRM_HICK_STABLE_INT + * - CRM_HEXT_STABLE_INT + * - CRM_PLL_STABLE_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void crm_interrupt_enable(uint32_t crm_int, confirm_state new_state) +{ + if(new_state == TRUE) + CRM->clkint |= crm_int; + else + CRM->clkint &= ~crm_int; +} + +/** + * @brief config hick divider select + * @param value + * this parameter can be one of the following values: + * - CRM_HICK48_DIV6 + * - CRM_HICK48_NODIV + * @retval none + */ +void crm_hick_divider_select(crm_hick_div_6_type value) +{ + CRM->misc1_bit.hickdiv = value; +} + +/** + * @brief hick as system clock frequency select + * @param value + * this parameter can be one of the following values: + * - CRM_HICK_SCLK_8MHZ + * - CRM_HICK_SCLK_48MHZ + * @retval none + */ +void crm_hick_sclk_frequency_select(crm_hick_sclk_frequency_type value) +{ + crm_hick_divider_select(CRM_HICK48_NODIV); + CRM->misc2_bit.hick_to_sclk = value; +} + +/** + * @brief usb 48 mhz clock source select + * @param value + * this parameter can be one of the following values: + * - CRM_USB_CLOCK_SOURCE_PLL + * - CRM_USB_CLOCK_SOURCE_HICK + * @retval none + */ +void crm_usb_clock_source_select(crm_usb_clock_source_type value) +{ + if(value == CRM_USB_CLOCK_SOURCE_HICK) + { + crm_hick_sclk_frequency_select(CRM_HICK_SCLK_48MHZ); + } + CRM->misc2_bit.hick_to_usb = value; +} + +/** + * @brief set crm clkout division + * @param clkout_div + * this parameter can be one of the following values: + * - CRM_CLKOUT_DIV_1 + * - CRM_CLKOUT_DIV_2 + * - CRM_CLKOUT_DIV_4 + * - CRM_CLKOUT_DIV_8 + * - CRM_CLKOUT_DIV_16 + * - CRM_CLKOUT_DIV_64 + * - CRM_CLKOUT_DIV_128 + * - CRM_CLKOUT_DIV_256 + * - CRM_CLKOUT_DIV_512 + * @retval none + */ +void crm_clkout_div_set(crm_clkout_div_type clkout_div) +{ + CRM->misc1_bit.clkoutdiv = clkout_div; +} + +/** + * @brief reset usb divider + * when enable pll, usb divider must reset. + * @param none + * @retval none + */ +void crm_usb_div_reset(void) +{ + uint8_t div_h = 0; + + /* reset usb divider */ + CRM->otg_exctrl_bit.usbdiv_rst = 1; + CRM->otg_exctrl_bit.usbdiv_rst = 0; + + div_h = CRM->cfg_bit.usbdiv_h; + CRM->cfg_bit.usbdiv_h = (~div_h) & 0x01; + CRM->cfg_bit.usbdiv_h = div_h; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ + diff --git a/libraries/drivers/src/at32f425_debug.c b/libraries/drivers/src/at32f425_debug.c new file mode 100644 index 0000000..92cf86b --- /dev/null +++ b/libraries/drivers/src/at32f425_debug.c @@ -0,0 +1,102 @@ +/** + ************************************************************************** + * @file at32f425_debug.c + * @brief contains all the functions for the debug firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup DEBUG + * @brief DEBUG driver modules + * @{ + */ + +#ifdef DEBUG_MODULE_ENABLED + +/** @defgroup DEBUG_private_functions + * @{ + */ + +/** + * @brief get debug device id + * @param none + * @retval the debug device id + */ +uint16_t debug_device_id_get(void) +{ + return (uint16_t)DEBUGMCU->pid; +} +/** + * @brief set periph debug mode + * @param periph_debug_mode + * this parameter can be any combination of the following values: + * - DEBUG_SLEEP + * - DEBUG_DEEPSLEEP + * - DEBUG_STANDBY + * - DEBUG_CAN_PAUSE + * - DEBUG_WDT_PAUSE + * - DEBUG_WWDT_PAUSE + * - DEBUG_TMR1_PAUSE + * - DEBUG_TMR2_PAUSE + * - DEBUG_TMR3_PAUSE + * - DEBUG_ERTC_PAUSE + * - DEBUG_I2C1_SMBUS_TIMEOUT + * - DEBUG_I2C2_SMBUS_TIMEOUT + * - DEBUG_TMR6_PAUSE + * - DEBUG_TMR7_PAUSE + * - DEBUG_ERTC_512_PAUSE + * - DEBUG_TMR15_PAUSE + * - DEBUG_TMR16_PAUSE + * - DEBUG_TMR17_PAUSE + * - DEBUG_TMR13_PAUSE + * - DEBUG_TMR14_PAUSE + * @param new_state (TRUE or FALSE) + * @retval none + */ +void debug_periph_mode_set(uint32_t periph_debug_mode, confirm_state new_state) +{ + if(new_state != FALSE) + { + DEBUGMCU->ctrl |= periph_debug_mode; + } + else + { + DEBUGMCU->ctrl &= ~periph_debug_mode; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_dma.c b/libraries/drivers/src/at32f425_dma.c new file mode 100644 index 0000000..6345c01 --- /dev/null +++ b/libraries/drivers/src/at32f425_dma.c @@ -0,0 +1,375 @@ +/** + ************************************************************************** + * @file at32f425_dma.c + * @brief contains all the functions for the dma firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup DMA + * @brief DMA driver modules + * @{ + */ + +#ifdef DMA_MODULE_ENABLED + +/** @defgroup DMA_private_functions + * @{ + */ + +/** + * @brief reset the dmax channely registers. + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * @retval none + */ +void dma_reset(dma_channel_type* dmax_channely) +{ + uint32_t temp = 0; + dmax_channely->ctrl_bit.chen = FALSE; + dmax_channely->ctrl = 0; + dmax_channely->dtcnt = 0; + dmax_channely->paddr = 0; + dmax_channely->maddr = 0; + + temp = (uint32_t)dmax_channely; + + /* dma1 channel */ + DMA1->clr |= (uint32_t)(0x0f << ((((temp & 0xff) - 0x08) / 0x14) * 4)); +} + +/** + * @brief set the number of data to be transferred + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * @param data_number: the number of data to be transferred(0x0000~0xFFFF) + * transfer. + * @retval none. + */ +void dma_data_number_set(dma_channel_type* dmax_channely, uint16_t data_number) +{ + dmax_channely->dtcnt = data_number; +} + +/** + * @brief get number of data from dtcnt register + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * @retval the number of data. + */ +uint16_t dma_data_number_get(dma_channel_type* dmax_channely) +{ + return (uint16_t)dmax_channely->dtcnt; +} + +/** + * @brief enable or disable dma interrupt + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * @param dma_int: + * this parameter can be any combination of the following values: + * - DMA_FDT_INT + * - DMA_HDT_INT + * - DMA_DTERR_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void dma_interrupt_enable(dma_channel_type* dmax_channely, uint32_t dma_int, confirm_state new_state) +{ + if (new_state != FALSE) + { + dmax_channely->ctrl |= dma_int; + } + else + { + dmax_channely->ctrl &= ~dma_int; + } +} + +/** + * @brief enable or disable dma channely + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * @param new_state (TRUE or FALSE) + * @retval None + */ +void dma_channel_enable(dma_channel_type* dmax_channely, confirm_state new_state) +{ + dmax_channely->ctrl_bit.chen = new_state; +} + +/** + * @brief initialize the dma_x flexible function according to the specified parameters. + * @param dma_x: + * this parameter can be one of the following values: + * - DMA1 + * @param flex_channelx: + * this parameter can be one of the following values: + * - FLEX_CHANNEL1 + * - FLEX_CHANNEL2 + * - FLEX_CHANNEL3 + * - FLEX_CHANNEL4 + * - FLEX_CHANNEL5 + * - FLEX_CHANNEL6 + * - FLEX_CHANNEL7 + * @param flexible_request: every peripheral have specified hardware_id. + * this parameter can be one of the following values: + * - DMA_FLEXIBLE_ADC1 - DMA_FLEXIBLE_UART4_RX - DMA_FLEXIBLE_TMR2_TRIG - DMA_FLEXIBLE_TMR7_OVERFLOW + * - DMA_FLEXIBLE_SPI1_RX - DMA_FLEXIBLE_UART4_TX - DMA_FLEXIBLE_TMR2_OVERFLOW - DMA_FLEXIBLE_TMR15_TRIG + * - DMA_FLEXIBLE_SPI1_TX - DMA_FLEXIBLE_I2C1_RX - DMA_FLEXIBLE_TMR2_CH1 - DMA_FLEXIBLE_TMR15_HALL + * - DMA_FLEXIBLE_SPI2_RX - DMA_FLEXIBLE_I2C1_TX - DMA_FLEXIBLE_TMR2_CH2 - DMA_FLEXIBLE_TMR15_OVERFLOW + * - DMA_FLEXIBLE_SPI2_TX - DMA_FLEXIBLE_I2C2_RX - DMA_FLEXIBLE_TMR2_CH3 - DMA_FLEXIBLE_TMR15_CH1 + * - DMA_FLEXIBLE_SPI3_RX - DMA_FLEXIBLE_I2C2_TX - DMA_FLEXIBLE_TMR2_CH4 - DMA_FLEXIBLE_TMR15_CH2 + * - DMA_FLEXIBLE_SPI3_TX - DMA_FLEXIBLE_TMR1_TRIG - DMA_FLEXIBLE_TMR3_TRIG - DMA_FLEXIBLE_TMR16_OVERFLOW + * - DMA_FLEXIBLE_UART1_RX - DMA_FLEXIBLE_TMR1_HALL - DMA_FLEXIBLE_TMR3_OVERFLOW - DMA_FLEXIBLE_TMR16_CH1 + * - DMA_FLEXIBLE_UART1_TX - DMA_FLEXIBLE_TMR1_OVERFLOW - DMA_FLEXIBLE_TMR3_CH1 - DMA_FLEXIBLE_TMR17_OVERFLOW + * - DMA_FLEXIBLE_UART2_RX - DMA_FLEXIBLE_TMR1_CH1 - DMA_FLEXIBLE_TMR3_CH2 - DMA_FLEXIBLE_TMR17_CH1 + * - DMA_FLEXIBLE_UART2_TX - DMA_FLEXIBLE_TMR1_CH2 - DMA_FLEXIBLE_TMR3_CH3 + * - DMA_FLEXIBLE_UART3_RX - DMA_FLEXIBLE_TMR1_CH3 - DMA_FLEXIBLE_TMR3_CH4 + * - DMA_FLEXIBLE_UART3_TX - DMA_FLEXIBLE_TMR1_CH4 - DMA_FLEXIBLE_TMR6_OVERFLOW + * @retval none + */ + +void dma_flexible_config(dma_type* dma_x, uint8_t flex_channelx, dma_flexible_request_type flexible_request) +{ + if(dma_x->src_sel1_bit.dma_flex_en == RESET) + { + dma_x->src_sel1_bit.dma_flex_en = TRUE; + } + + if(flex_channelx == FLEX_CHANNEL1) + { + dma_x->src_sel0_bit.ch1_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL2) + { + dma_x->src_sel0_bit.ch2_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL3) + { + dma_x->src_sel0_bit.ch3_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL4) + { + dma_x->src_sel0_bit.ch4_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL5) + { + dma_x->src_sel1_bit.ch5_src = flexible_request; + } + else if(flex_channelx == FLEX_CHANNEL6) + { + dma_x->src_sel1_bit.ch6_src = flexible_request; + } + else + { + if(flex_channelx == FLEX_CHANNEL7) + { + dma_x->src_sel1_bit.ch7_src = flexible_request; + } + } +} + +/** + * @brief get dma flag + * @param dmax_flag + * this parameter can be one of the following values: + * - DMA1_GL1_FLAG - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG + * - DMA1_GL2_FLAG - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG + * - DMA1_GL3_FLAG - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG + * - DMA1_GL4_FLAG - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG + * - DMA1_GL5_FLAG - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG + * - DMA1_GL6_FLAG - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG + * - DMA1_GL7_FLAG - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG + * @retval state of dma flag + */ +flag_status dma_flag_get(uint32_t dmax_flag) +{ + flag_status status = RESET; + uint32_t temp = 0; + + temp = DMA1->sts; + + if ((temp & dmax_flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief get dma interrupt flag + * @param dmax_flag + * this parameter can be one of the following values: + * - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG + * - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG + * - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG + * - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG + * - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG + * - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG + * - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG + * @retval state of dma flag + */ +flag_status dma_interrupt_flag_get(uint32_t dmax_flag) +{ + flag_status status = RESET; + uint32_t temp = 0; + + temp = DMA1->sts; + + if ((temp & dmax_flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief clear dma flag + * @param dmax_flag + * this parameter can be one of the following values: + * - DMA1_GL1_FLAG - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG + * - DMA1_GL2_FLAG - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG + * - DMA1_GL3_FLAG - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG + * - DMA1_GL4_FLAG - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG + * - DMA1_GL5_FLAG - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG + * - DMA1_GL6_FLAG - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG + * - DMA1_GL7_FLAG - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG + * @retval none + */ +void dma_flag_clear(uint32_t dmax_flag) +{ + DMA1->clr = dmax_flag; +} + +/** + * @brief dma init config with its default value. + * @param dma_init_struct : pointer to a dma_init_type structure which will + * be initialized. + * @retval none + */ +void dma_default_para_init(dma_init_type* dma_init_struct) +{ + dma_init_struct->peripheral_base_addr = 0x0; + dma_init_struct->memory_base_addr = 0x0; + dma_init_struct->direction = DMA_DIR_PERIPHERAL_TO_MEMORY; + dma_init_struct->buffer_size = 0x0; + dma_init_struct->peripheral_inc_enable = FALSE; + dma_init_struct->memory_inc_enable = FALSE; + dma_init_struct->peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + dma_init_struct->memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + dma_init_struct->loop_mode_enable = FALSE; + dma_init_struct->priority = DMA_PRIORITY_LOW; +} + +/** + * @brief dma init + * @param dmax_channely: + * this parameter can be one of the following values: + * - DMA1_CHANNEL1 + * - DMA1_CHANNEL2 + * - DMA1_CHANNEL3 + * - DMA1_CHANNEL4 + * - DMA1_CHANNEL5 + * - DMA1_CHANNEL6 + * - DMA1_CHANNEL7 + * @param dma_initstruct : pointer to a dma_init_type structure. + * @retval none + */ +void dma_init(dma_channel_type* dmax_channely, dma_init_type* dma_init_struct) +{ + /* clear ctrl register dtd bit and m2m bit */ + dmax_channely->ctrl &= 0xbfef; + dmax_channely->ctrl |= dma_init_struct->direction; + + dmax_channely->ctrl_bit.chpl = dma_init_struct->priority; + dmax_channely->ctrl_bit.mwidth = dma_init_struct->memory_data_width; + dmax_channely->ctrl_bit.pwidth = dma_init_struct->peripheral_data_width; + dmax_channely->ctrl_bit.mincm = dma_init_struct->memory_inc_enable; + dmax_channely->ctrl_bit.pincm = dma_init_struct->peripheral_inc_enable; + dmax_channely->ctrl_bit.lm = dma_init_struct->loop_mode_enable; + dmax_channely->dtcnt = dma_init_struct->buffer_size; + dmax_channely->paddr = dma_init_struct->peripheral_base_addr; + dmax_channely->maddr = dma_init_struct->memory_base_addr; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_ertc.c b/libraries/drivers/src/at32f425_ertc.c new file mode 100644 index 0000000..91387ae --- /dev/null +++ b/libraries/drivers/src/at32f425_ertc.c @@ -0,0 +1,1418 @@ +/** + ************************************************************************** + * @file at32f425_ertc.c + * @brief contains all the functions for the ertc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup ERTC + * @brief ERTC driver modules + * @{ + */ + +#ifdef ERTC_MODULE_ENABLED + +/** @defgroup ERTC_private_functions + * @{ + */ + +#define ERTC_TIMEOUT ((uint32_t) 0x00360000) + +/** + * @brief number conversion to bcd code. + * @param num: number(0~99) + * @retval bcd code. + */ +uint8_t ertc_num_to_bcd(uint8_t num) +{ + uint8_t bcd_h = 0, bcd_l = 0; + + bcd_h = num / 10; + bcd_l = num % 10; + + return ((uint8_t)(bcd_h << 4) | bcd_l); +} + +/** + * @brief bcd code conversion to number. + * @param bcd: bcd code(0~99). + * @retval number. + */ +uint8_t ertc_bcd_to_num(uint8_t bcd) +{ + return ((((uint8_t)(bcd & (uint8_t)0xF0) >> 4) * 10) + (bcd & (uint8_t)0x0F)); +} + +/** + * @brief enable write protection. + * @param none. + * @retval none + */ +void ertc_write_protect_enable(void) +{ + ERTC->wp = 0xFF; +} + +/** + * @brief disable write protection. + * @param none. + * @retval none + */ +void ertc_write_protect_disable(void) +{ + ERTC->wp = 0xCA; + ERTC->wp = 0x53; +} + +/** + * @brief ertc wait register update finish. + * @param none. + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_wait_update(void) +{ + uint32_t timeout = ERTC_TIMEOUT * 2; + + /* clear updf flag */ + ERTC->sts = ~(ERTC_UPDF_FLAG | 0x00000080) | (ERTC->sts_bit.imen << 7); + + while(ERTC->sts_bit.updf == 0) + { + if(timeout == 0) + { + return ERROR; + } + + timeout--; + } + + return SUCCESS; +} + +/** + * @brief ertc wait flag status. + * @param flag: flag to wait. + * this parameter can be one of the following values: + * - ERTC_ALAWF_FLAG: alarm a register allows write flag. + * - ERTC_WATWF_FLAG: wakeup timer register allows write flag. + * - ERTC_TADJF_FLAG: time adjustment flag. + * - ERTC_CALUPDF_FLAG: calibration value update completed flag. + * @param status: status to wait. + * this parameter can be one of the following values: + * - SET. + * - RESET. + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_wait_flag(uint32_t flag, flag_status status) +{ + uint32_t timeout = ERTC_TIMEOUT; + + while(ertc_flag_get(flag) == status) + { + if(timeout == 0) + { + /* enable write protection */ + ertc_write_protect_enable(); + + return ERROR; + } + + timeout--; + } + + return SUCCESS; +} + +/** + * @brief ertc enter init mode. + * @param none. + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_init_mode_enter(void) +{ + uint32_t timeout = ERTC_TIMEOUT * 2; + + if(ERTC->sts_bit.imf == 0) + { + /* enter init mode */ + ERTC->sts = 0xFFFFFFFF; + + while(ERTC->sts_bit.imf == 0) + { + if(timeout == 0) + { + /* enable write protection */ + ertc_write_protect_enable(); + + return ERROR; + } + + timeout--; + } + } + + return SUCCESS; +} + +/** + * @brief ertc exit init mode. + * @param none. + * @retval none. + */ +void ertc_init_mode_exit(void) +{ + ERTC->sts = 0xFFFFFF7F; +} + +/** + * @brief ertc reset all register. + * @param none. + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_reset(void) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl = (uint32_t)0x00000000; + + /* enter init mode */ + if(ertc_init_mode_enter() != SUCCESS) + { + return ERROR; + } + + /* reset register */ + ERTC->time = (uint32_t)0x00000000; + ERTC->date = (uint32_t)0x00002101; + ERTC->ctrl = (uint32_t)0x00000000; + ERTC->div = (uint32_t)0x007F00FF; + ERTC->wat = (uint32_t)0x0000FFFF; + ERTC->ala = (uint32_t)0x00000000; + ERTC->tadj = (uint32_t)0x00000000; + ERTC->scal = (uint32_t)0x00000000; + ERTC->tamp = (uint32_t)0x00000000; + ERTC->alasbs = (uint32_t)0x00000000; + ERTC->sts = (uint32_t)0x00000000; + + /* wait calendar update */ + ertc_wait_update(); + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief ertc division set. + * @param div_a: division a (0~0x7F). + * @param div_b: division b (0~0x7FFF). + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_divider_set(uint16_t div_a, uint16_t div_b) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + /* enter init mode */ + if(ertc_init_mode_enter() != SUCCESS) + { + return ERROR; + } + + /* config the ertc divider */ + ERTC->div_bit.diva = div_a; + ERTC->div_bit.divb = div_b; + + /* exit init mode */ + ertc_init_mode_exit(); + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief ertc hour mode set. + * @param mode: hour mode. + * this parameter can be one of the following values: + * - ERTC_HOUR_MODE_24: 24-hour format. + * - ERTC_HOUR_MODE_12: 12-hour format. + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_hour_mode_set(ertc_hour_mode_set_type mode) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + /* enter init mode */ + if(ertc_init_mode_enter() != SUCCESS) + { + return ERROR; + } + + /* write register */ + ERTC->ctrl_bit.hm = mode; + + /* exit init mode */ + ertc_init_mode_exit(); + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief set date. + * @param year: year (0~99). + * @param month: month (1~12). + * @param date: date (1~31). + * @param week: week (1~7). + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_date_set(uint8_t year, uint8_t month, uint8_t date, uint8_t week) +{ + ertc_reg_date_type reg; + + reg.date = 0; + + reg.date_bit.y = ertc_num_to_bcd(year); + reg.date_bit.m = ertc_num_to_bcd(month); + reg.date_bit.d = ertc_num_to_bcd(date); + reg.date_bit.wk = week; + + /* disable write protection */ + ertc_write_protect_disable(); + + /* enter init mode */ + if(ertc_init_mode_enter() != SUCCESS) + { + return ERROR; + } + + /* set the ertc_date register */ + ERTC->date = reg.date; + + /* exit init mode */ + ertc_init_mode_exit(); + + if(ERTC->ctrl_bit.dren == 0) + { + ertc_wait_update(); + } + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief set time. + * @param hour: hour (0~23). + * @param min: minute (0~59). + * @param sec: second (0~59). + * @param ampm: hour mode. + * this parameter can be one of the following values: + * - ERTC_24H: 24-hour format. + * - ERTC_AM: 12-hour format, ante meridiem. + * - ERTC_PM: 12-hour format, post meridiem. + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_time_set(uint8_t hour, uint8_t min, uint8_t sec, ertc_am_pm_type ampm) +{ + ertc_reg_time_type reg; + + reg.time = 0; + + reg.time_bit.h = ertc_num_to_bcd(hour); + reg.time_bit.m = ertc_num_to_bcd(min); + reg.time_bit.s = ertc_num_to_bcd(sec); + reg.time_bit.ampm = ampm; + + /* disable write protection */ + ertc_write_protect_disable(); + + /* enter init mode */ + if(ertc_init_mode_enter() != SUCCESS) + { + return ERROR; + } + + ERTC->time = reg.time; + + /* exit init mode */ + ertc_init_mode_exit(); + + if(ERTC->ctrl_bit.dren == 0) + { + ertc_wait_update(); + } + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief get calendar + * @param time: ertc time. + * @retval none. + */ +void ertc_calendar_get(ertc_time_type* time) +{ + ertc_reg_time_type reg_tm; + ertc_reg_date_type reg_dt; + + reg_tm.time = ERTC->time; + reg_dt.date = ERTC->date; + + time->hour = ertc_bcd_to_num(reg_tm.time_bit.h); + time->min = ertc_bcd_to_num(reg_tm.time_bit.m); + time->sec = ertc_bcd_to_num(reg_tm.time_bit.s); + time->ampm = (ertc_am_pm_type)reg_tm.time_bit.ampm; + + time->year = ertc_bcd_to_num(reg_dt.date_bit.y); + time->month = ertc_bcd_to_num(reg_dt.date_bit.m); + time->day = ertc_bcd_to_num(reg_dt.date_bit.d); + time->week = reg_dt.date_bit.wk; +} + +/** + * @brief get current sub second. + * @param none. + * @retval sub second. + */ +uint32_t ertc_sub_second_get(void) +{ + uint32_t reg = 0; + + reg = ERTC->sbs; + + (void) (ERTC->date); + + return (reg); +} + +/** + * @brief set which bits are irrelevant to the alarm match. + * @param alarm_x: select the alarm. + * this parameter can be one of the following values: + * - ERTC_ALA: alarm a. + * @param mask: select which bits are irrelevant to the alarm match. + * this parameter can be one of the following values: + * - ERTC_ALARM_MASK_NONE: match all. + * - ERTC_ALARM_MASK_SEC: don't match seconds. + * - ERTC_ALARM_MASK_MIN: don't match minute. + * - ERTC_ALARM_MASK_HOUR: don't match hour. + * - ERTC_ALARM_MASK_DATE_WEEK: don't match date or week. + * - ERTC_ALARM_MASK_ALL: don't match all. + * @param alarm: alarm para. + * @retval none. + */ +void ertc_alarm_mask_set(ertc_alarm_type alarm_x, uint32_t mask) +{ + uint32_t reg; + + /* disable write protection */ + ertc_write_protect_disable(); + + if(alarm_x == ERTC_ALA) + { + reg = ERTC->ala; + + reg &= ~ERTC_ALARM_MASK_ALL; + reg |= mask; + + ERTC->ala= reg; + } + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief alarm week or date mode select. + * @param alarm_x: select the alarm. + * this parameter can be one of the following values: + * - ERTC_ALA: alarm a. + * @param wk: week or date mode select. + * this parameter can be one of the following values: + * - ERTC_SLECT_DATE: slect date mode. + * - ERTC_SLECT_WEEK: slect week mode. + * @retval none. + */ +void ertc_alarm_week_date_select(ertc_alarm_type alarm_x, ertc_week_date_select_type wk) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + if(alarm_x == ERTC_ALA) + { + ERTC->ala_bit.wksel = wk; + } + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set alarm. + * @param alarm_x: select the alarm. + * this parameter can be one of the following values: + * - ERTC_ALA: alarm a. + * @param week_day: week or date. + * - week: 1~7. + * - date: 1~31. + * @param hour: hour (0~23). + * @param min: minute (0~59). + * @param sec: second (0~59). + * @param ampm: hour mode. + * this parameter can be one of the following values: + * - ERTC_24H: 24-hour format. + * - ERTC_AM: 12-hour format, ante meridiem. + * - ERTC_PM: 12-hour format, post meridiem. + * @param alarm: alarm para. + * @retval none. + */ +void ertc_alarm_set(ertc_alarm_type alarm_x, uint8_t week_date, uint8_t hour, uint8_t min, uint8_t sec, ertc_am_pm_type ampm) +{ + ertc_reg_alarm_type reg; + + if(alarm_x == ERTC_ALA) + { + reg.ala = ERTC->ala; + } + + reg.ala_bit.d = ertc_num_to_bcd(week_date); + reg.ala_bit.h = ertc_num_to_bcd(hour); + reg.ala_bit.m = ertc_num_to_bcd(min); + reg.ala_bit.s = ertc_num_to_bcd(sec); + reg.ala_bit.ampm = ampm; + + /* disable write protection */ + ertc_write_protect_disable(); + + if(alarm_x == ERTC_ALA) + { + ERTC->ala= reg.ala; + } + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set alarm sub second. + * @param alarm_x: select the alarm. + * this parameter can be one of the following values: + * - ERTC_ALA: alarm a. + * @param value: sub second value. + * @param mask: sub second mask. + * this parameter can be one of the following values: + * - ERTC_ALARM_SBS_MASK_ALL: do not match the sub-second. + * - ERTC_ALARM_SBS_MASK_14_1: only compare bit [0]. + * - ERTC_ALARM_SBS_MASK_14_2: only compare bit [1:0]. + * - ERTC_ALARM_SBS_MASK_14_3: only compare bit [2:0]. + * - ERTC_ALARM_SBS_MASK_14_4: only compare bit [3:0]. + * - ERTC_ALARM_SBS_MASK_14_5: only compare bit [4:0]. + * - ERTC_ALARM_SBS_MASK_14_6: only compare bit [5:0]. + * - ERTC_ALARM_SBS_MASK_14_7: only compare bit [6:0]. + * - ERTC_ALARM_SBS_MASK_14_8: only compare bit [7:0]. + * - ERTC_ALARM_SBS_MASK_14_9: only compare bit [8:0]. + * - ERTC_ALARM_SBS_MASK_14_10: only compare bit [9:0]. + * - ERTC_ALARM_SBS_MASK_14_11: only compare bit [10:0]. + * - ERTC_ALARM_SBS_MASK_14_12: only compare bit [11:0]. + * - ERTC_ALARM_SBS_MASK_14_13: only compare bit [12:0]. + * - ERTC_ALARM_SBS_MASK_14: only compare bit [13:0]. + * - ERTC_ALARM_SBS_MASK_NONE: compare bit [14:0]. + * @retval none. + */ +void ertc_alarm_sub_second_set(ertc_alarm_type alarm_x, uint32_t value, ertc_alarm_sbs_mask_type mask) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + if(alarm_x == ERTC_ALA) + { + ERTC->alasbs_bit.sbsmsk = mask; + ERTC->alasbs_bit.sbs = value; + } + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief enable or disable alarm clock. + * @param alarm_x: select the alarm. + * this parameter can be one of the following values: + * - ERTC_ALA: alarm a. + * @param new_state (TRUE or FALSE). + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_alarm_enable(ertc_alarm_type alarm_x, confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + if(alarm_x == ERTC_ALA) + { + ERTC->ctrl_bit.alaen = new_state; + + if(new_state == FALSE) + { + if(ertc_wait_flag(ERTC_ALAWF_FLAG, RESET) != SUCCESS) + { + return ERROR; + } + } + } + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief get alarm value. + * @param alarm_x: select the alarm. + * this parameter can be one of the following values: + * - ERTC_ALA: alarm a. + * @param alarm: alarm para. + * @retval none. + */ +void ertc_alarm_get(ertc_alarm_type alarm_x, ertc_alarm_value_type* alarm) +{ + ertc_reg_alarm_type reg; + + reg.ala = 0; + + if(alarm_x == ERTC_ALA) + { + reg.ala = ERTC->ala; + } + + alarm->day = ertc_bcd_to_num(reg.ala_bit.d); + alarm->week = ertc_bcd_to_num(reg.ala_bit.d); + alarm->hour = ertc_bcd_to_num(reg.ala_bit.h); + alarm->min = ertc_bcd_to_num(reg.ala_bit.m); + alarm->sec = ertc_bcd_to_num(reg.ala_bit.s); + alarm->ampm = (ertc_am_pm_type)reg.ala_bit.ampm; + alarm->week_date_sel = reg.ala_bit.wksel; + alarm->mask = reg.ala & ERTC_ALARM_MASK_ALL; +} + +/** + * @brief get alarm sub second. + * @param alarm_x: select the alarm. + * this parameter can be one of the following values: + * - ERTC_ALA: alarm a. + * @retval sub second. + */ +uint32_t ertc_alarm_sub_second_get(ertc_alarm_type alarm_x) +{ + return (ERTC->alasbs_bit.sbs); +} + +/** + * @brief set wakeup timer clock. + * @param clock: wakeup timer clock source. + * this parameter can be one of the following values: + * - ERTC_WAT_CLK_ERTCCLK_DIV16: ERTC_CLK / 16. + * - ERTC_WAT_CLK_ERTCCLK_DIV8: ERTC_CLK / 8. + * - ERTC_WAT_CLK_ERTCCLK_DIV4: ERTC_CLK / 4. + * - ERTC_WAT_CLK_ERTCCLK_DIV2: ERTC_CLK / 2. + * - ERTC_WAT_CLK_CK_B_16BITS: CK_B, wakeup counter = ERTC_WAT + * - ERTC_WAT_CLK_CK_B_17BITS: CK_B, wakeup counter = ERTC_WAT + 65535. + * @retval none. + */ +void ertc_wakeup_clock_set(ertc_wakeup_clock_type clock) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl_bit.watclk = clock; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set wakeup counter. + * @param counter: wakeup counter(0~65535). + * @retval none. + */ +void ertc_wakeup_counter_set(uint32_t counter) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->wat_bit.val = counter; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief get wakeup counter. + * @param none. + * @retval wakeup counter. + */ +uint16_t ertc_wakeup_counter_get(void) +{ + return ERTC->wat_bit.val; +} + +/** + * @brief enable or disable wakeup timer. + * @param new_state (TRUE or FALSE). + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_wakeup_enable(confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl_bit.waten = new_state; + + if(new_state == FALSE) + { + if(ertc_wait_flag(ERTC_WATWF_FLAG, RESET) != SUCCESS) + { + return ERROR; + } + } + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief config the smooth calibration. + * @param period: calibration period. + * this parameter can be one of the following values: + * - ERTC_SMOOTH_CAL_PERIOD_32: 32 second calibration period. + * - ERTC_SMOOTH_CAL_PERIOD_16: 16 second calibration period. + * - ERTC_SMOOTH_CAL_PERIOD_8: 8 second calibration period. + * @param clk_add: add clock. + * this parameter can be one of the following values: + * - ERTC_SMOOTH_CAL_CLK_ADD_0: do not increase clock. + * - ERTC_SMOOTH_CAL_CLK_ADD_512: add 512 clocks. + * @param clk_dec: decrease clock(0~511). + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_smooth_calibration_config(ertc_smooth_cal_period_type period, ertc_smooth_cal_clk_add_type clk_add, uint32_t clk_dec) +{ + ertc_reg_scal_type reg; + + /* disable write protection */ + ertc_write_protect_disable(); + + if(ertc_wait_flag(ERTC_CALUPDF_FLAG, SET) != SUCCESS) + { + return ERROR; + } + + reg.scal = 0; + + switch (period) + { + case ERTC_SMOOTH_CAL_PERIOD_32: + break; + case ERTC_SMOOTH_CAL_PERIOD_16: + reg.scal_bit.cal16 = 1; + break; + case ERTC_SMOOTH_CAL_PERIOD_8: + reg.scal_bit.cal8 = 1; + break; + default: + break; + } + + reg.scal_bit.add = clk_add; + reg.scal_bit.dec = clk_dec; + + ERTC->scal = reg.scal; + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief calibration output source select. + * @param output: output source. + * this parameter can be one of the following values: + * - ERTC_CAL_OUTPUT_512HZ: output 512 hz. + * - ERTC_CAL_OUTPUT_1HZ: output 1 hz. + * @retval none. + */ +void ertc_cal_output_select(ertc_cal_output_select_type output) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl_bit.calosel = output; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief enable or disable calibration output. + * @param new_state (TRUE or FALSE). + * @retval none. + */ +void ertc_cal_output_enable(confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl_bit.caloen = new_state; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief adjust the time. + * @param add1s: second operation. + * this parameter can be one of the following values: + * - ERTC_TIME_ADD_NONE: none operation. + * - ERTC_TIME_ADD_1S: add 1 second. + * @param decsbs: decrease sub second(0~0x7FFF). + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_time_adjust(ertc_time_adjust_type add1s, uint32_t decsbs) +{ + ertc_reg_tadj_type reg; + + reg.tadj = 0; + + /* disable write protection */ + ertc_write_protect_disable(); + + if(ertc_wait_flag(ERTC_TADJF_FLAG, SET) != SUCCESS) + { + return ERROR; + } + + /* check if the reference clock detection is disabled */ + if(ERTC->ctrl_bit.rcden == 0) + { + reg.tadj_bit.add1s = add1s; + reg.tadj_bit.decsbs = decsbs; + + ERTC->tadj = reg.tadj; + + if(ertc_wait_update() == ERROR) + { + return ERROR; + } + } + else + { + return ERROR; + } + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief config the daylight saving time. + * @param operation: time adjust. + * this parameter can be one of the following values: + * - ERTC_DST_ADD_1H: add 1 hour. + * - ERTC_DST_DEC_1H: dec 1 hour. + * @param save: operation save. + * this parameter can be one of the following values: + * - ERTC_DST_SAVE_0: set the bpr register value to 0. + * - ERTC_DST_SAVE_1: set the bpr register value to 1. + * @retval none. + */ +void ertc_daylight_set(ertc_dst_operation_type operation, ertc_dst_save_type save) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + if(operation == ERTC_DST_ADD_1H) + { + ERTC->ctrl_bit.add1h = 1; + } + else + { + ERTC->ctrl_bit.dec1h = 1; + } + + ERTC->ctrl_bit.bpr = save; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief get the bpr value. + * @param none. + * @retval bpr value. + */ +uint8_t ertc_daylight_bpr_get(void) +{ + return ERTC->ctrl_bit.bpr; +} + +/** + * @brief enable or disable refer clock detect. + * @param new_state (TRUE or FALSE). + * @retval error_status (ERROR or SUCCESS). + */ +error_status ertc_refer_clock_detect_enable(confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + /* enter init mode */ + if(ertc_init_mode_enter() != SUCCESS) + { + return ERROR; + } + + /* write register */ + ERTC->ctrl_bit.rcden = new_state; + + /* exit init mode */ + ertc_init_mode_exit(); + + /* enable write protection */ + ertc_write_protect_enable(); + + return SUCCESS; +} + +/** + * @brief enable or disable direct read mode. + * @param new_state (TRUE or FALSE). + * @retval none. + */ +void ertc_direct_read_enable(confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl_bit.dren = new_state; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set the output mode. + * @param source: output source. + * this parameter can be one of the following values: + * - ERTC_OUTPUT_DISABLE: diable output. + * - ERTC_OUTPUT_ALARM_A: output alarm a event. + * - ERTC_OUTPUT_WAKEUP: output wakeup event. + * @param polarity: output polarity. + * this parameter can be one of the following values: + * - ERTC_OUTPUT_POLARITY_HIGH: when the event occurs, the output is high. + * - ERTC_OUTPUT_POLARITY_LOW: when the event occurs, the output is low. + * @param type: output type. + * this parameter can be one of the following values: + * - ERTC_OUTPUT_TYPE_OPEN_DRAIN: open drain output. + * - ERTC_OUTPUT_TYPE_PUSH_PULL: push pull output. + * @retval none. + */ +void ertc_output_set(ertc_output_source_type source, ertc_output_polarity_type polarity, ertc_output_type type) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl_bit.outp = polarity; + + ERTC->tamp_bit.outtype = type; + + ERTC->ctrl_bit.outsel = source; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set the timestamp valid edge. + * @param edge: calibration period. + * this parameter can be one of the following values: + * - ERTC_TIMESTAMP_EDGE_RISING : rising edge trigger. + * - ERTC_TIMESTAMP_EDGE_FALLING: falling edge trigger. + * @retval none. + */ +void ertc_timestamp_valid_edge_set(ertc_timestamp_valid_edge_type edge) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl_bit.tsedg = edge; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief enable or disable timestamp. + * @param new_state (TRUE or FALSE). + * @retval none. + */ +void ertc_timestamp_enable(confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->ctrl_bit.tsen = new_state; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief get the timestamp. + * @param time: time. + * @param date: date. + * @retval none. + */ +void ertc_timestamp_get(ertc_time_type* time) +{ + ertc_reg_tstm_type tmtime; + ertc_reg_tsdt_type tmdate; + + tmtime.tstm = ERTC->tstm; + tmdate.tsdt = ERTC->tsdt; + + time->year = 0; + time->month = ertc_bcd_to_num(tmdate.tsdt_bit.m); + time->day = ertc_bcd_to_num(tmdate.tsdt_bit.d); + time->week = ertc_bcd_to_num(tmdate.tsdt_bit.wk); + time->hour = ertc_bcd_to_num(tmtime.tstm_bit.h); + time->min = ertc_bcd_to_num(tmtime.tstm_bit.m); + time->sec = ertc_bcd_to_num(tmtime.tstm_bit.s); + time->ampm = (ertc_am_pm_type)tmtime.tstm_bit.ampm; +} + +/** + * @brief get the timestamp sub second. + * @param none. + * @retval timestamp sub second. + */ +uint32_t ertc_timestamp_sub_second_get(void) +{ + return ERTC->tssbs_bit.sbs; +} + +/** + * @brief enable or disable tamper pin pull up. + * @param new_state (TRUE or FALSE). + * @retval none. + */ +void ertc_tamper_pull_up_enable(confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->tamp_bit.tppu = !new_state; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set the tamper pin pre-charge time. + * @param precharge: tamper detection pre-charge time + * this parameter can be one of the following values: + * - ERTC_TAMPER_PR_1_ERTCCLK: pre-charge time is 1 ERTC_CLK. + * - ERTC_TAMPER_PR_2_ERTCCLK: pre-charge time is 2 ERTC_CLK. + * - ERTC_TAMPER_PR_4_ERTCCLK: pre-charge time is 4 ERTC_CLK. + * - ERTC_TAMPER_PR_8_ERTCCLK: pre-charge time is 8 ERTC_CLK. + * @retval none. + */ +void ertc_tamper_precharge_set(ertc_tamper_precharge_type precharge) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->tamp_bit.tppr = precharge; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set the tamper filter time. + * @param filter: tamper filter. + * this parameter can be one of the following values: + * - ERTC_TAMPER_FILTER_DISABLE: disable filter function. + * - ERTC_TAMPER_FILTER_2: 2 consecutive samples arw valid, effective tamper event. + * - ERTC_TAMPER_FILTER_4: 4 consecutive samples arw valid, effective tamper event. + * - ERTC_TAMPER_FILTER_8: 8 consecutive samples arw valid, effective tamper event. + * @retval none. + */ +void ertc_tamper_filter_set(ertc_tamper_filter_type filter) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->tamp_bit.tpflt = filter; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set the tamper detection frequency. + * @param freq: tamper detection frequency. + * this parameter can be one of the following values: + * - ERTC_TAMPER_FREQ_DIV_32768: ERTC_CLK / 32768. + * - ERTC_TAMPER_FREQ_DIV_16384: ERTC_CLK / 16384. + * - ERTC_TAMPER_FREQ_DIV_8192: ERTC_CLK / 8192. + * - ERTC_TAMPER_FREQ_DIV_4096: ERTC_CLK / 4096. + * - ERTC_TAMPER_FREQ_DIV_2048: ERTC_CLK / 2048. + * - ERTC_TAMPER_FREQ_DIV_1024: ERTC_CLK / 1024. + * - ERTC_TAMPER_FREQ_DIV_512: ERTC_CLK / 512. + * - ERTC_TAMPER_FREQ_DIV_256: ERTC_CLK / 256. + * @retval none. + */ +void ertc_tamper_detect_freq_set(ertc_tamper_detect_freq_type freq) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->tamp_bit.tpfreq = freq; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief set the tamper trigger. + * @param tamper_x: select the tamper. + * this parameter can be one of the following values: + * - ERTC_TAMPER_1: tamper 1. + * @param trigger: tamper valid edge. + * this parameter can be one of the following values: + * - ERTC_TAMPER_EDGE_RISING: rising gedge. + * - ERTC_TAMPER_EDGE_FALLING: falling gedge. + * - ERTC_TAMPER_EDGE_LOW: low level. + * - ERTC_TAMPER_EDGE_HIGH: high level. + * @param alarm: alarm para. + * @retval none. + */ +void ertc_tamper_valid_edge_set(ertc_tamper_select_type tamper_x, ertc_tamper_valid_edge_type trigger) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + if(tamper_x == ERTC_TAMPER_1) + { + ERTC->tamp_bit.tp1edg = trigger; + } + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief enable or disable trigger timestamp when tamper event occurs. + * @param new_state (TRUE or FALSE). + * @retval none. + */ +void ertc_tamper_timestamp_enable(confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + ERTC->tamp_bit.tptsen = new_state; + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief enable or disable tamper. + * @param tamper_x: select the tamper. + * this parameter can be one of the following values: + * - ERTC_TAMPER_1: tamper 1. + * @param new_state (TRUE or FALSE). + * @retval none. + */ +void ertc_tamper_enable(ertc_tamper_select_type tamper_x, confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + if(tamper_x == ERTC_TAMPER_1) + { + ERTC->tamp_bit.tp1en = new_state; + } + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief enable or disable interrupt. + * @param source: interrupts sources + * this parameter can be any combination of the following values: + * - ERTC_TP_INT: tamper interrupt. + * - ERTC_ALA_INT: alarm a interrupt. + * - ERTC_WAT_INT: wakeup timer interrupt. + * - ERTC_TS_INT: timestamp interrupt. + * @param new_state (TRUE or FALSE). + * @retval none. + */ +void ertc_interrupt_enable(uint32_t source, confirm_state new_state) +{ + /* disable write protection */ + ertc_write_protect_disable(); + + if(source & ERTC_TP_INT) + { + if(new_state != FALSE) + { + ERTC->tamp |= ERTC_TP_INT; + } + else + { + ERTC->tamp &= ~ERTC_TP_INT; + } + + source &= ~ERTC_TP_INT; + } + + if(new_state != FALSE) + { + ERTC->ctrl |= source; + } + else + { + ERTC->ctrl &= ~source; + } + + /* enable write protection */ + ertc_write_protect_enable(); +} + +/** + * @brief get interrupt status + * @param source + * this parameter can be one of the following values: + * - ERTC_TP_INT: tamper interrupt. + * - ERTC_ALA_INT: alarm a interrupt. + * - ERTC_WAT_INT: wakeup timer interrupt. + * - ERTC_TS_INT: timestamp interrupt. + * @retval flag_status (SET or RESET) + */ +flag_status ertc_interrupt_get(uint32_t source) +{ + if(source & ERTC_TP_INT) + { + if((ERTC->tamp & ERTC_TP_INT) != RESET) + { + return SET; + } + else + { + return RESET; + } + } + + if((ERTC->ctrl & source) != RESET) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief get flag status. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - ERTC_ALAWF_FLAG: alarm a register allows write flag. + * - ERTC_WATWF_FLAG: wakeup timer register allows write flag. + * - ERTC_TADJF_FLAG: time adjustment flag. + * - ERTC_INITF_FLAG: calendar initialization flag. + * - ERTC_UPDF_FLAG: calendar update flag. + * - ERTC_IMF_FLAG: enter initialization mode flag. + * - ERTC_ALAF_FLAG: alarm clock a flag. + * - ERTC_WATF_FLAG: wakeup timer flag. + * - ERTC_TSF_FLAG: timestamp flag. + * - ERTC_TSOF_FLAG: timestamp overflow flag. + * - ERTC_TP1F_FLAG: tamper detection 1 flag. + * - ERTC_CALUPDF_FLAG: calibration value update completed flag. + * @retval the new state of flag (SET or RESET). + */ +flag_status ertc_flag_get(uint32_t flag) +{ + if((ERTC->sts & flag) != (uint32_t)RESET) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief get interrupt flag status. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - ERTC_ALAF_FLAG: alarm clock a flag. + * - ERTC_WATF_FLAG: wakeup timer flag. + * - ERTC_TSF_FLAG: timestamp flag. + * - ERTC_TP1F_FLAG: tamper detection 1 flag. + * @retval the new state of flag (SET or RESET). + */ +flag_status ertc_interrupt_flag_get(uint32_t flag) +{ + __IO uint32_t iten = 0; + + switch(flag) + { + case ERTC_ALAF_FLAG: + iten = ERTC->ctrl_bit.alaien; + break; + case ERTC_WATF_FLAG: + iten = ERTC->ctrl_bit.watien; + break; + case ERTC_TSF_FLAG: + iten = ERTC->ctrl_bit.tsien; + break; + case ERTC_TP1F_FLAG: + iten = ERTC->tamp_bit.tpien; + break; + + default: + break; + } + + if(((ERTC->sts & flag) != (uint32_t)RESET) && (iten)) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief clear flag status + * @param flag: specifies the flag to clear. + * this parameter can be any combination of the following values: + * - ERTC_ALAWF_FLAG: alarm a register allows write flag. + * - ERTC_WATWF_FLAG: wakeup timer register allows write flag. + * - ERTC_TADJF_FLAG: time adjustment flag. + * - ERTC_INITF_FLAG: calendar initialization flag. + * - ERTC_UPDF_FLAG: calendar update flag. + * - ERTC_IMF_FLAG: enter initialization mode flag. + * - ERTC_ALAF_FLAG: alarm clock a flag. + * - ERTC_WATF_FLAG: wakeup timer flag. + * - ERTC_TSF_FLAG: timestamp flag. + * - ERTC_TSOF_FLAG: timestamp overflow flag. + * - ERTC_TP1F_FLAG: tamper detection 1 flag. + * - ERTC_CALUPDF_FLAG: calibration value update completed flag. + * @retval none + */ +void ertc_flag_clear(uint32_t flag) +{ + ERTC->sts = ~(flag | 0x00000080) | (ERTC->sts_bit.imen << 7); +} + +/** + * @brief write data to the bpr register. + * @param dt: data register + * this parameter can be one of the following values: + * - ERTC_DT1 + * - ERTC_DT2 + * - ERTC_DT3 + * - ERTC_DT4 + * - ERTC_DT5 + * @param data: data to be write. + * @retval none. + */ +void ertc_bpr_data_write(ertc_dt_type dt, uint32_t data) +{ + __IO uint32_t reg = 0; + + reg = ERTC_BASE + 0x50 + (dt * 4); + + *(__IO uint32_t *)reg = data; +} + +/** + * @brief read data from bpr register. + * @param dt: data register + * this parameter can be one of the following values: + * - ERTC_DT1 + * - ERTC_DT2 + * - ERTC_DT3 + * - ERTC_DT4 + * - ERTC_DT5 + * @retval data value. + */ +uint32_t ertc_bpr_data_read(ertc_dt_type dt) +{ + __IO uint32_t reg = 0; + + reg = ERTC_BASE + 0x50 + (dt * 4); + + return (*(__IO uint32_t *)reg); +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_exint.c b/libraries/drivers/src/at32f425_exint.c new file mode 100644 index 0000000..c5f013d --- /dev/null +++ b/libraries/drivers/src/at32f425_exint.c @@ -0,0 +1,254 @@ +/** + ************************************************************************** + * @file at32f425_exint.c + * @brief contains all the functions for the exint firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup EXINT + * @brief EXINT driver modules + * @{ + */ + +#ifdef EXINT_MODULE_ENABLED + +/** @defgroup EXINT_private_functions + * @{ + */ + +/** + * @brief exint reset + * @param none + * @retval none + */ +void exint_reset(void) +{ + EXINT->inten = 0x00000000; + EXINT->polcfg1 = 0x00000000; + EXINT->polcfg2 = 0x00000000; + EXINT->evten = 0x00000000; + EXINT->intsts = 0x003FFFFF; +} + +/** + * @brief exint default para init + * @param exint_struct + * - to the structure of exint_init_type + * @retval none + */ +void exint_default_para_init(exint_init_type *exint_struct) +{ + exint_struct->line_enable = FALSE; + exint_struct->line_select = EXINT_LINE_NONE; + exint_struct->line_polarity = EXINT_TRIGGER_FALLING_EDGE; + exint_struct->line_mode = EXINT_LINE_EVENT; +} + +/** + * @brief exint init + * @param exint_struct + * - to the structure of exint_init_type + * @retval none + */ +void exint_init(exint_init_type *exint_struct) +{ + uint32_t line_index = 0; + line_index = exint_struct->line_select; + + EXINT->inten &= ~line_index; + EXINT->evten &= ~line_index; + + if(exint_struct->line_enable != FALSE) + { + if(exint_struct->line_mode == EXINT_LINE_INTERRUPUT) + { + EXINT->inten |= line_index; + } + else + { + EXINT->evten |= line_index; + } + + EXINT->polcfg1 &= ~line_index; + EXINT->polcfg2 &= ~line_index; + if(exint_struct->line_polarity == EXINT_TRIGGER_RISING_EDGE) + { + EXINT->polcfg1 |= line_index; + } + else if(exint_struct->line_polarity == EXINT_TRIGGER_FALLING_EDGE) + { + EXINT->polcfg2 |= line_index; + } + else + { + EXINT->polcfg1 |= line_index; + EXINT->polcfg2 |= line_index; + } + } +} + +/** + * @brief clear exint flag + * @param exint_line + * this parameter can be any combination of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_20 + * @retval none + */ +void exint_flag_clear(uint32_t exint_line) +{ + EXINT->intsts = exint_line; +} + +/** + * @brief get exint flag + * @param exint_line + * this parameter can be one of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_20 + * @retval state of exint flag + */ +flag_status exint_flag_get(uint32_t exint_line) +{ + flag_status status = RESET; + uint32_t exint_flag =0; + exint_flag = EXINT->intsts & exint_line; + if((exint_flag != (uint16_t)RESET)) + { + status = SET; + } + else + { + status = RESET; + } + return status; +} + +/** + * @brief get exint interrupt flag + * @param exint_line + * this parameter can be one of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_20 + * @retval state of exint flag + */ +flag_status exint_interrupt_flag_get(uint32_t exint_line) +{ + flag_status status = RESET; + uint32_t exint_flag =0; + exint_flag = EXINT->intsts & exint_line; + exint_flag = exint_flag & EXINT->inten; + + if((exint_flag != (uint16_t)RESET)) + { + status = SET; + } + else + { + status = RESET; + } + return status; +} + +/** + * @brief generate exint software interrupt event + * @param exint_line + * this parameter can be one of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_20 + * @retval none + */ +void exint_software_interrupt_event_generate(uint32_t exint_line) +{ + EXINT->swtrg |= exint_line; +} + +/** + * @brief enable or disable exint interrupt + * @param exint_line + * this parameter can be any combination of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_20 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void exint_interrupt_enable(uint32_t exint_line, confirm_state new_state) +{ + if(new_state == TRUE) + { + EXINT->inten |= exint_line; + } + else + { + EXINT->inten &= ~exint_line; + } +} + +/** + * @brief enable or disable exint event + * this parameter can be any combination of the following values: + * - EXINT_LINE_0 + * - EXINT_LINE_1 + * ... + * - EXINT_LINE_20 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void exint_event_enable(uint32_t exint_line, confirm_state new_state) +{ + if(new_state == TRUE) + { + EXINT->evten |= exint_line; + } + else + { + EXINT->evten &= ~exint_line; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_flash.c b/libraries/drivers/src/at32f425_flash.c new file mode 100644 index 0000000..739999a --- /dev/null +++ b/libraries/drivers/src/at32f425_flash.c @@ -0,0 +1,830 @@ +/** + ************************************************************************** + * @file at32f425_flash.c + * @brief contains all the functions for the flash firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup FLASH + * @brief FLASH driver modules + * @{ + */ + +#ifdef FLASH_MODULE_ENABLED + +/** @defgroup FLASH_private_functions + * @{ + */ + +/** + * @brief check whether the specified flash flag is set or not. + * @param flash_flag: specifies the flash flag to check. + * this parameter can be one of flash flag status: + * - FLASH_OBF_FLAG + * - FLASH_ODF_FLAG + * - FLASH_PRGMERR_FLAG + * - FLASH_EPPERR_FLAG + * - FLASH_USDERR_FLAG + * @retval the new state of flash_flag (SET or RESET). + */ +flag_status flash_flag_get(uint32_t flash_flag) +{ + flag_status status = RESET; + uint32_t flag_position; + flag_position = flash_flag & 0x70000000; + flash_flag &= 0x8FFFFFFF; + switch(flag_position) + { + case 0x00000000: + if(FLASH->sts & flash_flag) + status = SET; + break; + case 0x40000000: + if(FLASH->usd & flash_flag) + status = SET; + break; + default: + break; + } + /* return the new state of flash_flag (SET or RESET) */ + return status; +} + +/** + * @brief clear the flash flag. + * @param flash_flag: specifies the flash flags to clear. + * this parameter can be any combination of the following values: + * - FLASH_ODF_FLAG + * - FLASH_PRGMERR_FLAG + * - FLASH_EPPERR_FLAG + * @retval none + */ +void flash_flag_clear(uint32_t flash_flag) +{ + FLASH->sts = flash_flag; +} + +/** + * @brief return the flash operation status. + * @param none + * @retval status: the returned value can be: FLASH_OPERATE_BUSY, + * FLASH_PROGRAM_ERROR, FLASH_EPP_ERROR or FLASH_OPERATE_DONE. + */ +flash_status_type flash_operation_status_get(void) +{ + flash_status_type flash_status = FLASH_OPERATE_DONE; + if(FLASH->sts_bit.obf != RESET) + { + flash_status = FLASH_OPERATE_BUSY; + } + else if(FLASH->sts_bit.prgmerr != RESET) + { + flash_status = FLASH_PROGRAM_ERROR; + } + else if(FLASH->sts_bit.epperr != RESET) + { + flash_status = FLASH_EPP_ERROR; + } + else + { + flash_status = FLASH_OPERATE_DONE; + } + /* return the flash status */ + return flash_status; +} + +/** + * @brief wait for flash operation complete or timeout. + * @param time_out: flash operation timeout + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_operation_wait_for(uint32_t time_out) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* check for the flash status */ + status = flash_operation_status_get(); + + while((status == FLASH_OPERATE_BUSY) && (time_out != 0x00)) + { + status = flash_operation_status_get(); + time_out--; + } + if(time_out == 0x00) + { + status = FLASH_OPERATE_TIMEOUT; + } + /* return the status */ + return status; +} + +/** + * @brief unlock the flash controller. + * @param none + * @retval none + */ +void flash_unlock(void) +{ + FLASH->unlock = FLASH_UNLOCK_KEY1; + FLASH->unlock = FLASH_UNLOCK_KEY2; +} + +/** + * @brief lock the flash controller. + * @param none + * @retval none + */ +void flash_lock(void) +{ + FLASH->ctrl_bit.oplk = TRUE; +} + +/** + * @brief erase a specified flash sector. + * @param sector_address: the sector address to be erased. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_sector_erase(uint32_t sector_address) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + FLASH->ctrl_bit.secers = TRUE; + FLASH->addr = sector_address; + FLASH->ctrl_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the secers bit */ + FLASH->ctrl_bit.secers = FALSE; + + /* return the erase status */ + return status; +} + +/** + * @brief erase flash all internal sectors. + * @param none + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_internal_all_erase(void) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + FLASH->ctrl_bit.bankers = TRUE; + FLASH->ctrl_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the bankers bit */ + FLASH->ctrl_bit.bankers = FALSE; + + /* return the erase status */ + return status; +} + +/** + * @brief erase the flash user system data. + * @note this functions erases all user system data except the fap byte. + * when fap high level enabled, can't use this function. + * @param none + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_user_system_data_erase(void) +{ + flash_status_type status = FLASH_OPERATE_DONE; + uint16_t fap_val = FAP_RELIEVE_KEY; + /* get the flash access protection status */ + if(flash_fap_status_get() != RESET) + { + fap_val = 0x0000; + } + + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + /* erase the user system data */ + FLASH->ctrl_bit.usders = TRUE; + FLASH->ctrl_bit.erstr = TRUE; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the usders bit */ + FLASH->ctrl_bit.usders = FALSE; + + if((status == FLASH_OPERATE_DONE) && (fap_val == FAP_RELIEVE_KEY)) + { + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + + /* restore the last flash access protection value */ + USD->fap = (uint16_t)fap_val; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /*disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + } + + /* return the erase status */ + return status; +} + +/** + * @brief program a word at a specified address. + * @param address: specifies the address to be programmed, word alignment is recommended. + * @param data: specifies the data to be programmed. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_word_program(uint32_t address, uint32_t data) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + FLASH->ctrl_bit.fprgm = TRUE; + *(__IO uint32_t*)address = data; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl_bit.fprgm = FALSE; + + /* return the program status */ + return status; +} + +/** + * @brief program a halfword at a specified address. + * @param address: specifies the address to be programmed, halfword alignment is recommended. + * @param data: specifies the data to be programmed. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_halfword_program(uint32_t address, uint16_t data) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + FLASH->ctrl_bit.fprgm = TRUE; + *(__IO uint16_t*)address = data; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl_bit.fprgm = FALSE; + + /* return the program status */ + return status; +} + +/** + * @brief program a byte at a specified address. + * @param address: specifies the address to be programmed. + * @param data: specifies the data to be programmed. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_byte_program(uint32_t address, uint8_t data) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + FLASH->ctrl_bit.fprgm = TRUE; + *(__IO uint8_t*)address = data; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the fprgm bit */ + FLASH->ctrl_bit.fprgm = FALSE; + + /* return the program status */ + return status; +} + +/** + * @brief program a halfword at a specified user system data address. + * @param address: specifies the address to be programmed. + * @param data: specifies the data to be programmed. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_user_system_data_program(uint32_t address, uint8_t data) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + *(__IO uint16_t*)address = data; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + + /* return the user system data program status */ + return status; +} + +/** + * @brief config erase/program protection for the desired sectors. + * @param sector_bits: + * the pointer of the address of the sectors to be erase/program protected. + * the first 16bits general every bit is used to protect the 4KB bytes. the + * bit 31 is used to protect the extension memory. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_epp_set(uint32_t *sector_bits) +{ + uint16_t epp_data[4] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF}; + flash_status_type status = FLASH_OPERATE_DONE; + sector_bits[0] = (uint32_t)(~sector_bits[0]); + epp_data[0] = (uint16_t)((sector_bits[0] >> 0) & 0xFF); + epp_data[1] = (uint16_t)((sector_bits[0] >> 8) & 0xFF); + epp_data[2] = (uint16_t)((sector_bits[0] >> 16) & 0xFF); + epp_data[3] = (uint16_t)((sector_bits[0] >> 24) & 0xFF); + + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + FLASH->ctrl_bit.usdprgm = TRUE; + USD->epp0 = epp_data[0]; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + if(status == FLASH_OPERATE_DONE) + { + USD->epp1 = epp_data[1]; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + if(status == FLASH_OPERATE_DONE) + { + USD->epp2 = epp_data[2]; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + if(status == FLASH_OPERATE_DONE) + { + USD->epp3 = epp_data[3]; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + + /* return the erase/program protection operation status */ + return status; +} + +/** + * @brief return the flash erase/program protection status. + * @param sector_bits: pointer to get the epps register. + * @retval none + */ +void flash_epp_status_get(uint32_t *sector_bits) +{ + /* return the flash erase/program protection register value */ + sector_bits[0] = (uint32_t)(FLASH->epps); +} + +/** + * @brief enable or disable the flash access protection. + * @note if the user has already programmed the other user system data before calling + * this function, must re-program them since this function erase all user system data. + * @param new_state: new state of the flash access protection. + * this parameter can be: TRUE or FALSE. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_fap_enable(confirm_state new_state) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + FLASH->ctrl_bit.usders = TRUE; + FLASH->ctrl_bit.erstr = TRUE; + /* wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the usders bit */ + FLASH->ctrl_bit.usders = FALSE; + + if(status == FLASH_OPERATE_DONE) + { + if(new_state == FALSE) + { + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + USD->fap = FAP_RELIEVE_KEY; + + /* Wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + } + } + + /* return the flash access protection operation status */ + return status; +} + +/** + * @brief check the flash access protection status. + * @param none + * @retval flash access protection status(SET or RESET) + */ +flag_status flash_fap_status_get(void) +{ + return (flag_status)FLASH->usd_bit.fap; +} + +/** + * @brief enable or disable the flash access protection high level. + * @note if the user has already programmed the other user system data before calling + * this function, must re-program them since this function erase all user system data. + * @note once the fap high level enabled, the swd debugger port will be permanently disable!!! + * @param new_state: new state of the flash access protection high level. + * this parameter can be: TRUE or FALSE. + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_fap_high_level_enable(void) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + FLASH->ctrl_bit.usders = TRUE; + FLASH->ctrl_bit.erstr = TRUE; + /* wait for operation to be completed */ + status = flash_operation_wait_for(ERASE_TIMEOUT); + + /* disable the usders bit */ + FLASH->ctrl_bit.usders = FALSE; + + if(status == FLASH_OPERATE_DONE) + { + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + USD->fap = FAP_HIGH_LEVEL_KEY; + + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + } + + /* return the flash access protection operation status */ + return status; +} + +/** + * @brief check the flash access protection high level status. + * @param none + * @retval flash access protection high level status(SET or RESET) + */ +flag_status flash_fap_high_level_status_get(void) +{ + return (flag_status)FLASH->usd_bit.fap_hl; +} + +/** + * @brief program the flash system setting byte in usd: wdt_ato_en / depslp_rst / stdby_rst / boot1 / depslp_wdt / stdby_wdt. + * @param usd_ssb: the system setting byte + * @note this parameter usd_ssb must contain a combination of all the following 6 types of data + * type 1: wdt_ato_en, select the wdt auto start + * this data can be one of the following values: + * - USD_WDT_ATO_DISABLE: disable wdt auto start + * - USD_WDT_ATO_ENABLE: enable wdt auto start + * type 2: depslp_rst, reset event when entering deepsleep mode. + * this data can be one of the following values: + * - USD_DEPSLP_NO_RST: no reset generated when entering in deepsleep + * - USD_DEPSLP_RST: reset generated when entering in deepsleep + * type 3: stdby_rst, reset event when entering standby mode. + * this data can be one of the following values: + * - USD_STDBY_NO_RST: no reset generated when entering in standby + * - USD_STDBY_RST: reset generated when entering in standby + * type 4: boot1, at startup, when boot0 pin is high level, selected the device boot from bootmem/sram. + * this data can be one of the following values: + * - USD_BOOT1_LOW: when boot0 is high level, boot from bootmem + * - USD_BOOT1_HIGH: when boot0 is high level, boot from sram + * type 5: depslp_wdt, wdt stop count when entering deepsleep mode. + * this data can be one of the following values: + * - USD_DEPSLP_WDT_CONTINUE: wdt continue count when entering in deepsleep + * - USD_DEPSLP_WDT_STOP: wdt stop count when entering in deepsleep + * type 6: stdby_wdt, wdt stop count when entering standby mode. + * this data can be one of the following values: + * - USD_STDBY_WDT_CONTINUE: wdt continue count when entering in standby + * - USD_STDBY_WDT_STOP: wdt stop count when entering in standby + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_ssb_set(uint8_t usd_ssb) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + /* unlock the user system data */ + FLASH->usd_unlock = FLASH_UNLOCK_KEY1; + FLASH->usd_unlock = FLASH_UNLOCK_KEY2; + while(FLASH->ctrl_bit.usdulks==RESET); + + /* enable the user system data programming operation */ + FLASH->ctrl_bit.usdprgm = TRUE; + + USD->ssb = usd_ssb; + /* wait for operation to be completed */ + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + + /* disable the usdprgm bit */ + FLASH->ctrl_bit.usdprgm = FALSE; + + /* return the user system data program status */ + return status; +} + +/** + * @brief return the flash system setting byte status. + * @param none + * @retval values from flash_usd register: wdt_ato_en(bit0), depslp_rst(bit1), + * stdby_rst(bit2), boot1(bit4), depslp_wdt(bit5) and stdby_wdt(bit6). + */ +uint8_t flash_ssb_status_get(void) +{ + /* return the system setting byte status */ + return (uint8_t)(FLASH->usd >> 2); +} + +/** + * @brief enable or disable the specified flash interrupts. + * @param flash_int: specifies the flash interrupt sources to be enabled or disabled. + * this parameter can be any combination of the following values: + * - FLASH_ERR_INT + * - FLASH_ODF_INT + * @param new_state: new state of the specified flash interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void flash_interrupt_enable(uint32_t flash_int, confirm_state new_state) +{ + if(flash_int & FLASH_ERR_INT) + FLASH->ctrl_bit.errie = new_state; + if(flash_int & FLASH_ODF_INT) + FLASH->ctrl_bit.odfie = new_state; +} + +/** + * @brief enable main block security library function. + * @param pwd: slib password + * start_sector: security library start sector + * inst_start_sector: security library i-bus area start sector + * end_sector: security library end sector + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_slib_enable(uint32_t pwd, uint16_t start_sector, uint16_t inst_start_sector, uint16_t end_sector) +{ + uint32_t slib_range; + flash_status_type status = FLASH_OPERATE_DONE; + + /*check range param limits*/ + if((start_sector > inst_start_sector) || ((inst_start_sector > end_sector) && \ + (inst_start_sector != 0x7FF)) || (start_sector > end_sector)) + return FLASH_PROGRAM_ERROR; + + /* unlock slib cfg register */ + FLASH->slib_unlock = SLIB_UNLOCK_KEY; + while(FLASH->slib_misc_sts_bit.slib_ulkf==RESET); + + slib_range = ((uint32_t)(inst_start_sector << 11) & FLASH_SLIB_INST_START_SECTOR) | \ + ((uint32_t)(end_sector << 22) & FLASH_SLIB_END_SECTOR) | \ + (start_sector & FLASH_SLIB_START_SECTOR); + /* configure slib, set pwd and range */ + FLASH->slib_set_pwd = pwd; + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + if(status == FLASH_OPERATE_DONE) + { + FLASH->slib_set_range = slib_range; + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + + return status; +} + +/** + * @brief disable main block slib when slib enabled. + * @param pwd: slib password + * @retval success or error + */ +error_status flash_slib_disable(uint32_t pwd) +{ + flash_status_type status = FLASH_OPERATE_DONE; + /* write password to disable slib */ + FLASH->slib_pwd_clr = pwd; + + status = flash_operation_wait_for(ERASE_TIMEOUT); + if(status == FLASH_OPERATE_DONE) + { + if(FLASH->slib_misc_sts_bit.slib_pwd_ok) + return SUCCESS; + else + return ERROR; + } + return ERROR; +} + +/** + * @brief get the main block slib state. + * @param none + * @retval SET or RESET + */ +flag_status flash_slib_state_get(void) +{ + if(FLASH->slib_sts0_bit.slib_enf) + return SET; + else + return RESET; +} + +/** + * @brief get the main block start sector of slib. + * @param none + * @retval uint16_t + */ +uint16_t flash_slib_start_sector_get(void) +{ + return (uint16_t)FLASH->slib_sts1_bit.slib_ss; +} + +/** + * @brief get the main block inst start sector of slib. + * @param none + * @retval uint16_t + */ +uint16_t flash_slib_inststart_sector_get(void) +{ + return (uint16_t)FLASH->slib_sts1_bit.slib_inst_ss; +} + +/** + * @brief get the main block end sector of slib. + * @param none + * @retval uint16_t + */ +uint16_t flash_slib_end_sector_get(void) +{ + return (uint16_t)FLASH->slib_sts1_bit.slib_es; +} + +/** + * @brief flash crc calibration. + * @param start_addr: crc calibration start sector address + * sector_cnt: crc calibration sector count + * @retval uint32: crc calibration result + */ +uint32_t flash_crc_calibrate(uint32_t start_addr, uint32_t sector_cnt) +{ + FLASH->crc_addr = start_addr; + FLASH->crc_ctrl = sector_cnt | 0x10000; + flash_operation_wait_for(OPERATION_TIMEOUT); + return FLASH->crc_chkr; +} + +/** + * @brief enable boot memory as extension mode. + * @note this function is irreversible, can not disable!!! + * @param none + * @retval none. + */ +void flash_boot_memory_extension_mode_enable(void) +{ + if(FLASH->slib_sts0_bit.btm_ap_enf == RESET) + { + FLASH->slib_unlock = SLIB_UNLOCK_KEY; + while(FLASH->slib_misc_sts_bit.slib_ulkf==RESET); + FLASH->btm_mode_set = 0; + flash_operation_wait_for(OPERATION_TIMEOUT); + } +} + +/** + * @brief enable extension memory security library function. + * @param pwd: slib password + * inst_start_sector: extension memory security library i-bus area start sector, range 0~3 or 0xFF + * @retval status: the returned value can be: FLASH_PROGRAM_ERROR, + * FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT. + */ +flash_status_type flash_extension_memory_slib_enable(uint32_t pwd, uint16_t inst_start_sector) +{ + flash_status_type status = FLASH_OPERATE_DONE; + + /* unlock slib cfg register */ + FLASH->slib_unlock = SLIB_UNLOCK_KEY; + while(FLASH->slib_misc_sts_bit.slib_ulkf==RESET); + + /* configure slib, set pwd and range */ + FLASH->slib_set_pwd = pwd; + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + if(status == FLASH_OPERATE_DONE) + { + FLASH->em_slib_set = (uint32_t)(inst_start_sector << 16) + (uint32_t)0x5AA5; + status = flash_operation_wait_for(PROGRAMMING_TIMEOUT); + } + + return status; +} + +/** + * @brief get the extension memory slib state. + * @param none + * @retval SET or RESET + */ +flag_status flash_extension_memory_slib_state_get(void) +{ + if(FLASH->slib_sts0_bit.em_slib_enf) + return SET; + else + return RESET; +} + +/** + * @brief get the extension memory inst start sector of slib. + * @param none + * @retval uint16_t + */ +uint16_t flash_em_slib_inststart_sector_get(void) +{ + return (uint16_t)FLASH->slib_sts0_bit.em_slib_inst_ss; +} + +/** + * @brief config flash low power mode enable or disable. + * if enabled, when system entry deep sleep mode, flash also entry low power mode. + * @param new_state: new state of the flash low power mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void flash_low_power_mode_enable(confirm_state new_state) +{ + FLASH->ctrl_bit.lpmen = new_state; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_gpio.c b/libraries/drivers/src/at32f425_gpio.c new file mode 100644 index 0000000..7b4da8d --- /dev/null +++ b/libraries/drivers/src/at32f425_gpio.c @@ -0,0 +1,498 @@ +/** + ************************************************************************** + * @file at32f425_gpio.c + * @brief contains all the functions for the gpio firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup GPIO + * @brief GPIO driver modules + * @{ + */ + +#ifdef GPIO_MODULE_ENABLED + +/** @defgroup GPIO_private_functions + * @{ + */ + +/** + * @brief reset the gpio register + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @retval none + */ +void gpio_reset(gpio_type *gpio_x) +{ + if(gpio_x == GPIOA) + { + crm_periph_reset(CRM_GPIOA_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOA_PERIPH_RESET, FALSE); + } + else if(gpio_x == GPIOB) + { + crm_periph_reset(CRM_GPIOB_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOB_PERIPH_RESET, FALSE); + } + else if(gpio_x == GPIOC) + { + crm_periph_reset(CRM_GPIOC_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOC_PERIPH_RESET, FALSE); + } + else if(gpio_x == GPIOD) + { + crm_periph_reset(CRM_GPIOD_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOD_PERIPH_RESET, FALSE); + } + else if(gpio_x == GPIOF) + { + crm_periph_reset(CRM_GPIOF_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_GPIOF_PERIPH_RESET, FALSE); + } +} + +/** + * @brief initialize the gpio peripheral. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param gpio_init_struct: pointer to gpio init structure. + * @retval none + */ +void gpio_init(gpio_type *gpio_x, gpio_init_type *gpio_init_struct) +{ + uint16_t pinx_value, pin_index = 0; + + pinx_value = (uint16_t)gpio_init_struct->gpio_pins; + + while(pinx_value > 0) + { + if(pinx_value & 0x01) + { + gpio_x->cfgr &= (uint32_t)~(0x03 << (pin_index * 2)); + gpio_x->cfgr |= (uint32_t)(gpio_init_struct->gpio_mode << (pin_index * 2)); + + gpio_x->omode &= (uint32_t)~(0x01 << (pin_index)); + gpio_x->omode |= (uint32_t)(gpio_init_struct->gpio_out_type << (pin_index)); + + gpio_x->odrvr &= (uint32_t)~(0x03 << (pin_index * 2)); + gpio_x->odrvr |= (uint32_t)(gpio_init_struct->gpio_drive_strength << (pin_index * 2)); + + gpio_x->pull &= (uint32_t)~(0x03 << (pin_index * 2)); + gpio_x->pull |= (uint32_t)(gpio_init_struct->gpio_pull << (pin_index * 2)); + } + pinx_value >>= 1; + pin_index++; + } +} + +/** + * @brief fill each gpio_init_type member with its default value. + * @param gpio_init_struct : pointer to a gpio_init_type structure which will be initialized. + * @retval none + */ +void gpio_default_para_init(gpio_init_type *gpio_init_struct) +{ + /* reset gpio init structure parameters values */ + gpio_init_struct->gpio_pins = GPIO_PINS_ALL; + gpio_init_struct->gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct->gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct->gpio_pull = GPIO_PULL_NONE; + gpio_init_struct->gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; +} + +/** + * @brief read the specified input port pin. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param pins: gpio pin number + * this parameter can be one of the following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * @retval flag_status (SET or RESET) + */ +flag_status gpio_input_data_bit_read(gpio_type *gpio_x, uint16_t pins) +{ + flag_status status = RESET; + + if(pins != (pins & gpio_x->idt)) + { + status = RESET; + } + else + { + status = SET; + } + + return status; +} + +/** + * @brief read the specified gpio input data port. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @retval gpio input data port value. + */ +uint16_t gpio_input_data_read(gpio_type *gpio_x) +{ + return ((uint16_t)(gpio_x->idt)); +} + +/** + * @brief read the specified output port pin. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param pins: gpio pin number + * this parameter can be one of the following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * @retval flag_status (SET or RESET) + */ +flag_status gpio_output_data_bit_read(gpio_type *gpio_x, uint16_t pins) +{ + flag_status status = RESET; + + if((gpio_x->odt & pins) != RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief read the specified gpio ouput data port. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @retval gpio input data port value. + */ +uint16_t gpio_output_data_read(gpio_type *gpio_x) +{ + return ((uint16_t)(gpio_x->odt)); +} + +/** + * @brief set the selected data port bits. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param pins: gpio pin number + * parameter can be any combination of gpio_pin_x, gpio_pin_x as following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @retval none + */ +void gpio_bits_set(gpio_type *gpio_x, uint16_t pins) +{ + gpio_x->scr = pins; +} + +/** + * @brief clear the selected data port bits. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param pins: gpio pin number + * parameter can be any combination of gpio_pin_x, gpio_pin_x as following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @retval none + */ +void gpio_bits_reset(gpio_type *gpio_x, uint16_t pins) +{ + gpio_x->clr = pins; +} + +/** + * @brief set or clear the selected data port bit. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param pins: gpio pin number + * parameter can be any combination of gpio_pin_x, gpio_pin_x as following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @param bit_state: specifies the value to be written to the selected bit (TRUE or FALSE). + * @retval none + */ +void gpio_bits_write(gpio_type *gpio_x, uint16_t pins, confirm_state bit_state) +{ + if(bit_state != FALSE) + { + gpio_x->scr = pins; + } + else + { + gpio_x->clr = pins; + } +} + +/** + * @brief write data to the specified gpio data port. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param port_value: specifies the value to be written to the port output data register. + * @retval none + */ +void gpio_port_write(gpio_type *gpio_x, uint16_t port_value) +{ + gpio_x->odt = port_value; +} + +/** + * @brief write protect gpio pins configuration registers. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param pins: gpio pin number + * this parameter can be any combination of the following: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @retval none + */ +void gpio_pin_wp_config(gpio_type *gpio_x, uint16_t pins) +{ + uint32_t temp = 0x00010000; + + temp |= pins; + /* set wpen bit */ + gpio_x->wpr = temp; + /* reset wpen bit */ + gpio_x->wpr = pins; + /* set wpen bit */ + gpio_x->wpr = temp; + /* read wpen bit*/ + temp = gpio_x->wpr; + /* read wpen bit*/ + temp = gpio_x->wpr; +} + +/** + * @brief enable or disable gpio pins huge driven. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param pins: gpio pin number + * parameter can be any combination of gpio_pin_x, gpio_pin_x as following values: + * - GPIO_PINS_0 + * - GPIO_PINS_1 + * - GPIO_PINS_2 + * - GPIO_PINS_3 + * - GPIO_PINS_4 + * - GPIO_PINS_5 + * - GPIO_PINS_6 + * - GPIO_PINS_7 + * - GPIO_PINS_8 + * - GPIO_PINS_9 + * - GPIO_PINS_10 + * - GPIO_PINS_11 + * - GPIO_PINS_12 + * - GPIO_PINS_13 + * - GPIO_PINS_14 + * - GPIO_PINS_15 + * - GPIO_PINS_ALL + * @param new_state: new state of the slew rate. + * this parameter can be: true or false. + * @retval none + */ +void gpio_pins_huge_driven_config(gpio_type *gpio_x, uint16_t pins, confirm_state new_state) +{ + if(new_state != FALSE) + { + gpio_x->hdrv |= pins; + } + else + { + gpio_x->hdrv &= ~pins; + } +} + +/** + * @brief configure the pin's muxing function. + * @param gpio_x: to select the gpio peripheral. + * this parameter can be one of the following values: + * GPIOA, GPIOB, GPIOC, GPIOD, GPIOF. + * @param gpio_pin_source: specifies the pin for the muxing function. + * this parameter can be one of the following values: + * - GPIO_PINS_SOURCE0 + * - GPIO_PINS_SOURCE1 + * - GPIO_PINS_SOURCE2 + * - GPIO_PINS_SOURCE3 + * - GPIO_PINS_SOURCE4 + * - GPIO_PINS_SOURCE5 + * - GPIO_PINS_SOURCE6 + * - GPIO_PINS_SOURCE7 + * - GPIO_PINS_SOURCE8 + * - GPIO_PINS_SOURCE9 + * - GPIO_PINS_SOURCE10 + * - GPIO_PINS_SOURCE11 + * - GPIO_PINS_SOURCE12 + * - GPIO_PINS_SOURCE13 + * - GPIO_PINS_SOURCE14 + * - GPIO_PINS_SOURCE15 + * @param gpio_mux: select the pin to used as muxing function. + * this parameter can be one of the following values: + * - GPIO_MUX_0 + * - GPIO_MUX_1 + * - GPIO_MUX_2 + * - GPIO_MUX_3 + * - GPIO_MUX_4 + * - GPIO_MUX_5 + * - GPIO_MUX_6 + * - GPIO_MUX_7 + * @retval none + */ +void gpio_pin_mux_config(gpio_type *gpio_x, gpio_pins_source_type gpio_pin_source, gpio_mux_sel_type gpio_mux) +{ + uint32_t temp = 0x00; + uint32_t temp_2 = 0x00; + + temp = ((uint32_t)(gpio_mux) << ((uint32_t)((uint32_t)gpio_pin_source & (uint32_t)0x07) * 4)); + if(gpio_pin_source >> 0x03) + { + gpio_x->muxh &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)gpio_pin_source & (uint32_t)0x07) * 4)); + temp_2 = gpio_x->muxh | temp; + gpio_x->muxh = temp_2; + } + else + { + gpio_x->muxl &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)gpio_pin_source & (uint32_t)0x07) * 4)); + temp_2 = gpio_x->muxl | temp; + gpio_x->muxl = temp_2; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_i2c.c b/libraries/drivers/src/at32f425_i2c.c new file mode 100644 index 0000000..cae7715 --- /dev/null +++ b/libraries/drivers/src/at32f425_i2c.c @@ -0,0 +1,812 @@ +/** + ************************************************************************** + * @file at32f425_i2c.c + * @brief contains all the functions for the i2c firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup I2C + * @brief I2C driver modules + * @{ + */ + +#ifdef I2C_MODULE_ENABLED + +/** @defgroup I2C_private_functions + * @{ + */ + +/** + * @brief reset the i2c register + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @retval none + */ +void i2c_reset(i2c_type *i2c_x) +{ + if(i2c_x == I2C1) + { + crm_periph_reset(CRM_I2C1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_I2C1_PERIPH_RESET, FALSE); + } + else if(i2c_x == I2C2) + { + crm_periph_reset(CRM_I2C2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_I2C2_PERIPH_RESET, FALSE); + } +} + +/** + * @brief init i2c digit filters and clock control register. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param dfilters: number of digit filters (0x00~0x0F). + * @param clk: i2c clock control register (0x00000000~0xFFFFFFFF). + * @retval none + */ +void i2c_init(i2c_type *i2c_x, uint8_t dfilters, uint32_t clk) +{ + /* disable i2c peripheral */ + i2c_x->ctrl1_bit.i2cen = FALSE; + + /* write clkctrl register*/ + i2c_x->clkctrl = clk; + + /* write digital filter register*/ + i2c_x->ctrl1_bit.dflt = dfilters; +} + +/** + * @brief config i2c own address 1. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param mode: i2c address mode. + * this parameter can be one of the following values: + * - I2C_ADDRESS_MODE_7BIT: 7bit address. + * - I2C_ADDRESS_MODE_10BIT: 10bit address. + * @param address: own address 1, such as 0xB0. + * @retval none + */ +void i2c_own_address1_set(i2c_type *i2c_x, i2c_address_mode_type mode, uint16_t address) +{ + /* config address mode */ + i2c_x->oaddr1_bit.addr1mode = mode; + + /* config address */ + i2c_x->oaddr1_bit.addr1 = address & 0x03FF; + + /* enable address */ + i2c_x->oaddr1_bit.addr1en = TRUE; +} + +/** + * @brief config i2c own address 2 and mask. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param address: own address 1, such as 0xC0. + * @param mask: own address 2 mask. + * this parameter can be one of the following values: + * - I2C_ADDR2_NOMASK: compare bit [7:1]. + * - I2C_ADDR2_MASK01: only compare bit [7:2]. + * - I2C_ADDR2_MASK02: only compare bit [7:3]. + * - I2C_ADDR2_MASK03: only compare bit [7:4]. + * - I2C_ADDR2_MASK04: only compare bit [7:5]. + * - I2C_ADDR2_MASK05: only compare bit [7:6]. + * - I2C_ADDR2_MASK06: only compare bit [7]. + * - I2C_ADDR2_MASK07: response all addresses other than those reserved for i2c. + * @retval none + */ +void i2c_own_address2_set(i2c_type *i2c_x, uint8_t address, i2c_addr2_mask_type mask) +{ + i2c_x->oaddr2_bit.addr2mask = mask; + + i2c_x->oaddr2_bit.addr2 = (address >> 1) & 0x7F; +} + +/** + * @brief enable or disable own address 2. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_own_address2_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->oaddr2_bit.addr2en = new_state; +} + +/** + * @brief enable or disable smbus mode. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param mode: smbus device mode. + * this parameter can be one of the following values: + * - I2C_SMBUS_MODE_DEVICE: smbus device. + * - I2C_SMBUS_MODE_HOST: smbus host. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_smbus_enable(i2c_type *i2c_x, i2c_smbus_mode_type mode, confirm_state new_state) +{ + switch (mode) + { + case I2C_SMBUS_MODE_DEVICE: + i2c_x->ctrl1_bit.devaddren = new_state; + break; + case I2C_SMBUS_MODE_HOST: + i2c_x->ctrl1_bit.haddren = new_state; + break; + default: + break; + } +} + +/** + * @brief enable or disable peripheral. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.i2cen = new_state; +} + +/** + * @brief enable or disable clock stretch. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_clock_stretch_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.stretch = (!new_state); +} + +/** + * @brief enable or disable ack. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none. + */ +void i2c_ack_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl2_bit.nacken = (!new_state); +} + +/** + * @brief enable or disable 10-bit address mode (master transfer). + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_addr10_mode_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl2_bit.addr10 = new_state; +} + +/** + * @brief config the slave address to be transmitted. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param address: slave address. + * @retval none + */ +void i2c_transfer_addr_set(i2c_type *i2c_x, uint16_t address) +{ + i2c_x->ctrl2_bit.saddr = address & 0x03FF; +} + +/** + * @brief get the slave address to be transmitted. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @retval slave address + */ +uint16_t i2c_transfer_addr_get(i2c_type *i2c_x) +{ + return i2c_x->ctrl2_bit.saddr; +} + +/** + * @brief config the master transfer direction. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param i2c_direction: transfer request direction. + * this parameter can be one of the following values: + * - I2C_DIR_TRANSMIT: master request a write transfer. + * - I2C_DIR_RECEIVE: master request a read transfer. + * @retval none + */ +void i2c_transfer_dir_set(i2c_type *i2c_x, i2c_transfer_dir_type i2c_direction) +{ + i2c_x->ctrl2_bit.dir = i2c_direction; +} + +/** + * @brief slave get the i2c transfer direction. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2, I2C3. + * @retval the value of the slave direction + * - I2C_DIR_TRANSMIT: master request a write transfer, slave enters receiver mode. + * - I2C_DIR_RECEIVE: master request a read transfer, slave enters transmitter mode. + */ +i2c_transfer_dir_type i2c_transfer_dir_get(i2c_type *i2c_x) +{ + if (i2c_x->sts_bit.sdir == 0) + { + return I2C_DIR_TRANSMIT; + } + else + { + return I2C_DIR_RECEIVE; + } +} + +/** + * @brief get the i2c slave matched address. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @retval slave matched address. + */ +uint8_t i2c_matched_addr_get(i2c_type *i2c_x) +{ + return (i2c_x->sts_bit.addr << 1); +} + +/** + * @brief enable or disable auto send stop mode. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_auto_stop_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl2_bit.astopen = new_state; +} + +/** + * @brief enable or disable cnt reload mode. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_reload_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl2_bit.rlden = new_state; +} + +/** + * @brief config the transfer cnt . + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param cnt: transfer cnt. + * @retval none + */ +void i2c_cnt_set(i2c_type *i2c_x, uint8_t cnt) +{ + i2c_x->ctrl2_bit.cnt = cnt; +} + +/** + * @brief enable or disable read 10-bit header, this mode + * only used in 10-bit address mode read. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_addr10_header_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl2_bit.readh10 = new_state; +} + +/** + * @brief enable or disable general call mode. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_general_call_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.gcaen = new_state; +} + +/** + * @brief drives the smbus alert pin high or low. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param level + * this parameter can be one of the following values: + * - I2C_SMBUS_ALERT_LOW: smbus alert set low. + * - I2C_SMBUS_ALERT_HIGH: smbus alert set high. + * @retval none + */ +void i2c_smbus_alert_set(i2c_type *i2c_x, i2c_smbus_alert_set_type level) +{ + i2c_x->ctrl1_bit.smbalert = level; +} + +/** + * @brief enable or disable slave data control. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_slave_data_ctrl_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.sctrl = new_state; +} + +/** + * @brief enable or disable pec calculate. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_pec_calculate_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl1_bit.pecen = new_state; +} + +/** + * @brief enable or disable pec transfer. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_pec_transmit_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->ctrl2_bit.pecten = new_state; +} + +/** + * @brief get the i2c pec value. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @retval the value of the pec. + */ +uint8_t i2c_pec_value_get(i2c_type *i2c_x) +{ + return (uint8_t)(i2c_x->pec_bit.pecval); +} + +/** + * @brief config the i2c bus timeout. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param timeout: timeout (0x0000~0x0FFF). + * @retval none + */ +void i2c_timeout_set(i2c_type *i2c_x, uint16_t timeout) +{ + i2c_x->timeout_bit.totime = timeout; +} + +/** + * @brief config the bus timeout detcet level. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param level + * this parameter can be one of the following values: + * - I2C_TIMEOUT_DETCET_HIGH: detect high level timeout. + * - I2C_TIMEOUT_DETCET_LOW: detect low level timeout. + * @retval none + */ +void i2c_timeout_detcet_set(i2c_type *i2c_x, i2c_timeout_detcet_type mode) +{ + i2c_x->timeout_bit.tomode = mode; +} + +/** + * @brief enable or disable bus timeout. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_timeout_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->timeout_bit.toen = new_state; +} + +/** + * @brief config the i2c extend bus timeout. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param timeout: extend timeout (0x0000~0x0FFF). + * @retval none + */ +void i2c_ext_timeout_set(i2c_type *i2c_x, uint16_t timeout) +{ + i2c_x->timeout_bit.exttime = timeout; +} + +/** + * @brief enable or disable extend bus timeout. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_ext_timeout_enable(i2c_type *i2c_x, confirm_state new_state) +{ + i2c_x->timeout_bit.exten = new_state; +} + +/** + * @brief enable or disable interrupts. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param i2c_int: interrupts sources. + * this parameter can be one of the following values: + * - I2C_TD_INT: transmit data interrupt. + * - I2C_RD_INT: receive data interrupt. + * - I2C_ADDR_INT: address match interrupt. + * - I2C_ACKFIAL_INT: ack fail interrupt. + * - I2C_STOP_INT: stop detect interrupt. + * - I2C_TDC_INT: transmit data complete interrupt. + * - I2C_ERR_INT: bus error interrupt. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_interrupt_enable(i2c_type *i2c_x, uint32_t source, confirm_state new_state) +{ + if (new_state != FALSE) + { + i2c_x->ctrl1 |= source; + } + else + { + i2c_x->ctrl1 &= (uint32_t)~source; + } +} + +/** + * @brief get interrupt status + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param source + * this parameter can be one of the following values: + * - I2C_TD_INT: transmit data interrupt. + * - I2C_RD_INT: receive data interrupt. + * - I2C_ADDR_INT: address match interrupt. + * - I2C_ACKFIAL_INT: ack fail interrupt. + * - I2C_STOP_INT: stop detect interrupt. + * - I2C_TDC_INT: transmit data complete interrupt. + * - I2C_ERR_INT: bus error interrupt. + * @retval flag_status (SET or RESET) + */ +flag_status i2c_interrupt_get(i2c_type *i2c_x, uint16_t source) +{ + if((i2c_x->ctrl1 & source) != RESET) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief enable or disable dma requests. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param dma_req: dma transfer request. + * this parameter can be one of the following values: + * - I2C_DMA_REQUEST_TX: dma transmit request. + * - I2C_DMA_REQUEST_RX: dma receive request. + * @param new_state (TRUE or FALSE). + * @retval none + */ +void i2c_dma_enable(i2c_type *i2c_x, i2c_dma_request_type dma_req, confirm_state new_state) +{ + if(dma_req == I2C_DMA_REQUEST_TX) + { + i2c_x->ctrl1_bit.dmaten = new_state; + } + else + { + i2c_x->ctrl1_bit.dmaren = new_state; + } +} + +/** + * @brief config data transfer. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param address: slave address. + * @param cnt: transfer conuter(0~255) + * @param rld_stop: config reload and gen stop condition mode. + * this parameter can be one of the following values: + * - I2C_AUTO_STOP_MODE: auto generate stop mode. + * - I2C_SOFT_STOP_MODE: soft generate stop mode. + * - I2C_RELOAD_MODE: reload mode. + * @param start: config gen start condition mode. + * this parameter can be one of the following values: + * - I2C_WITHOUT_START: transfer data without start condition. + * - I2C_GEN_START_READ: read data and generate start. + * - I2C_GEN_START_WRITE: send data and generate start. + * @retval none + */ +void i2c_transmit_set(i2c_type *i2c_x, uint16_t address, uint8_t cnt, i2c_reload_stop_mode_type rld_stop, i2c_start_mode_type start) +{ + uint32_t temp; + + /* copy ctrl2 value to temp */ + temp = i2c_x->ctrl2; + + /* clear ctrl2_bit specific bits */ + temp &= ~0x03FF67FF; + + /* transfer mode and address set */ + temp |= address | rld_stop | start; + + /* transfer counter set */ + temp |= (uint32_t)cnt << 16; + + /* update ctrl2 value */ + i2c_x->ctrl2 = temp; +} + +/** + * @brief generate start condition. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @retval none + */ +void i2c_start_generate(i2c_type *i2c_x) +{ + i2c_x->ctrl2_bit.genstart = TRUE; +} + +/** + * @brief generate stop condition. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @retval none + */ +void i2c_stop_generate(i2c_type *i2c_x) +{ + i2c_x->ctrl2_bit.genstop = TRUE; +} + +/** + * @brief send a byte through the i2c periph. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param data: byte to be transmitted. + * @retval none + */ +void i2c_data_send(i2c_type *i2c_x, uint8_t data) +{ + i2c_x->txdt = data; +} + +/** + * @brief receive a byte through the i2c periph. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @retval the value of the received data. + */ +uint8_t i2c_data_receive(i2c_type *i2c_x) +{ + return (uint8_t)i2c_x->rxdt; +} + +/** + * @brief get flag status. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - I2C_TDBE_FLAG: transmit data buffer empty flag. + * - I2C_TDIS_FLAG: send interrupt status. + * - I2C_RDBF_FLAG: receive data buffer full flag. + * - I2C_ADDRF_FLAG: 0~7 bit address match flag. + * - I2C_ACKFAIL_FLAG: acknowledge failure flag. + * - I2C_STOPF_FLAG: stop condition generation complete flag. + * - I2C_TDC_FLAG: transmit data complete flag. + * - I2C_TCRLD_FLAG: transmission is complete, waiting to load data. + * - I2C_BUSERR_FLAG: bus error flag. + * - I2C_ARLOST_FLAG: arbitration lost flag. + * - I2C_OUF_FLAG: overflow or underflow flag. + * - I2C_PECERR_FLAG: pec receive error flag. + * - I2C_TMOUT_FLAG: smbus timeout flag. + * - I2C_ALERTF_FLAG: smbus alert flag. + * - I2C_BUSYF_FLAG: bus busy flag transmission mode. + * - I2C_SDIR_FLAG: slave data transmit direction. + * @retval the new state of flag (SET or RESET). + */ +flag_status i2c_flag_get(i2c_type *i2c_x, uint32_t flag) +{ + if((i2c_x->sts & flag) != RESET) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief get interrupt flag status. + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - I2C_TDBE_FLAG: transmit data buffer empty flag. + * - I2C_TDIS_FLAG: send interrupt status. + * - I2C_RDBF_FLAG: receive data buffer full flag. + * - I2C_ADDRF_FLAG: 0~7 bit address match flag. + * - I2C_ACKFAIL_FLAG: acknowledge failure flag. + * - I2C_STOPF_FLAG: stop condition generation complete flag. + * - I2C_TDC_FLAG: transmit data complete flag. + * - I2C_TCRLD_FLAG: transmission is complete, waiting to load data. + * - I2C_BUSERR_FLAG: bus error flag. + * - I2C_ARLOST_FLAG: arbitration lost flag. + * - I2C_OUF_FLAG: overflow or underflow flag. + * - I2C_PECERR_FLAG: pec receive error flag. + * - I2C_TMOUT_FLAG: smbus timeout flag. + * - I2C_ALERTF_FLAG: smbus alert flag. + * @retval the new state of flag (SET or RESET). + */ +flag_status i2c_interrupt_flag_get(i2c_type *i2c_x, uint32_t flag) +{ + __IO uint32_t iten = 0; + + switch(flag) + { + case I2C_TDIS_FLAG: + iten = i2c_x->ctrl1_bit.tdien; + break; + case I2C_RDBF_FLAG: + iten = i2c_x->ctrl1_bit.rdien; + break; + case I2C_ADDRF_FLAG: + iten = i2c_x->ctrl1_bit.addrien; + break; + case I2C_ACKFAIL_FLAG: + iten = i2c_x->ctrl1_bit.ackfailien; + break; + case I2C_STOPF_FLAG: + iten = i2c_x->ctrl1_bit.stopien; + break; + case I2C_TDC_FLAG: + case I2C_TCRLD_FLAG: + iten = i2c_x->ctrl1_bit.tdcien; + break; + case I2C_BUSERR_FLAG: + case I2C_ARLOST_FLAG: + case I2C_OUF_FLAG: + case I2C_PECERR_FLAG: + case I2C_TMOUT_FLAG: + case I2C_ALERTF_FLAG: + iten = i2c_x->ctrl1_bit.errien; + break; + + default: + break; + } + + if(((i2c_x->sts & flag) != RESET) && (iten)) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief clear flag status + * @param i2c_x: to select the i2c peripheral. + * this parameter can be one of the following values: + * I2C1, I2C2. + * @param flag: specifies the flag to clear. + * this parameter can be any combination of the following values: + * - I2C_ADDRF_FLAG: 0~7 bit address match flag. + * - I2C_ACKFAIL_FLAG: acknowledge failure flag. + * - I2C_STOPF_FLAG: stop condition generation complete flag. + * - I2C_BUSERR_FLAG: bus error flag. + * - I2C_ARLOST_FLAG: arbitration lost flag. + * - I2C_OUF_FLAG: overflow or underflow flag. + * - I2C_PECERR_FLAG: pec receive error flag. + * - I2C_TMOUT_FLAG: smbus timeout flag. + * - I2C_ALERTF_FLAG: smbus alert flag. + * @retval none + */ +void i2c_flag_clear(i2c_type *i2c_x, uint32_t flag) +{ + i2c_x->clr = flag; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_misc.c b/libraries/drivers/src/at32f425_misc.c new file mode 100644 index 0000000..2dcef80 --- /dev/null +++ b/libraries/drivers/src/at32f425_misc.c @@ -0,0 +1,171 @@ +/** + ************************************************************************** + * @file at32f425_misc.c + * @brief contains all the functions for the misc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* includes ------------------------------------------------------------------*/ +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup MISC + * @brief MISC driver modules + * @{ + */ + +#ifdef MISC_MODULE_ENABLED + +/** @defgroup MISC_private_functions + * @{ + */ + +#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) + +/** + * @brief system reset + * @param none + * @retval none + */ +void nvic_system_reset(void) +{ + NVIC_SystemReset(); +} + +/** + * @brief enable nvic irq + * @param irqn (IRQn_Type number) + * @param preempt_priority: preemptive priority value (starting from 0) + * @param sub_priority: subpriority value (starting from 0) + * @retval none + */ +void nvic_irq_enable(IRQn_Type irqn, uint32_t preempt_priority, uint32_t sub_priority) +{ + uint32_t temp_priority = 0; + + /* encode priority */ + temp_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preempt_priority, sub_priority); + /* set priority */ + NVIC_SetPriority(irqn, temp_priority); + /* enable irqn */ + NVIC_EnableIRQ(irqn); +} + +/** + * @brief disable nvic irq number + * @param irqn (IRQn_Type number) + * @retval none + */ +void nvic_irq_disable(IRQn_Type irqn) +{ + NVIC_DisableIRQ(irqn); +} + +/** + * @brief config nvic priority group + * @param priority_group + * this parameter can be one of the following values: + * - NVIC_PRIORITY_GROUP_0 + * - NVIC_PRIORITY_GROUP_1 + * - NVIC_PRIORITY_GROUP_2 + * - NVIC_PRIORITY_GROUP_3 + * - NVIC_PRIORITY_GROUP_4 + * @retval none + */ +void nvic_priority_group_config(nvic_priority_group_type priority_group) +{ + /* set the prigroup[10:8] bits according to nvic_prioritygroup value */ + NVIC_SetPriorityGrouping(priority_group); +} + +/** + * @brief set the vector table location and offset. + * @param base + * this parameter can be one of the following values: + * - NVIC_VECTTAB_RAM + * - NVIC_VECTTAB_FLASH + * @param offset (vector table base offset field. this value must be a multiple of 0x200) + * @retval none + */ +void nvic_vector_table_set(uint32_t base, uint32_t offset) +{ + SCB->VTOR = base | (offset & (uint32_t)0x1FFFFF80); +} + +/** + * @brief config nvic lowpower mode + * @param lp_mode + * this parameter can be one of the following values: + * - NVIC_LP_SEVONPEND + * - NVIC_LP_SLEEPDEEP + * - NVIC_LP_SLEEPONEXIT + * @param new_state (new state of lp condition. ENABLE or DISABLE) + * @retval none + */ +void nvic_lowpower_mode_config(nvic_lowpower_mode_type lp_mode, confirm_state new_state) +{ + if(new_state != FALSE) + { + SCB->SCR |= lp_mode; + } + else + { + SCB->SCR &= (uint32_t)(~(uint32_t)lp_mode); + } +} + +/** + * @brief config systick clock source + * @param source + * this parameter can be one of the following values: + * - SYSTICK_CLOCK_SOURCE_AHBCLK_DIV8 + * - SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV + * @retval none + */ +void systick_clock_source_config(systick_clock_source_type source) +{ + if(source == SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV) + { + SysTick->CTRL |= SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV; + } + else + { + SysTick->CTRL &= ~(uint32_t)SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV; + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ + + diff --git a/libraries/drivers/src/at32f425_pwc.c b/libraries/drivers/src/at32f425_pwc.c new file mode 100644 index 0000000..8ec4982 --- /dev/null +++ b/libraries/drivers/src/at32f425_pwc.c @@ -0,0 +1,269 @@ +/** + ************************************************************************** + * @file at32f425_pwc.c + * @brief contains all the functions for the pwc firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup PWC + * @brief PWC driver modules + * @{ + */ + +#ifdef PWC_MODULE_ENABLED + +/** @defgroup PWC_private_functions + * @{ + */ + +/** + * @brief deinitialize the pwc peripheral registers to their default reset values. + * @param none + * @retval none + */ +void pwc_reset(void) +{ + crm_periph_reset(CRM_PWC_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_PWC_PERIPH_RESET, FALSE); +} + +/** + * @brief enable or disable access to the battery powered domain. + * @param new_state: new state of battery powered domain access. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void pwc_battery_powered_domain_access(confirm_state new_state) +{ + PWC->ctrl_bit.bpwen = new_state; +} + +/** + * @brief select the voltage threshold detected by the power voltage detector. + * @param pvm_voltage: select pwc pvm voltage + * this parameter can be one of the following values: + * - PWC_PVM_VOLTAGE_2V3 + * - PWC_PVM_VOLTAGE_2V4 + * - PWC_PVM_VOLTAGE_2V5 + * - PWC_PVM_VOLTAGE_2V6 + * - PWC_PVM_VOLTAGE_2V7 + * - PWC_PVM_VOLTAGE_2V8 + * - PWC_PVM_VOLTAGE_2V9 + * @retval none + */ +void pwc_pvm_level_select(pwc_pvm_voltage_type pvm_voltage) +{ + PWC->ctrl_bit.pvmsel = pvm_voltage; +} + +/** + * @brief enable or disable pwc power voltage monitor (pvm) + * @param new_state: new state of pvm. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void pwc_power_voltage_monitor_enable(confirm_state new_state) +{ + PWC->ctrl_bit.pvmen = new_state; +} + +/** + * @brief enable or disable pwc standby wakeup pin + * @param pin_num: choose the wakeup pin. + * this parameter can be be any combination of the following values: + * - PWC_WAKEUP_PIN_1 + * - PWC_WAKEUP_PIN_2 + * - PWC_WAKEUP_PIN_4 + * - PWC_WAKEUP_PIN_5 + * - PWC_WAKEUP_PIN_6 + * - PWC_WAKEUP_PIN_7 + * @param new_state: new state of the standby wakeup pin. + * this parameter can be one of the following values: + * - TRUE + * - FALSE + * @retval none + */ +void pwc_wakeup_pin_enable(uint32_t pin_num, confirm_state new_state) +{ + if(new_state == TRUE) + { + PWC->ctrlsts |= pin_num; + } + else + { + PWC->ctrlsts &= ~pin_num; + } +} + +/** + * @brief clear flag of pwc + * @param pwc_flag: select the pwc flag. + * this parameter can be any combination of the following values: + * - PWC_WAKEUP_FLAG + * - PWC_STANDBY_FLAG + * - note:"PWC_PVM_OUTPUT_FLAG" cannot be choose!this bit is readonly bit,it means the voltage monitoring output state + * @retval none + */ +void pwc_flag_clear(uint32_t pwc_flag) +{ + if(pwc_flag & PWC_STANDBY_FLAG) + PWC->ctrl_bit.clsef = TRUE; + if(pwc_flag & PWC_WAKEUP_FLAG) + PWC->ctrl_bit.clswef = TRUE; +} + +/** + * @brief get flag of pwc + * @param pwc_flag: select the pwc flag. + * this parameter can be one of the following values: + * - PWC_WAKEUP_FLAG + * - PWC_STANDBY_FLAG + * - PWC_PVM_OUTPUT_FLAG + * @retval state of select flag(SET or RESET). + */ +flag_status pwc_flag_get(uint32_t pwc_flag) +{ + flag_status status = RESET; + if ((PWC->ctrlsts & pwc_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief enter pwc sleep mode + * @param sleep_mode_enter: choose the instruction to enter sleep mode. + * this parameter can be one of the following values: + * - PWC_SLEEP_ENTER_WFI + * - PWC_SLEEP_ENTER_WFE + * @retval none + */ +void pwc_sleep_mode_enter(pwc_sleep_enter_type pwc_sleep_enter) +{ + SCB->SCR &= (uint32_t)~0x4; + if(pwc_sleep_enter == PWC_SLEEP_ENTER_WFE) + { + __SEV(); + __WFE(); + __WFE(); + } + else if(pwc_sleep_enter == PWC_SLEEP_ENTER_WFI) + { + __WFI(); + } +} + +/** + * @brief enter pwc deep-sleep mode + * @param pwc_deep_sleep_enter: choose the instruction to enter deep sleep mode. + * this parameter can be one of the following values: + * - PWC_DEEP_SLEEP_ENTER_WFI + * - PWC_DEEP_SLEEP_ENTER_WFE + * @retval none + */ +void pwc_deep_sleep_mode_enter(pwc_deep_sleep_enter_type pwc_deep_sleep_enter) +{ + SCB->SCR |= 0x04; + if(pwc_deep_sleep_enter == PWC_DEEP_SLEEP_ENTER_WFE) + { + __SEV(); + __WFE(); + __WFE(); + } + else if(pwc_deep_sleep_enter == PWC_DEEP_SLEEP_ENTER_WFI) + { + __WFI(); + } + SCB->SCR &= (uint32_t)~0x4; +} + +/** + * @brief regulate low power consumption in the deep sleep mode + * @param pwc_regulator: set the regulator state. + * this parameter can be one of the following values: + * - PWC_REGULATOR_ON + * - PWC_REGULATOR_LOW_POWER + * - PWC_REGULATOR_EXTRA_LOW_POWER + * @retval none + */ +void pwc_voltage_regulate_set(pwc_regulator_type pwc_regulator) +{ + switch(pwc_regulator) + { + case PWC_REGULATOR_ON: + PWC->ctrl2_bit.vrexlpen = FALSE; + PWC->ctrl_bit.vrsel = FALSE; + break; + case PWC_REGULATOR_LOW_POWER: + PWC->ctrl2_bit.vrexlpen = FALSE; + PWC->ctrl_bit.vrsel = TRUE; + break; + case PWC_REGULATOR_EXTRA_LOW_POWER: + PWC->ctrl2_bit.vrexlpen = TRUE; + PWC->ctrl_bit.vrsel = TRUE; + break; + default: + break; + } +} + +/** + * @brief enter pwc standby mode + * @param none + * @retval none + */ +void pwc_standby_mode_enter(void) +{ + PWC->ctrl_bit.clswef = TRUE; + PWC->ctrl_bit.lpsel = TRUE; + SCB->SCR |= 0x04; +#if defined (__CC_ARM) + __force_stores(); +#endif + while(1) + { + __WFI(); + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_scfg.c b/libraries/drivers/src/at32f425_scfg.c new file mode 100644 index 0000000..26a3b38 --- /dev/null +++ b/libraries/drivers/src/at32f425_scfg.c @@ -0,0 +1,228 @@ +/** + ************************************************************************** + * @file at32f425_scfg.c + * @brief contains all the functions for the system config firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup SCFG + * @brief SCFG driver modules + * @{ + */ + +#ifdef SCFG_MODULE_ENABLED + +/** @defgroup SCFG_private_functions + * @{ + */ + +/** + * @brief scfg reset + * @param none + * @retval none + */ +void scfg_reset(void) +{ + crm_periph_reset(CRM_SCFG_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SCFG_PERIPH_RESET, FALSE); +} + +/** + * @brief scfg infrared config + * @param source + * this parameter can be one of the following values: + * - SCFG_IR_SOURCE_TMR10 + * @param polarity + * this parameter can be one of the following values: + * - SCFG_IR_POLARITY_NO_AFFECTE + * - SCFG_IR_POLARITY_REVERSE + * @retval none + */ +void scfg_infrared_config(scfg_ir_source_type source, scfg_ir_polarity_type polarity) +{ + SCFG->cfg1_bit.ir_src_sel = source; + SCFG->cfg1_bit.ir_pol = polarity; +} + +/** + * @brief scfg memory address mapping get + * @param none + * @retval return parameter can be one of the following values: + * - SCFG_MEM_MAP_MAIN_MEMORY + * - SCFG_MEM_MAP_BOOT_MEMORY + * - SCFG_MEM_MAP_INTERNAL_SRAM + */ +scfg_mem_map_type scfg_mem_map_get(void) +{ + if(SCFG->cfg1_bit.mem_map_sel & 0x1) + { + return (scfg_mem_map_type)SCFG->cfg1_bit.mem_map_sel; + } + return SCFG_MEM_MAP_MAIN_MEMORY; +} + +/** + * @brief scfg pa11/12 pin remap + * @param pin_remap + * this parameter can be one of the following values: + * - SCFG_PA11PA12_NO_REMAP + * - SCFG_PA11PA12_TO_PA9PA10 + * @retval none + */ +void scfg_pa11pa12_pin_remap(scfg_pa11pa12_remap_type pin_remap) +{ + SCFG->cfg1_bit.pa11_12_rmp = pin_remap; +} + + +/** + * @brief select the gpio pin used as exint line. + * @param port_source: + * select the gpio port to be used as source for exint lines. + * this parameter can be one of the following values: + * - SCFG_PORT_SOURCE_GPIOA + * - SCFG_PORT_SOURCE_GPIOB + * - SCFG_PORT_SOURCE_GPIOC + * - SCFG_PORT_SOURCE_GPIOD + * - SCFG_PORT_SOURCE_GPIOF + * @param pin_source: + * specifies the exint line to be configured. + * this parameter can be one of the following values: + * - SCFG_PINS_SOURCE0 + * - SCFG_PINS_SOURCE1 + * - SCFG_PINS_SOURCE2 + * - SCFG_PINS_SOURCE3 + * - SCFG_PINS_SOURCE4 + * - SCFG_PINS_SOURCE5 + * - SCFG_PINS_SOURCE6 + * - SCFG_PINS_SOURCE7 + * - SCFG_PINS_SOURCE8 + * - SCFG_PINS_SOURCE9 + * - SCFG_PINS_SOURCE10 + * - SCFG_PINS_SOURCE11 + * - SCFG_PINS_SOURCE12 + * - SCFG_PINS_SOURCE13 + * - SCFG_PINS_SOURCE14 + * - SCFG_PINS_SOURCE15 + * @retval none + */ +void scfg_exint_line_config(scfg_port_source_type port_source, scfg_pins_source_type pin_source) +{ + uint32_t tmp = 0x00; + tmp = ((uint32_t)0x0F) << (0x04 * (pin_source & (uint8_t)0x03)); + + switch (pin_source >> 0x02) + { + case 0: + SCFG->exintc1 &= ~tmp; + SCFG->exintc1 |= (((uint32_t)port_source) << (0x04 * (pin_source & (uint8_t)0x03))); + break; + + case 1: + SCFG->exintc2 &= ~tmp; + SCFG->exintc2 |= (((uint32_t)port_source) << (0x04 * (pin_source & (uint8_t)0x03))); + break; + + case 2: + SCFG->exintc3 &= ~tmp; + SCFG->exintc3 |= (((uint32_t)port_source) << (0x04 * (pin_source & (uint8_t)0x03))); + break; + + case 3: + SCFG->exintc4 &= ~tmp; + SCFG->exintc4 |= (((uint32_t)port_source) << (0x04 * (pin_source & (uint8_t)0x03))); + break; + + default: + break; + } +} + +/** + * @brief enable or disable gpio pins ultra driven. + * @param value: + * this parameter can be one of the following values: + * - SCFG_ULTRA_DRIVEN_PB8 + * - SCFG_ULTRA_DRIVEN_PB9 + * - SCFG_ULTRA_DRIVEN_PB13 + * - SCFG_ULTRA_DRIVEN_PB14 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void scfg_pins_ultra_driven_enable(scfg_ultra_driven_pins_type value, confirm_state new_state) +{ + if(TRUE == new_state) + { + SCFG->cfg1 |= value; + } + else + { + SCFG->cfg1&= ~value; + } +} + +/** + * @brief i2s full duplex config. + * @param i2s_full_duplex: + * this parameter can be one of the following values: + * - SCFG_FULL_DUPLEX_I2S_NONE + * - SCFG_FULL_DUPLEX_I2S1_I2S3 + * - SCFG_FULL_DUPLEX_I2S2_I2S3 + * - SCFG_FULL_DUPLEX_I2S1_I2S2 + * @retval none + */ +void scfg_i2s_full_duplex_config(scfg_i2s_type i2s_full_duplex) +{ + SCFG->cfg2_bit.i2s_fd = i2s_full_duplex; +} + +/** + * @brief scfg pvm lock enable. + * @param new_state (TRUE or FALSE) + * - TRUE (pvm interrupt connect to the brake of TMR15/16/17 ) + * - FALSE (pvm interrupt not connect to the brake of TMR15/16/17 ) + * @retval none + */ +void scfg_pvm_lock_enable(confirm_state new_state) +{ + SCFG->cfg2_bit.pvm_lk = new_state; +} + + + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_spi.c b/libraries/drivers/src/at32f425_spi.c new file mode 100644 index 0000000..1dbc272 --- /dev/null +++ b/libraries/drivers/src/at32f425_spi.c @@ -0,0 +1,715 @@ +/** + ************************************************************************** + * @file at32f425_spi.c + * @brief contains all the functions for the spi firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup SPI + * @brief SPI driver modules + * @{ + */ + +#ifdef SPI_MODULE_ENABLED + +/** @defgroup SPI_private_functions + * @{ + */ + +/** + * @brief spi reset by crm reset register + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @retval none + */ +void spi_i2s_reset(spi_type *spi_x) +{ + if(spi_x == SPI1) + { + crm_periph_reset(CRM_SPI1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI1_PERIPH_RESET, FALSE); + } + else if(spi_x == SPI2) + { + crm_periph_reset(CRM_SPI2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI2_PERIPH_RESET, FALSE); + } +#if defined (AT32F425Rx) || defined (AT32F425Cx) || defined (AT32F425Kx) || \ + defined (AT32F425Gx) + else if(spi_x == SPI3) + { + crm_periph_reset(CRM_SPI3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_SPI3_PERIPH_RESET, FALSE); + } +#endif +} + +/** + * @brief spi init config with its default value. + * @param spi_init_struct : pointer to a spi_init_type structure which will + * be initialized. + * @retval none + */ +void spi_default_para_init(spi_init_type* spi_init_struct) +{ + spi_init_struct->transmission_mode = SPI_TRANSMIT_FULL_DUPLEX; + spi_init_struct->master_slave_mode = SPI_MODE_SLAVE; + spi_init_struct->mclk_freq_division = SPI_MCLK_DIV_2; + spi_init_struct->first_bit_transmission = SPI_FIRST_BIT_MSB; + spi_init_struct->frame_bit_num = SPI_FRAME_8BIT; + spi_init_struct->clock_polarity = SPI_CLOCK_POLARITY_LOW; + spi_init_struct->clock_phase = SPI_CLOCK_PHASE_1EDGE; + spi_init_struct->cs_mode_selection = SPI_CS_SOFTWARE_MODE; +} + +/** + * @brief spi init config with its setting value. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param spi_init_struct : pointer to a spi_init_type structure which will be initialized. + * @retval none + */ +void spi_init(spi_type* spi_x, spi_init_type* spi_init_struct) +{ + spi_x->i2sctrl_bit.i2smsel = FALSE; + if(spi_init_struct->transmission_mode == SPI_TRANSMIT_FULL_DUPLEX) + { + spi_x->ctrl1_bit.slben = FALSE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = FALSE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_SIMPLEX_RX) + { + spi_x->ctrl1_bit.slben = FALSE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = TRUE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_HALF_DUPLEX_RX) + { + spi_x->ctrl1_bit.slben = TRUE; + spi_x->ctrl1_bit.slbtd = FALSE; + spi_x->ctrl1_bit.ora = FALSE; + } + else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_HALF_DUPLEX_TX) + { + spi_x->ctrl1_bit.slben = TRUE; + spi_x->ctrl1_bit.slbtd = TRUE; + spi_x->ctrl1_bit.ora = FALSE; + } + + spi_x->ctrl1_bit.swcsen = spi_init_struct->cs_mode_selection; + if((spi_init_struct->master_slave_mode == SPI_MODE_MASTER) && (spi_init_struct->cs_mode_selection == SPI_CS_SOFTWARE_MODE)) + { + spi_x->ctrl1_bit.swcsil = TRUE; + } + else + { + spi_x->ctrl1_bit.swcsil = FALSE; + } + spi_x->ctrl1_bit.msten = spi_init_struct->master_slave_mode; + if(spi_init_struct->mclk_freq_division <= SPI_MCLK_DIV_256) + { + spi_x->ctrl2_bit.mdiv3en = FALSE; + spi_x->ctrl2_bit.mdiv_h = FALSE; + spi_x->ctrl1_bit.mdiv_l = spi_init_struct->mclk_freq_division; + } + else if(spi_init_struct->mclk_freq_division == SPI_MCLK_DIV_3) + { + spi_x->ctrl2_bit.mdiv3en = TRUE; + spi_x->ctrl2_bit.mdiv_h = FALSE; + spi_x->ctrl1_bit.mdiv_l = 0; + } + else + { + spi_x->ctrl2_bit.mdiv3en = FALSE; + spi_x->ctrl2_bit.mdiv_h = TRUE; + spi_x->ctrl1_bit.mdiv_l = spi_init_struct->mclk_freq_division & 0x7; + } + spi_x->ctrl1_bit.ltf = spi_init_struct->first_bit_transmission; + spi_x->ctrl1_bit.fbn = spi_init_struct->frame_bit_num; + spi_x->ctrl1_bit.clkpol = spi_init_struct->clock_polarity; + spi_x->ctrl1_bit.clkpha = spi_init_struct->clock_phase; +} + +/** + * @brief enable or disable the ti mode for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param new_state: new state of ti mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_ti_mode_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.tien = new_state; +} + +/** + * @brief spi next transmit crc for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @retval none + */ +void spi_crc_next_transmit(spi_type* spi_x) +{ + spi_x->ctrl1_bit.ntc = TRUE; +} + +/** + * @brief set the crc polynomial value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param crc_poly: crc polynomial value. + * @retval none + */ +void spi_crc_polynomial_set(spi_type* spi_x, uint16_t crc_poly) +{ + spi_x->cpoly_bit.cpoly = crc_poly; +} + +/** + * @brief return the crc polynomial register value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @retval the select crc polynomial register value + */ +uint16_t spi_crc_polynomial_get(spi_type* spi_x) +{ + return spi_x->cpoly_bit.cpoly; +} + +/** + * @brief enable or disable the hardware crc calculation for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param new_state: new state of crc calculation. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_crc_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl1_bit.ccen = new_state; +} + +/** + * @brief return the transmit or the receive crc value for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param crc_direction: select transmit or receive crc value to be read + * - SPI_CRC_RX + * - SPI_CRC_TX + * @retval the select crc register value + */ +uint16_t spi_crc_value_get(spi_type* spi_x, spi_crc_direction_type crc_direction) +{ + if(crc_direction == SPI_CRC_RX) + return spi_x->rcrc_bit.rcrc; + else + return spi_x->tcrc_bit.tcrc; +} + +/** + * @brief enable or disable the hardware cs output for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param new_state: new state of spi master cs output. + * this parameter can be: TRUE or FALSE. + * note:the bit only use in spi master mode + * @retval none + */ +void spi_hardware_cs_output_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.hwcsoe = new_state; +} + +/** + * @brief set the software cs internal level for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param level: set the state of spi cs level. + * this parameter can be one of the following values: + * - SPI_SWCS_INTERNAL_LEVEL_LOW + * - SPI_SWCS_INTERNAL_LEVEL_HIGHT + * note:the bit only use when swcsen bit is set. + * note:when use this bit,io operation on the cs pin are invalid. + * @retval none + */ +void spi_software_cs_internal_level_set(spi_type* spi_x, spi_software_cs_level_type level) +{ + spi_x->ctrl1_bit.swcsil = level; +} + +/** + * @brief set the data frame bit num for the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param bit_num: set the data frame size + * - SPI_FRAME_8BIT + * - SPI_FRAME_16BIT + * @retval none + */ +void spi_frame_bit_num_set(spi_type* spi_x, spi_frame_bit_num_type bit_num) +{ + spi_x->ctrl1_bit.fbn = bit_num; +} + +/** + * @brief set the data transmission direction in single line bidirectiona half duplex mode of the spi peripheral. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param direction: data transfer direction + * this parameter can be one of the following values: + * - SPI_HALF_DUPLEX_DIRECTION_RX + * - SPI_HALF_DUPLEX_DIRECTION_TX + * @retval none + */ +void spi_half_duplex_direction_set(spi_type* spi_x, spi_half_duplex_direction_type direction) +{ + spi_x->ctrl1_bit.slbtd = direction; +} + +/** + * @brief enable or disable spi. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param new_state: new state of spi. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl1_bit.spien = new_state; +} + +/** + * @brief i2s init config with its default value. + * @param i2s_init_struct : pointer to a i2s_init_type structure which will + * be initialized. + * @retval none + */ +void i2s_default_para_init(i2s_init_type* i2s_init_struct) +{ + i2s_init_struct->operation_mode = I2S_MODE_SLAVE_TX; + i2s_init_struct->audio_protocol = I2S_AUDIO_PROTOCOL_PHILLIPS; + i2s_init_struct->audio_sampling_freq = I2S_AUDIO_FREQUENCY_DEFAULT; + i2s_init_struct->data_channel_format = I2S_DATA_16BIT_CHANNEL_16BIT; + i2s_init_struct->clock_polarity = I2S_CLOCK_POLARITY_LOW; + i2s_init_struct->mclk_output_enable = FALSE; +} + +/** + * @brief i2s init config with its setting value. + * @param spi_x: select the spi peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param i2s_init_struct : pointer to a i2s_init_type structure which will be initialized. + * @retval none + */ +void i2s_init(spi_type* spi_x, i2s_init_type* i2s_init_struct) +{ + crm_clocks_freq_type clocks_freq; + uint32_t i2s_sclk_index = 0; + uint32_t i2sdiv_index = 2, i2sodd_index = 0, frequency_index = 0; + + /* i2s audio frequency config */ + if(i2s_init_struct->audio_sampling_freq == I2S_AUDIO_FREQUENCY_DEFAULT) + { + i2sodd_index = 0; + i2sdiv_index = 2; + } + else + { + crm_clocks_freq_get(&clocks_freq); + i2s_sclk_index = clocks_freq.sclk_freq; + if((i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_SHORT) || (i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_LONG)) + { + if(i2s_init_struct->mclk_output_enable == TRUE) + { + frequency_index = (((i2s_sclk_index / 128) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + else + { + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + frequency_index = (((i2s_sclk_index / 16) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + else + frequency_index = (((i2s_sclk_index / 32) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + } + else + { + if(i2s_init_struct->mclk_output_enable == TRUE) + { + frequency_index = (((i2s_sclk_index / 256) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + else + { + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + frequency_index = (((i2s_sclk_index / 32) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + else + frequency_index = (((i2s_sclk_index / 64) * 10) / i2s_init_struct->audio_sampling_freq) + 5; + } + } + } + frequency_index = frequency_index / 10; + i2sodd_index = frequency_index & (uint16_t)0x0001; + i2sdiv_index = (frequency_index - i2sodd_index) / 2; + if((i2sdiv_index < 2) || (i2sdiv_index > 0x03FF)) + { + i2sodd_index = 0; + i2sdiv_index = 2; + } + spi_x->i2sclk_bit.i2sodd = i2sodd_index; + if(i2sdiv_index > 0x00FF) + { + spi_x->i2sclk_bit.i2sdiv_h = (i2sdiv_index >> 8) & 0x0003; + spi_x->i2sclk_bit.i2sdiv_l = i2sdiv_index & 0x00FF; + } + else + { + spi_x->i2sclk_bit.i2sdiv_h = 0; + spi_x->i2sclk_bit.i2sdiv_l = i2sdiv_index; + } + + /* i2s audio_protocol set*/ + if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_LONG) + { + spi_x->i2sctrl_bit.pcmfssel = 1; + spi_x->i2sctrl_bit.stdsel = 3; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_SHORT) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 3; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_LSB) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 2; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_MSB) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 1; + } + else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PHILLIPS) + { + spi_x->i2sctrl_bit.pcmfssel = 0; + spi_x->i2sctrl_bit.stdsel = 0; + } + + /* i2s data_channel_format set*/ + if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT) + { + spi_x->i2sctrl_bit.i2scbn = 0; + spi_x->i2sctrl_bit.i2sdbn = 0; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 0; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_24BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 1; + } + else if(i2s_init_struct->data_channel_format == I2S_DATA_32BIT_CHANNEL_32BIT) + { + spi_x->i2sctrl_bit.i2scbn = 1; + spi_x->i2sctrl_bit.i2sdbn = 2; + } + + spi_x->i2sctrl_bit.i2sclkpol = i2s_init_struct->clock_polarity; + spi_x->i2sclk_bit.i2smclkoe = i2s_init_struct->mclk_output_enable; + spi_x->i2sctrl_bit.opersel = i2s_init_struct->operation_mode; + spi_x->i2sctrl_bit.i2smsel = TRUE; +} + +/** + * @brief enable or disable i2s. + * @param spi_x: select the i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param new_state: new state of i2s. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void i2s_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->i2sctrl_bit.i2sen = new_state; +} + +/** + * @brief enable or disable the specified spi/i2s interrupts. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param spi_i2s_int: specifies the spi/i2s interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - SPI_I2S_ERROR_INT + * - SPI_I2S_RDBF_INT + * - SPI_I2S_TDBE_INT + * @param new_state: new state of the specified spi/i2s interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_interrupt_enable(spi_type* spi_x, uint32_t spi_i2s_int, confirm_state new_state) +{ + if(new_state != FALSE) + { + spi_x->ctrl2 |= spi_i2s_int; + } + else + { + spi_x->ctrl2 &= ~spi_i2s_int; + } +} + +/** + * @brief enable or disable the spi/i2s dma transmitter mode. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param new_state: new state of the dma request. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_dma_transmitter_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.dmaten = new_state; +} + +/** + * @brief enable or disable the spi/i2s dma receiver mode. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param new_state: new state of the dma request. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void spi_i2s_dma_receiver_enable(spi_type* spi_x, confirm_state new_state) +{ + spi_x->ctrl2_bit.dmaren = new_state; +} + +/** + * @brief spi/i2s data transmit + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param tx_data: the data to be transmit. + * this parameter can be: + * - (0x0000~0xFFFF) + * @retval none + */ +void spi_i2s_data_transmit(spi_type* spi_x, uint16_t tx_data) +{ + spi_x->dt = tx_data; +} + +/** + * @brief spi/i2s data receive + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @retval the received data value + */ +uint16_t spi_i2s_data_receive(spi_type* spi_x) +{ + return (uint16_t)spi_x->dt; +} + +/** + * @brief get flag of the specified spi/i2s peripheral. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param spi_i2s_flag: select the spi/i2s flag + * this parameter can be one of the following values: + * - SPI_I2S_RDBF_FLAG + * - SPI_I2S_TDBE_FLAG + * - I2S_ACS_FLAG (this flag only use in i2s mode) + * - I2S_TUERR_FLAG (this flag only use in i2s mode) + * - SPI_CCERR_FLAG (this flag only use in spi mode) + * - SPI_MMERR_FLAG (this flag only use in spi mode) + * - SPI_I2S_ROERR_FLAG + * - SPI_I2S_BF_FLAG + * - SPI_CSPAS_FLAG + * @retval the new state of spi/i2s flag + */ +flag_status spi_i2s_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag) +{ + flag_status status = RESET; + if ((spi_x->sts & spi_i2s_flag) == RESET) + { + status = RESET; + } + else + { + status = SET; + } + return status; +} + +/** + * @brief get flag of the specified spi/i2s peripheral. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param spi_i2s_flag: select the spi/i2s flag + * this parameter can be one of the following values: + * - SPI_I2S_RDBF_FLAG + * - SPI_I2S_TDBE_FLAG + * - I2S_TUERR_FLAG (this flag only use in i2s mode) + * - SPI_CCERR_FLAG (this flag only use in spi mode) + * - SPI_MMERR_FLAG (this flag only use in spi mode) + * - SPI_I2S_ROERR_FLAG + * - SPI_CSPAS_FLAG + * @retval the new state of spi/i2s flag + */ +flag_status spi_i2s_interrupt_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag) +{ + flag_status status = RESET; + + switch(spi_i2s_flag) + { + case SPI_I2S_RDBF_FLAG: + if(spi_x->sts_bit.rdbf && spi_x->ctrl2_bit.rdbfie) + { + status = SET; + } + break; + case SPI_I2S_TDBE_FLAG: + if(spi_x->sts_bit.tdbe && spi_x->ctrl2_bit.tdbeie) + { + status = SET; + } + break; + case I2S_TUERR_FLAG: + if(spi_x->sts_bit.tuerr && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + case SPI_CCERR_FLAG: + if(spi_x->sts_bit.ccerr && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + case SPI_MMERR_FLAG: + if(spi_x->sts_bit.mmerr && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + case SPI_I2S_ROERR_FLAG: + if(spi_x->sts_bit.roerr && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + case SPI_CSPAS_FLAG: + if(spi_x->sts_bit.cspas && spi_x->ctrl2_bit.errie) + { + status = SET; + } + break; + default: + break; + }; + return status; +} + + +/** + * @brief clear flag of the specified spi/i2s peripheral. + * @param spi_x: select the spi/i2s peripheral. + * this parameter can be one of the following values: + * SPI1, SPI2, SPI3 + * @param spi_i2s_flag: select the spi/i2s flag + * this parameter can be one of the following values: + * - SPI_CCERR_FLAG + * - SPI_I2S_RDBF_FLAG + * - I2S_TUERR_FLAG + * - SPI_MMERR_FLAG + * - SPI_I2S_ROERR_FLAG + * - SPI_CSPAS_FLAG + * @note + * SPI_I2S_TDBE_FLAG this flag is cleared when the tx buffer already contain data to be transmit. + * I2S_ACS_FLAG this flag cann't cleared by software,the flag indicate the channel side(not use in pcm standard mode). + * SPI_I2S_BF_FLAG this flag cann't cleared by software, it's set and cleared by hardware. + * @retval none + */ +void spi_i2s_flag_clear(spi_type* spi_x, uint32_t spi_i2s_flag) +{ + if(spi_i2s_flag == SPI_CCERR_FLAG) + spi_x->sts = ~SPI_CCERR_FLAG; + else if(spi_i2s_flag == SPI_I2S_RDBF_FLAG) + UNUSED(spi_x->dt); + else if(spi_i2s_flag == I2S_TUERR_FLAG) + UNUSED(spi_x->sts); + else if(spi_i2s_flag == SPI_CSPAS_FLAG) + UNUSED(spi_x->sts); + else if(spi_i2s_flag == SPI_MMERR_FLAG) + { + UNUSED(spi_x->sts); + spi_x->ctrl1 = spi_x->ctrl1; + } + else if(spi_i2s_flag == SPI_I2S_ROERR_FLAG) + { + UNUSED(spi_x->dt); + UNUSED(spi_x->sts); + } +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_tmr.c b/libraries/drivers/src/at32f425_tmr.c new file mode 100644 index 0000000..0f6f157 --- /dev/null +++ b/libraries/drivers/src/at32f425_tmr.c @@ -0,0 +1,1758 @@ +/** + ************************************************************************** + * @file at32f425_tmr.c + * @brief contains all the functions for the tmr firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup TMR + * @brief TMR driver modules + * @{ + */ + +#ifdef TMR_MODULE_ENABLED + +/** @defgroup TMR_private_functions + * @{ + */ + +/** + * @brief tmr reset by crm reset register + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @retval none + */ +void tmr_reset(tmr_type *tmr_x) +{ + if(tmr_x == TMR1) + { + crm_periph_reset(CRM_TMR1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR1_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR2) + { + crm_periph_reset(CRM_TMR2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR2_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR3) + { + crm_periph_reset(CRM_TMR3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR3_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR6) + { + crm_periph_reset(CRM_TMR6_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR6_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR14) + { + crm_periph_reset(CRM_TMR14_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR14_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR15) + { + crm_periph_reset(CRM_TMR15_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR15_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR16) + { + crm_periph_reset(CRM_TMR16_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR16_PERIPH_RESET, FALSE); + } + else if(tmr_x == TMR17) + { + crm_periph_reset(CRM_TMR17_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_TMR17_PERIPH_RESET, FALSE); + } + +} + +/** + * @brief enable or disable tmr counter + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_counter_enable(tmr_type *tmr_x, confirm_state new_state) +{ + /* tmr counter enable */ + tmr_x->ctrl1_bit.tmren = new_state; +} + +/** + * @brief init tmr output default para + * @param tmr_output_struct + * - to the structure of tmr_output_config_type + * @retval none + */ +void tmr_output_default_para_init(tmr_output_config_type *tmr_output_struct) +{ + tmr_output_struct->oc_mode = TMR_OUTPUT_CONTROL_OFF; + tmr_output_struct->oc_idle_state = FALSE; + tmr_output_struct->occ_idle_state = FALSE; + tmr_output_struct->oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct->occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct->oc_output_state = FALSE; + tmr_output_struct->occ_output_state = FALSE; +} + +/** + * @brief init tmr input default para + * @param tmr_input_struct + * - to the structure of tmr_input_config_type + * @retval none + */ +void tmr_input_default_para_init(tmr_input_config_type *tmr_input_struct) +{ + tmr_input_struct->input_channel_select = TMR_SELECT_CHANNEL_1; + tmr_input_struct->input_polarity_select = TMR_INPUT_RISING_EDGE; + tmr_input_struct->input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT; + tmr_input_struct->input_filter_value = 0x0; +} + +/** + * @brief init tmr brkdt default para + * @param tmr_brkdt_struct + * - to the structure of tmr_brkdt_config_type + * @retval none + */ +void tmr_brkdt_default_para_init(tmr_brkdt_config_type *tmr_brkdt_struct) +{ + tmr_brkdt_struct->deadtime = 0x0; + tmr_brkdt_struct->brk_polarity = TMR_BRK_INPUT_ACTIVE_LOW; + tmr_brkdt_struct->wp_level = TMR_WP_OFF; + tmr_brkdt_struct->auto_output_enable = FALSE ; + tmr_brkdt_struct->fcsoen_state = FALSE ; + tmr_brkdt_struct->fcsodis_state = FALSE ; + tmr_brkdt_struct->brk_enable = FALSE ; +} + +/** + * @brief init tmr base + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_pr (0x0000~0xFFFF) + * @param tmr_div (timer div value:0x0000~0xFFFF) + * @retval none + */ +void tmr_base_init(tmr_type* tmr_x, uint32_t tmr_pr, uint32_t tmr_div) +{ + /* set the pr value */ + tmr_x->pr = tmr_pr; + + /* set the div value */ + tmr_x->div = tmr_div; + + /* trigger the overflow event to immediately reload pr value and div value */ + tmr_x->swevt_bit.ovfswtr = TRUE; +} + +/** + * @brief set tmr clock source division + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_clock_div + * this parameter can be one of the following values: + * - TMR_CLOCK_DIV1 + * - TMR_CLOCK_DIV2 + * - TMR_CLOCK_DIV4 + * @retval none + */ +void tmr_clock_source_div_set(tmr_type *tmr_x, tmr_clock_division_type tmr_clock_div) +{ + /* set tmr clock source division */ + tmr_x->ctrl1_bit.clkdiv = tmr_clock_div; +} + +/** + * @brief set tmr counter count direction + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3 + * @param tmr_cnt_dir + * this parameter can be one of the following values: + * - TMR_COUNT_UP + * - TMR_COUNT_DOWN + * - TMR_COUNT_TWO_WAY_1 + * - TMR_COUNT_TWO_WAY_2 + * - TMR_COUNT_TWO_WAY_3 + * @retval none + */ +void tmr_cnt_dir_set(tmr_type *tmr_x, tmr_count_mode_type tmr_cnt_dir) +{ + /* set the cnt direct */ + tmr_x->ctrl1_bit.cnt_dir = tmr_cnt_dir; +} + +/** + * @brief set the repetition counter register(rpr) value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR15, TMR16, TMR17 + * @param tmr_rpr_value (0x00~0xFF) + * @retval none + */ +void tmr_repetition_counter_set(tmr_type *tmr_x, uint8_t tmr_rpr_value) +{ + /* set the repetition counter value */ + tmr_x->rpr_bit.rpr = tmr_rpr_value; +} + +/** + * @brief set tmr counter value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_cnt_value (0x0000~0xFFFF) + * @retval none + */ +void tmr_counter_value_set(tmr_type *tmr_x, uint32_t tmr_cnt_value) +{ + /* set the tmr counter value */ + tmr_x->cval = tmr_cnt_value; +} + +/** + * @brief get tmr counter value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @retval tmr counter value + */ +uint32_t tmr_counter_value_get(tmr_type *tmr_x) +{ + return tmr_x->cval; +} + +/** + * @brief set tmr div value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_div_value (0x0000~0xFFFF) + * @retval none + */ +void tmr_div_value_set(tmr_type *tmr_x, uint32_t tmr_div_value) +{ + /* set the tmr div value */ + tmr_x->div = tmr_div_value; +} + +/** + * @brief get tmr div value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @retval tmr div value + */ +uint32_t tmr_div_value_get(tmr_type *tmr_x) +{ + return tmr_x->div; +} + +/** + * @brief config tmr output channel + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @param tmr_output_struct + * - to the structure of tmr_output_config_type + * @retval none + */ +void tmr_output_channel_config(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_output_config_type *tmr_output_struct) +{ +uint16_t channel_index = 0, channel_c_index = 0, channel = 0, chx_offset, chcx_offset; + + chx_offset = (8 + tmr_channel); + chcx_offset = (9 + tmr_channel); + + /* get channel idle state bit position in ctrl2 register */ + channel_index = (uint16_t)(tmr_output_struct->oc_idle_state << chx_offset); + + /* get channel complementary idle state bit position in ctrl2 register */ + channel_c_index = (uint16_t)(tmr_output_struct->occ_idle_state << chcx_offset); + + /* set output channel complementary idle state */ + tmr_x->ctrl2 &= ~(1<ctrl2 |= channel_c_index; + + /* set output channel idle state */ + tmr_x->ctrl2 &= ~(1<ctrl2 |= channel_index; + + /* set channel output mode */ + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1octrl = tmr_output_struct->oc_mode; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2octrl = tmr_output_struct->oc_mode; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3octrl = tmr_output_struct->oc_mode; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4octrl = tmr_output_struct->oc_mode; + break; + + default: + break; + } + + chx_offset = ((tmr_channel * 2) + 1); + chcx_offset = ((tmr_channel * 2) + 3); + + /* get channel polarity bit position in cctrl register */ + channel_index = (uint16_t)(tmr_output_struct->oc_polarity << chx_offset); + + /* get channel complementary polarity bit position in cctrl register */ + channel_c_index = (uint16_t)(tmr_output_struct->occ_polarity << chcx_offset); + + /* set output channel complementary polarity */ + tmr_x->cctrl &= ~(1<cctrl |= channel_c_index; + + /* set output channel polarity */ + tmr_x->cctrl &= ~(1<cctrl |= channel_index; + + chx_offset = (tmr_channel * 2); + chcx_offset = ((tmr_channel * 2) + 2); + + /* get channel enable bit position in cctrl register */ + channel_index = (uint16_t)(tmr_output_struct->oc_output_state << (tmr_channel * 2)); + + /* get channel complementary enable bit position in cctrl register */ + channel_c_index = (uint16_t)(tmr_output_struct->occ_output_state << ((tmr_channel * 2) + 2)); + + /* set output channel complementary enable bit */ + tmr_x->cctrl &= ~(1<cctrl |= channel_c_index; + + /* set output channel enable bit */ + tmr_x->cctrl &= ~(1<cctrl |= channel_index; +} + +/** + * @brief select tmr output channel mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @param oc_mode + * this parameter can be one of the following values: + * - TMR_OUTPUT_CONTROL_OFF + * - TMR_OUTPUT_CONTROL_HIGH + * - TMR_OUTPUT_CONTROL_LOW + * - TMR_OUTPUT_CONTROL_SWITCH + * - TMR_OUTPUT_CONTROL_FORCE_HIGH + * - TMR_OUTPUT_CONTROL_FORCE_LOW + * - TMR_OUTPUT_CONTROL_PWM_MODE_A + * - TMR_OUTPUT_CONTROL_PWM_MODE_B + * @retval none + */ +void tmr_output_channel_mode_select(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_output_control_mode_type oc_mode) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1octrl = oc_mode; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2octrl = oc_mode; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3octrl = oc_mode; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4octrl = oc_mode; + break; + + default: + break; + } +} +/** + * @brief set tmr period value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_pr_value: timer period register value of counter (0x0000~0xFFFF) + * @retval none + */ +void tmr_period_value_set(tmr_type *tmr_x, uint32_t tmr_pr_value) +{ + /* set tmr period value */ + tmr_x->pr = tmr_pr_value; +} + +/** + * @brief get tmr period value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @retval timer period register value of counter(0x0000~0xFFFFF) + */ +uint32_t tmr_period_value_get(tmr_type *tmr_x) +{ + return tmr_x->pr; +} + +/** + * @brief set tmr channel value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @param tmr_channel_value (0x0000~0xFFFF) + * @retval none + */ +void tmr_channel_value_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + uint32_t tmr_channel_value) +{ + uint16_t channel; + + channel = tmr_channel; + + /* set tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->c1dt = tmr_channel_value; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->c2dt = tmr_channel_value; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->c3dt = tmr_channel_value; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->c4dt = tmr_channel_value; + break; + + default: + break; + } +} + +/** + * @brief get tmr channel value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @retval tmr channel value + */ +uint32_t tmr_channel_value_get(tmr_type *tmr_x, tmr_channel_select_type tmr_channel) +{ + uint32_t cc_value_get = 0; + uint16_t channel; + + channel = tmr_channel; + + /* get tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + cc_value_get = tmr_x->c1dt; + break; + + case TMR_SELECT_CHANNEL_2: + cc_value_get = tmr_x->c2dt; + break; + + case TMR_SELECT_CHANNEL_3: + cc_value_get = tmr_x->c3dt; + break; + + case TMR_SELECT_CHANNEL_4: + cc_value_get = tmr_x->c4dt; + break; + + default: + break; + } + + return cc_value_get; +} +/** + * @brief enable tmr period buffer + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_period_buffer_enable(tmr_type *tmr_x, confirm_state new_state) +{ + /* tmr period buffer set */ + tmr_x->ctrl1_bit.prben = new_state; +} + +/** + * @brief enable tmr output channel buffer + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_output_channel_buffer_enable(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + confirm_state new_state) +{ + uint16_t channel; + + channel = tmr_channel; + + /* get tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1oben = new_state; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2oben = new_state; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3oben = new_state; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4oben = new_state; + break; + + default: + break; + } +} + +/** + * @brief set tmr output channel immediately + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_output_channel_immediately_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + confirm_state new_state) +{ + uint16_t channel; + + channel = tmr_channel; + + /* get tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1oien = new_state; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2oien = new_state; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3oien = new_state; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4oien = new_state; + break; + + default: + break; + } +} + +/** + * @brief set tmr output channel switch + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_output_channel_switch_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + confirm_state new_state) +{ + uint16_t channel; + + channel = tmr_channel; + + /* get tmr channel value */ + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1osen = new_state; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2osen = new_state; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3osen = new_state; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4osen = new_state; + break; + + default: + break; + } +} + +/** + * @brief enable or disable tmr one cycle mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_one_cycle_mode_enable(tmr_type *tmr_x, confirm_state new_state) +{ + /* tmr one cycle mode enable */ + tmr_x->ctrl1_bit.ocmen = new_state; +} + +/** + * @brief enable or disable tmr 32 bit function(plus mode) + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR2 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_32_bit_function_enable (tmr_type *tmr_x, confirm_state new_state) +{ + /* tmr 32 bit function(plus mode) enable,only for TMR2 */ + if(tmr_x == TMR2) + { + tmr_x->ctrl1_bit.pmen = new_state; + } +} + +/** + * @brief select tmr the overflow event sources + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_overflow_request_source_set(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->ctrl1_bit.ovfs = new_state; +} + +/** + * @brief enable or disable tmr overflow event generation + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_overflow_event_disable(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->ctrl1_bit.ovfen = new_state; +} + +/** + * @brief init tmr input channel + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param input_struct + * - to the structure of tmr_input_config_type + * @param divider_factor + * this parameter can be one of the following values: + * - TMR_CHANNEL_INPUT_DIV_1 + * - TMR_CHANNEL_INPUT_DIV_2 + * - TMR_CHANNEL_INPUT_DIV_4 + * - TMR_CHANNEL_INPUT_DIV_8 + * @retval none + */ +void tmr_input_channel_init(tmr_type *tmr_x, tmr_input_config_type *input_struct, \ + tmr_channel_input_divider_type divider_factor) +{ + uint16_t channel = 0; + + /* get channel selected */ + channel = input_struct->input_channel_select; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cctrl_bit.c1en = FALSE; + tmr_x->cctrl_bit.c1p = (uint32_t)input_struct->input_polarity_select; + tmr_x->cctrl_bit.c1cp = (input_struct->input_polarity_select & 0x2) >> 1; + tmr_x->cm1_input_bit.c1c = input_struct->input_mapped_select; + tmr_x->cm1_input_bit.c1df = input_struct->input_filter_value; + tmr_x->cm1_input_bit.c1idiv = divider_factor; + tmr_x->cctrl_bit.c1en = TRUE; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cctrl_bit.c2en = FALSE; + tmr_x->cctrl_bit.c2p = (uint32_t)input_struct->input_polarity_select; + tmr_x->cctrl_bit.c2cp = (input_struct->input_polarity_select & 0x2) >> 1; + tmr_x->cm1_input_bit.c2c = input_struct->input_mapped_select; + tmr_x->cm1_input_bit.c2df = input_struct->input_filter_value; + tmr_x->cm1_input_bit.c2idiv = divider_factor; + tmr_x->cctrl_bit.c2en = TRUE; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cctrl_bit.c3en = FALSE; + tmr_x->cctrl_bit.c3p = (uint32_t)input_struct->input_polarity_select; + tmr_x->cctrl_bit.c3cp = (input_struct->input_polarity_select & 0x2) >> 1; + tmr_x->cm2_input_bit.c3c = input_struct->input_mapped_select; + tmr_x->cm2_input_bit.c3df = input_struct->input_filter_value; + tmr_x->cm2_input_bit.c3idiv = divider_factor; + tmr_x->cctrl_bit.c3en = TRUE; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cctrl_bit.c4en = FALSE; + tmr_x->cctrl_bit.c4p = (uint32_t)input_struct->input_polarity_select; + tmr_x->cm2_input_bit.c4c = input_struct->input_mapped_select; + tmr_x->cm2_input_bit.c4df = input_struct->input_filter_value; + tmr_x->cm2_input_bit.c4idiv = divider_factor; + tmr_x->cctrl_bit.c4en = TRUE; + break; + + default: + break; + } +} + +/** + * @brief tmr channel enable + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_1C only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_2C only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_3C only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_channel_enable(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, confirm_state new_state) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cctrl_bit.c1en = new_state; + break; + + case TMR_SELECT_CHANNEL_1C: + tmr_x->cctrl_bit.c1cen = new_state; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cctrl_bit.c2en = new_state; + break; + + case TMR_SELECT_CHANNEL_2C: + tmr_x->cctrl_bit.c2cen = new_state; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cctrl_bit.c3en = new_state; + break; + + case TMR_SELECT_CHANNEL_3C: + tmr_x->cctrl_bit.c3cen = new_state; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cctrl_bit.c4en = new_state; + break; + + default: + break; + } +} + +/** + * @brief set tmr input channel filter + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR3 + * @param filter_value (0x0~0xf) + * @retval none + */ +void tmr_input_channel_filter_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + uint16_t filter_value) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_input_bit.c1df = filter_value; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_input_bit.c2df = filter_value; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_input_bit.c3df = filter_value; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_input_bit.c4df = filter_value; + break; + + default: + break; + } +} + +/** + * @brief config tmr pwm input + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15 + * @param input_struct + * - to the structure of tmr_input_config_type + * @param divider_factor + * this parameter can be one of the following values: + * - TMR_CHANNEL_INPUT_DIV_1 + * - TMR_CHANNEL_INPUT_DIV_2 + * - TMR_CHANNEL_INPUT_DIV_4 + * - TMR_CHANNEL_INPUT_DIV_8 + * @retval none + */ +void tmr_pwm_input_config(tmr_type *tmr_x, tmr_input_config_type *input_struct, \ + tmr_channel_input_divider_type divider_factor) +{ + uint16_t channel = 0; + + /* get channel selected */ + channel = input_struct->input_channel_select; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + if(input_struct->input_polarity_select == TMR_INPUT_RISING_EDGE) + { + /* set channel polarity */ + tmr_x->cctrl_bit.c1p = TMR_INPUT_RISING_EDGE; + tmr_x->cctrl_bit.c2p = TMR_INPUT_FALLING_EDGE; + } + else if(input_struct->input_polarity_select == TMR_INPUT_FALLING_EDGE) + { + /* set channel polarity */ + tmr_x->cctrl_bit.c1p = TMR_INPUT_FALLING_EDGE; + tmr_x->cctrl_bit.c2p = TMR_INPUT_RISING_EDGE; + } + + if(input_struct->input_mapped_select == TMR_CC_CHANNEL_MAPPED_DIRECT) + { + /* ic1 is mapped on ti1 */ + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_DIRECT; + + /* ic1 is mapped on ti2 */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_INDIRECT; + } + else if(input_struct->input_mapped_select == TMR_CC_CHANNEL_MAPPED_INDIRECT) + { + /* ic1 is mapped on ti1 */ + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_INDIRECT; + + /* ic1 is mapped on ti2 */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_DIRECT; + } + + /* set input ch1 and ch2 filter value*/ + tmr_x->cm1_input_bit.c1df = input_struct->input_filter_value; + tmr_x->cm1_input_bit.c2df = input_struct->input_filter_value; + + /*set input ch1 and ch2 divider value*/ + tmr_x->cm1_input_bit.c1idiv = divider_factor; + tmr_x->cm1_input_bit.c2idiv = divider_factor; + + tmr_x->cctrl_bit.c1en = TRUE; + tmr_x->cctrl_bit.c2en = TRUE; + break; + + case TMR_SELECT_CHANNEL_2: + if(input_struct->input_polarity_select == TMR_INPUT_RISING_EDGE) + { + /* set channel polarity */ + tmr_x->cctrl_bit.c2p = TMR_INPUT_RISING_EDGE; + tmr_x->cctrl_bit.c1p = TMR_INPUT_FALLING_EDGE; + } + else if(input_struct->input_polarity_select == TMR_INPUT_FALLING_EDGE) + { + /* set channel polarity */ + tmr_x->cctrl_bit.c2p = TMR_INPUT_FALLING_EDGE; + tmr_x->cctrl_bit.c1p = TMR_INPUT_RISING_EDGE; + } + + if(input_struct->input_mapped_select == TMR_CC_CHANNEL_MAPPED_DIRECT) + { + /* set mapped direct */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_DIRECT; + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_INDIRECT; + } + else if(input_struct->input_mapped_select == TMR_CC_CHANNEL_MAPPED_INDIRECT) + { + /* set mapped direct */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_INDIRECT; + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_DIRECT; + } + + /* set input ch1 and ch2 filter value*/ + tmr_x->cm1_input_bit.c1df = input_struct->input_filter_value; + tmr_x->cm1_input_bit.c2df = input_struct->input_filter_value; + + /*set input ch1 and ch2 divider value*/ + tmr_x->cm1_input_bit.c1idiv = divider_factor; + tmr_x->cm1_input_bit.c2idiv = divider_factor; + + tmr_x->cctrl_bit.c1en = TRUE; + tmr_x->cctrl_bit.c2en = TRUE; + break; + + default: + break; + } +} + +/** + * @brief select tmr channel1 input + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15 + * @param ch1_connect + * this parameter can be one of the following values: + * - TMR_CHANEL1_CONNECTED_C1IRAW + * - TMR_CHANEL1_2_3_CONNECTED_C1IRAW_XOR + * @retval none + */ +void tmr_channel1_input_select(tmr_type *tmr_x, tmr_channel1_input_connected_type ch1_connect) +{ + tmr_x->ctrl2_bit.c1insel = ch1_connect; +} + +/** + * @brief set tmr input channel divider + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 only available for TMR1, TMR2, TMR3, TMR14, TMR15, TMR16, TMR17 + * - TMR_SELECT_CHANNEL_2 only available for TMR1, TMR2, TMR3, TMR15 + * - TMR_SELECT_CHANNEL_3 only available for TMR1, TMR2, TMR3 + * - TMR_SELECT_CHANNEL_4 only available for TMR1, TMR2, TMR3 + * @param divider_factor + * this parameter can be one of the following values: + * - TMR_CHANNEL_INPUT_DIV_1 + * - TMR_CHANNEL_INPUT_DIV_2 + * - TMR_CHANNEL_INPUT_DIV_4 + * - TMR_CHANNEL_INPUT_DIV_8 + * @retval none + */ +void tmr_input_channel_divider_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_channel_input_divider_type divider_factor) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_input_bit.c1idiv = divider_factor; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_input_bit.c2idiv = divider_factor; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_input_bit.c3idiv = divider_factor; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_input_bit.c4idiv = divider_factor; + break; + + default: + break; + } +} + +/** + * @brief select tmr primary mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR15 + * @param primary_mode + * this parameter can be one of the following values: + * - TMR_PRIMARY_SEL_RESET + * - TMR_PRIMARY_SEL_ENABLE + * - TMR_PRIMARY_SEL_OVERFLOW + * - TMR_PRIMARY_SEL_COMPARE + * - TMR_PRIMARY_SEL_C1ORAW + * - TMR_PRIMARY_SEL_C2ORAW + * - TMR_PRIMARY_SEL_C3ORAW + * - TMR_PRIMARY_SEL_C4ORAW + * @retval none + */ +void tmr_primary_mode_select(tmr_type *tmr_x, tmr_primary_select_type primary_mode) +{ + tmr_x->ctrl2_bit.ptos = primary_mode; +} + +/** + * @brief select tmr subordinate mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15, + * @param sub_mode + * this parameter can be one of the following values: + * - TMR_SUB_MODE_DIABLE + * - TMR_SUB_ENCODER_MODE_A + * - TMR_SUB_ENCODER_MODE_B + * - TMR_SUB_ENCODER_MODE_C + * - TMR_SUB_RESET_MODE + * - TMR_SUB_HANG_MODE + * - TMR_SUB_TRIGGER_MODE + * - TMR_SUB_EXTERNAL_CLOCK_MODE_A + * @retval none + */ +void tmr_sub_mode_select(tmr_type *tmr_x, tmr_sub_mode_select_type sub_mode) +{ + tmr_x->stctrl_bit.smsel = sub_mode; +} + +/** + * @brief select tmr channel dma + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15, TMR16, TMR17 + * @param cc_dma_select + * this parameter can be one of the following values: + * - TMR_DMA_REQUEST_BY_CHANNEL + * - TMR_DMA_REQUEST_BY_OVERFLOW + * @retval none + */ +void tmr_channel_dma_select(tmr_type *tmr_x, tmr_dma_request_source_type cc_dma_select) +{ + tmr_x->ctrl2_bit.drs = cc_dma_select; +} + +/** + * @brief select tmr hall + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR15, TMR16, TMR17 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_hall_select(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->ctrl2_bit.ccfs = new_state; +} + +/** + * @brief enbale tmr channel buffer + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR15, TMR16, TMR17 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_channel_buffer_enable(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->ctrl2_bit.cbctrl = new_state; +} + +/** + * @brief select tmr sub-trigger + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15 + * @param trigger_select + * this parameter can be one of the following values: + * - TMR_SUB_INPUT_SEL_IS0 + * - TMR_SUB_INPUT_SEL_IS1 + * - TMR_SUB_INPUT_SEL_IS2 + * - TMR_SUB_INPUT_SEL_IS3 + * - TMR_SUB_INPUT_SEL_C1INC + * - TMR_SUB_INPUT_SEL_C1DF1 + * - TMR_SUB_INPUT_SEL_C2DF2 + * - TMR_SUB_INPUT_SEL_EXTIN + * @retval none + */ +void tmr_trigger_input_select(tmr_type *tmr_x, sub_tmr_input_sel_type trigger_select) +{ + tmr_x->stctrl_bit.stis = trigger_select; +} + +/** + * @brief set tmr subordinate synchronization mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_sub_sync_mode_set(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->stctrl_bit.sts = new_state; +} + +/** + * @brief enable or disable tmr dma request + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR15, TMR16, TMR17 + * @param dma_request + * this parameter can be one of the following values: + * - TMR_OVERFLOW_DMA_REQUEST + * - TMR_C1_DMA_REQUEST + * - TMR_C2_DMA_REQUEST + * - TMR_C3_DMA_REQUEST + * - TMR_C4_DMA_REQUEST + * - TMR_HALL_DMA_REQUEST + * - TMR_TRIGGER_DMA_REQUEST + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_dma_request_enable(tmr_type *tmr_x, tmr_dma_request_type dma_request, confirm_state new_state) +{ + if(new_state == TRUE) + { + tmr_x->iden |= dma_request; + } + else if(new_state == FALSE) + { + tmr_x->iden &= ~dma_request; + } +} + +/** + * @brief enable or disable tmr interrupt + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_interrupt + * this parameter can be one of the following values: + * - TMR_OVF_INT + * - TMR_C1_INT + * - TMR_C2_INT + * - TMR_C3_INT + * - TMR_C4_INT + * - TMR_HALL_INT + * - TMR_TRIGGER_INT + * - TMR_BRK_INT + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_interrupt_enable(tmr_type *tmr_x, uint32_t tmr_interrupt, confirm_state new_state) +{ + if(new_state == TRUE) + { + tmr_x->iden |= tmr_interrupt; + } + else if(new_state == FALSE) + { + tmr_x->iden &= ~tmr_interrupt; + } +} + +/** + * @brief get tmr interrupt flag + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, + * TMR16, TMR17 + * @param tmr_flag + * this parameter can be one of the following values: + * - TMR_OVF_FLAG + * - TMR_C1_FLAG + * - TMR_C2_FLAG + * - TMR_C3_FLAG + * - TMR_C4_FLAG + * - TMR_HALL_FLAG + * - TMR_TRIGGER_FLAG + * - TMR_BRK_FLAG + * @retval state of tmr interrupt flag + */ +flag_status tmr_interrupt_flag_get(tmr_type *tmr_x, uint32_t tmr_flag) +{ + flag_status status = RESET; + + if((tmr_x->ists & tmr_flag) && (tmr_x->iden & tmr_flag)) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief get tmr flag + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, + * TMR16, TMR17 + * @param tmr_flag + * this parameter can be one of the following values: + * - TMR_OVF_FLAG + * - TMR_C1_FLAG + * - TMR_C2_FLAG + * - TMR_C3_FLAG + * - TMR_C4_FLAG + * - TMR_HALL_FLAG + * - TMR_TRIGGER_FLAG + * - TMR_BRK_FLAG + * - TMR_C1_RECAPTURE_FLAG + * - TMR_C2_RECAPTURE_FLAG + * - TMR_C3_RECAPTURE_FLAG + * - TMR_C4_RECAPTURE_FLAG + * @retval state of tmr flag + */ +flag_status tmr_flag_get(tmr_type *tmr_x, uint32_t tmr_flag) +{ + flag_status status = RESET; + + if((tmr_x->ists & tmr_flag) != RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief clear tmr flag + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, + * TMR16, TMR17 + * @param tmr_flag + * this parameter can be any combination of the following values: + * - TMR_OVF_FLAG + * - TMR_C1_FLAG + * - TMR_C2_FLAG + * - TMR_C3_FLAG + * - TMR_C4_FLAG + * - TMR_HALL_FLAG + * - TMR_TRIGGER_FLAG + * - TMR_BRK_FLAG + * - TMR_C1_RECAPTURE_FLAG + * - TMR_C2_RECAPTURE_FLAG + * - TMR_C3_RECAPTURE_FLAG + * - TMR_C4_RECAPTURE_FLAG + * @retval none + */ +void tmr_flag_clear(tmr_type *tmr_x, uint32_t tmr_flag) +{ + tmr_x->ists = ~tmr_flag; +} + +/** + * @brief generate tmr event + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR6, TMR7, TMR13, TMR14, TMR15, + * TMR16, TMR17 + * @param tmr_event + * this parameter can be one of the following values: + * - TMR_OVERFLOW_SWTRIG + * - TMR_C1_SWTRIG + * - TMR_C2_SWTRIG + * - TMR_C3_SWTRIG + * - TMR_C4_SWTRIG + * - TMR_HALL_SWTRIG + * - TMR_TRIGGER_SWTRIG + * - TMR_BRK_SWTRIG + * @retval none + */ +void tmr_event_sw_trigger(tmr_type *tmr_x, tmr_event_trigger_type tmr_event) +{ + tmr_x->swevt |= tmr_event; +} + +/** + * @brief tmr output enable(oen),this function is important for advtm output enable + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR15, TMR16, TMR17 + * @param new_state (TRUE or FALSE) + * @retval none + */ +void tmr_output_enable(tmr_type *tmr_x, confirm_state new_state) +{ + tmr_x->brk_bit.oen = new_state; +} + +/** + * @brief set tmr select internal clock + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15 + * @retval none + */ +void tmr_internal_clock_set(tmr_type *tmr_x) +{ + tmr_x->stctrl_bit.smsel = TMR_SUB_MODE_DIABLE; +} + +/** + * @brief set tmr output channel polarity + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * - TMR_SELECT_CHANNEL_1C + * - TMR_SELECT_CHANNEL_2C + * - TMR_SELECT_CHANNEL_3C + * @param oc_polarity + * this parameter can be one of the following values: + * - TMR_POLARITY_ACTIVE_HIGH + * - TMR_POLARITY_ACTIVE_LOW + * @retval none + */ +void tmr_output_channel_polarity_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_polarity_active_type oc_polarity) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cctrl_bit.c1p = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cctrl_bit.c2p = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cctrl_bit.c3p = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cctrl_bit.c4p = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_1C: + tmr_x->cctrl_bit.c1cp = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_2C: + tmr_x->cctrl_bit.c2cp = (uint32_t)oc_polarity; + break; + + case TMR_SELECT_CHANNEL_3C: + tmr_x->cctrl_bit.c3cp = (uint32_t)oc_polarity; + break; + + default: + break; + } +} + +/** + * @brief config tmr external clock + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3 + * @param es_divide + * this parameter can be one of the following values: + * - TMR_ES_FREQUENCY_DIV_1 + * - TMR_ES_FREQUENCY_DIV_2 + * - TMR_ES_FREQUENCY_DIV_4 + * - TMR_ES_FREQUENCY_DIV_8 + * @param es_polarity + * this parameter can be one of the following values: + * - TMR_ES_POLARITY_NON_INVERTED + * - TMR_ES_POLARITY_INVERTED + * @param es_filter (0x0~0xf) + * @retval none + */ +void tmr_external_clock_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, \ + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter) +{ + tmr_x->stctrl_bit.esdiv = es_divide; + tmr_x->stctrl_bit.esp = es_polarity; + tmr_x->stctrl_bit.esf = es_filter; +} + +/** + * @brief config tmr external clock mode1 + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15 + * @param es_divide + * this parameter can be one of the following values: + * - TMR_ES_FREQUENCY_DIV_1 + * - TMR_ES_FREQUENCY_DIV_2 + * - TMR_ES_FREQUENCY_DIV_4 + * - TMR_ES_FREQUENCY_DIV_8 + * @param es_polarity + * this parameter can be one of the following values: + * - TMR_ES_POLARITY_NON_INVERTED + * - TMR_ES_POLARITY_INVERTED + * @param es_filter (0x0~0xf) + * @retval none + */ +void tmr_external_clock_mode1_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, \ + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter) +{ + tmr_external_clock_config(tmr_x, es_divide, es_polarity, es_filter); + tmr_x->stctrl_bit.smsel = TMR_SUB_EXTERNAL_CLOCK_MODE_A; + tmr_x->stctrl_bit.stis = TMR_SUB_INPUT_SEL_EXTIN; +} + +/** + * @brief config tmr external clock mode2 + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3 + * @param es_divide + * this parameter can be one of the following values: + * - TMR_ES_FREQUENCY_DIV_1 + * - TMR_ES_FREQUENCY_DIV_2 + * - TMR_ES_FREQUENCY_DIV_4 + * - TMR_ES_FREQUENCY_DIV_8 + * @param es_polarity + * this parameter can be one of the following values: + * - TMR_ES_POLARITY_NON_INVERTED + * - TMR_ES_POLARITY_INVERTED + * @param es_filter (0x0~0xf) + * @retval none + */ +void tmr_external_clock_mode2_config(tmr_type *tmr_x, tmr_external_signal_divider_type es_divide, \ + tmr_external_signal_polarity_type es_polarity, uint16_t es_filter) +{ + tmr_external_clock_config(tmr_x, es_divide, es_polarity, es_filter); + tmr_x->stctrl_bit.ecmben = TRUE; +} + +/** + * @brief config tmr encoder mode + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3 + * @param encoder_mode + * this parameter can be one of the following values: + * - TMR_ENCODER_MODE_A + * - TMR_ENCODER_MODE_B + * - TMR_ENCODER_MODE_C + * @param ic1_polarity + * this parameter can be one of the following values: + * - TMR_INPUT_RISING_EDGE + * - TMR_INPUT_FALLING_EDGE + * - TMR_INPUT_BOTH_EDGE + * @param ic2_polarity + * this parameter can be one of the following values: + * - TMR_INPUT_RISING_EDGE + * - TMR_INPUT_FALLING_EDGE + * - TMR_INPUT_BOTH_EDGE + * @retval none + */ +void tmr_encoder_mode_config(tmr_type *tmr_x, tmr_encoder_mode_type encoder_mode, tmr_input_polarity_type \ + ic1_polarity, tmr_input_polarity_type ic2_polarity) +{ + tmr_x->stctrl_bit.smsel = encoder_mode; + + /* set ic1 polarity */ + tmr_x->cctrl_bit.c1p = (ic1_polarity & 0x1); + tmr_x->cctrl_bit.c1cp = (ic1_polarity >> 1); + /* set ic1 as input channel */ + tmr_x->cm1_input_bit.c1c = TMR_CC_CHANNEL_MAPPED_DIRECT; + + /* set ic2 polarity */ + tmr_x->cctrl_bit.c2p = (ic2_polarity & 0x1); + tmr_x->cctrl_bit.c2cp = (ic2_polarity >> 1); + /* set ic2 as input channel */ + tmr_x->cm1_input_bit.c2c = TMR_CC_CHANNEL_MAPPED_DIRECT; +} + +/** + * @brief set tmr force output + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR13, TMR14, TMR15, TMR16, TMR17 + * @param tmr_channel + * this parameter can be one of the following values: + * - TMR_SELECT_CHANNEL_1 + * - TMR_SELECT_CHANNEL_2 + * - TMR_SELECT_CHANNEL_3 + * - TMR_SELECT_CHANNEL_4 + * @param force_output + * this parameter can be one of the following values: + * - TMR_FORCE_OUTPUT_HIGH + * - TMR_FORCE_OUTPUT_LOW + * @retval none + */ +void tmr_force_output_set(tmr_type *tmr_x, tmr_channel_select_type tmr_channel, \ + tmr_force_output_type force_output) +{ + uint16_t channel; + + channel = tmr_channel; + + switch(channel) + { + case TMR_SELECT_CHANNEL_1: + tmr_x->cm1_output_bit.c1octrl = force_output; + break; + + case TMR_SELECT_CHANNEL_2: + tmr_x->cm1_output_bit.c2octrl = force_output; + break; + + case TMR_SELECT_CHANNEL_3: + tmr_x->cm2_output_bit.c3octrl = force_output; + break; + + case TMR_SELECT_CHANNEL_4: + tmr_x->cm2_output_bit.c4octrl = force_output; + break; + + default: + break; + } +} + +/** + * @brief config tmr dma control + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR2, TMR3, TMR15, TMR16, TMR17 + * @param dma_length + * this parameter can be one of the following values: + * - TMR_DMA_TRANSFER_1BYTE + * - TMR_DMA_TRANSFER_2BYTES + * - TMR_DMA_TRANSFER_3BYTES + * ... + * - TMR_DMA_TRANSFER_17BYTES + * - TMR_DMA_TRANSFER_18BYTES + * @param dma_base_address + * this parameter can be one of the following values: + * - TMR_CTRL1_ADDRESS + * - TMR_CTRL2_ADDRESS + * - TMR_STCTRL_ADDRESS + * - TMR_IDEN_ADDRESS + * - TMR_ISTS_ADDRESS + * - TMR_SWEVT_ADDRESS + * - TMR_CM1_ADDRESS + * - TMR_CM2_ADDRESS + * - TMR_CCTRL_ADDRESS + * - TMR_CVAL_ADDRESS + * - TMR_DIV_ADDRESS + * - TMR_PR_ADDRESS + * - TMR_RPR_ADDRESS + * - TMR_C1DT_ADDRESS + * - TMR_C2DT_ADDRESS + * - TMR_C3DT_ADDRESS + * - TMR_C4DT_ADDRESS + * - TMR_BRK_ADDRESS + * - TMR_DMACTRL_ADDRESS + * @retval none + */ +void tmr_dma_control_config(tmr_type *tmr_x, tmr_dma_transfer_length_type dma_length, \ + tmr_dma_address_type dma_base_address) +{ + tmr_x->dmactrl_bit.dtb = dma_length; + tmr_x->dmactrl_bit.addr = dma_base_address; +} + +/** + * @brief config tmr brake mode and dead-time + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR15, TMR16, TMR17 + * @param brkdt_struct + * - to the structure of tmr_brkdt_config_type + * @retval none + */ +void tmr_brkdt_config(tmr_type *tmr_x, tmr_brkdt_config_type *brkdt_struct) +{ + tmr_x->brk_bit.brken = brkdt_struct->brk_enable; + tmr_x->brk_bit.dtc = brkdt_struct->deadtime; + tmr_x->brk_bit.fcsodis = brkdt_struct->fcsodis_state; + tmr_x->brk_bit.fcsoen = brkdt_struct->fcsoen_state; + tmr_x->brk_bit.brkv = brkdt_struct->brk_polarity; + tmr_x->brk_bit.aoen = brkdt_struct->auto_output_enable; + tmr_x->brk_bit.wpc = brkdt_struct->wp_level; +} + +/** + * @brief set tmr break input filter value + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR1, TMR15, TMR16, TMR17 + * @param filter_value (0x0~0xf) + * @retval none + */ +void tmr_brk_filter_value_set(tmr_type *tmr_x, uint8_t filter_value) +{ + tmr_x->brk_bit.bkf = filter_value; +} + +/** + * @brief set tmr14 input channel remap + * @param tmr_x: select the tmr peripheral. + * this parameter can be one of the following values: + * TMR14 + * @param input_remap + * - TMR14_GPIO + * - TMR14_ERTCCLK + * - TMR14_HEXT_DIV32 + * - TMR14_CLKOUT + * @retval none + */ +void tmr_iremap_config(tmr_type *tmr_x, tmr_input_remap_type input_remap) +{ + tmr_x->rmp_bit.tmr14_ch1_irmp = input_remap; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_usart.c b/libraries/drivers/src/at32f425_usart.c new file mode 100644 index 0000000..e60dd06 --- /dev/null +++ b/libraries/drivers/src/at32f425_usart.c @@ -0,0 +1,780 @@ +/** + ************************************************************************** + * @file at32f425_usart.c + * @brief contains all the functions for the usart firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/* includes ------------------------------------------------------------------*/ +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup USART + * @brief USART driver modules + * @{ + */ + +#ifdef USART_MODULE_ENABLED + +/** @defgroup USART_private_functions + * @{ + */ + +/** + * @brief deinitialize the usart peripheral registers to their default reset values. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @retval none + */ +void usart_reset(usart_type* usart_x) +{ + if(usart_x == USART1) + { + crm_periph_reset(CRM_USART1_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_USART1_PERIPH_RESET, FALSE); + } + else if(usart_x == USART2) + { + crm_periph_reset(CRM_USART2_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_USART2_PERIPH_RESET, FALSE); + } + else if(usart_x == USART3) + { + crm_periph_reset(CRM_USART3_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_USART3_PERIPH_RESET, FALSE); + } + else if(usart_x == USART4) + { + crm_periph_reset(CRM_USART4_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_USART4_PERIPH_RESET, FALSE); + } +} + +/** + * @brief initialize the usart peripheral according to the specified parameters. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param baud_rate: configure the usart communication baud rate. + * @param data_bit: data bits transmitted or received in a frame + * this parameter can be one of the following values: + * - USART_DATA_7BITS + * - USART_DATA_8BITS + * - USART_DATA_9BITS. + * note: + * - when parity check is disabled, the data bit width is the actual data bit number. + * - when parity check is enabled, the data bit width is the actual data bit number minus 1, and the MSB bit is replaced with the parity bit. + * @param stop_bit: stop bits transmitted + * this parameter can be one of the following values: + * - USART_STOP_1_BIT + * - USART_STOP_0_5_BIT. + * - USART_STOP_2_BIT + * - USART_STOP_1_5_BIT. + * @retval none + */ +void usart_init(usart_type* usart_x, uint32_t baud_rate, usart_data_bit_num_type data_bit, usart_stop_bit_num_type stop_bit) +{ + crm_clocks_freq_type clocks_freq; + uint32_t apb_clock, temp_val; + crm_clocks_freq_get(&clocks_freq); + if(usart_x == USART1) + { + apb_clock = clocks_freq.apb2_freq; + } + else + { + apb_clock = clocks_freq.apb1_freq; + } + temp_val = (apb_clock * 10 / baud_rate); + if((temp_val % 10) < 5) + { + temp_val = (temp_val / 10); + } + else + { + temp_val = (temp_val / 10) + 1; + } + usart_x->baudr_bit.div = temp_val; + if(data_bit == USART_DATA_7BITS) + { + usart_x->ctrl1_bit.dbn_h = 1; + usart_x->ctrl1_bit.dbn_l = 0; + } + else if(data_bit == USART_DATA_8BITS) + { + usart_x->ctrl1_bit.dbn_h = 0; + usart_x->ctrl1_bit.dbn_l = 0; + } + else + { + usart_x->ctrl1_bit.dbn_h = 0; + usart_x->ctrl1_bit.dbn_l = 1; + } + usart_x->ctrl2_bit.stopbn = stop_bit; +} + +/** + * @brief usart parity selection config. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param parity: select the none, odd or even parity. + * this parameter can be one of the following values: + * - USART_PARITY_NONE + * - USART_PARITY_EVEN. + * - USART_PARITY_ODD + * @retval none + */ +void usart_parity_selection_config(usart_type* usart_x, usart_parity_selection_type parity) +{ + if(parity == USART_PARITY_NONE) + { + usart_x->ctrl1_bit.psel = FALSE; + usart_x->ctrl1_bit.pen = FALSE; + } + else if(parity == USART_PARITY_EVEN) + { + usart_x->ctrl1_bit.psel = FALSE; + usart_x->ctrl1_bit.pen = TRUE; + } + else if(parity == USART_PARITY_ODD) + { + usart_x->ctrl1_bit.psel = TRUE; + usart_x->ctrl1_bit.pen = TRUE; + } +} + +/** + * @brief enable or disable the specified usart peripheral. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the usart peripheral. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl1_bit.uen = new_state; +} + +/** + * @brief usart transmitter enable. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void usart_transmitter_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl1_bit.ten = new_state; +} + +/** + * @brief usart receiver enable. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: TRUE or FALSE. + * @retval none + */ +void usart_receiver_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl1_bit.ren = new_state; +} + +/** + * @brief usart clock config. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param clk_pol: polarity of the clock output on the ck pin. + * this parameter can be one of the following values: + * - USART_CLOCK_POLARITY_LOW + * - USART_CLOCK_POLARITY_HIGH + * @param clk_pha: phase of the clock output on the ck pin. + * this parameter can be one of the following values: + * - USART_CLOCK_PHASE_1EDGE + * - USART_CLOCK_PHASE_2EDGE + * @param clk_lb: whether the clock pulse of the last data bit transmitted (MSB) is outputted on the ck pin. + * this parameter can be one of the following values: + * - USART_CLOCK_LAST_BIT_NONE + * - USART_CLOCK_LAST_BIT_OUTPUT + * @retval none + */ +void usart_clock_config(usart_type* usart_x, usart_clock_polarity_type clk_pol, usart_clock_phase_type clk_pha, usart_lbcp_type clk_lb) +{ + usart_x->ctrl2_bit.clkpol = clk_pol; + usart_x->ctrl2_bit.clkpha = clk_pha; + usart_x->ctrl2_bit.lbcp = clk_lb; +} + +/** + * @brief usart enable the ck pin. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: TRUE or FALSE + * @retval none + */ +void usart_clock_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl2_bit.clken = new_state; +} + +/** + * @brief enable or disable the specified usart interrupts. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param usart_int: specifies the USART interrupt sources to be enabled or disabled. + * this parameter can be one of the following values: + * - USART_IDLE_INT: idle interrupt + * - USART_RDBF_INT: rdbf interrupt + * - USART_TDC_INT: tdc interrupt + * - USART_TDBE_INT: tdbe interrupt + * - USART_PERR_INT: perr interrupt + * - USART_BF_INT: break frame interrupt + * - USART_ERR_INT: err interrupt + * - USART_CTSCF_INT: ctscf interrupt + * @param new_state: new state of the specified usart interrupts. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_interrupt_enable(usart_type* usart_x, uint32_t usart_int, confirm_state new_state) +{ + if(new_state == TRUE) + PERIPH_REG((uint32_t)usart_x, usart_int) |= PERIPH_REG_BIT(usart_int); + else + PERIPH_REG((uint32_t)usart_x, usart_int) &= ~PERIPH_REG_BIT(usart_int); +} + +/** + * @brief enable or disable the usart's dma transmitter interface. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the dma request sources. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_dma_transmitter_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.dmaten = new_state; +} + +/** + * @brief enable or disable the usart's dma receiver interface. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the dma request sources. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_dma_receiver_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.dmaren = new_state; +} + +/** + * @brief set the wakeup id of the usart. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param usart_id: the matching id(0x0~0xFF). + * @retval none + */ +void usart_wakeup_id_set(usart_type* usart_x, uint8_t usart_id) +{ + if(usart_x->ctrl2_bit.idbn == USART_ID_FIXED_4_BIT) + { + usart_x->ctrl2_bit.id_l = (usart_id & 0x0F); + usart_x->ctrl2_bit.id_h = 0; + } + else + { + usart_x->ctrl2_bit.id_l = (usart_id & 0x0F); + usart_x->ctrl2_bit.id_h = ((usart_id & 0xF0) >> 4); + } +} + +/** + * @brief select the usart wakeup method in multi-processor communication. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param wakeup_mode: determines the way to wake up usart method. + * this parameter can be one of the following values: + * - USART_WAKEUP_BY_IDLE_FRAME + * - USART_WAKEUP_BY_MATCHING_ID + * @retval none + */ +void usart_wakeup_mode_set(usart_type* usart_x, usart_wakeup_mode_type wakeup_mode) +{ + usart_x->ctrl1_bit.wum = wakeup_mode; +} + +/** + * @brief config the usart in mute mode in multi-processor communication. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the usart mute mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_receiver_mute_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl1_bit.rm = new_state; +} + +/** + * @brief set the usart break frame bit num. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param break_bit: specifies the break bit num. + * this parameter can be one of the following values: + * - USART_BREAK_10BITS + * - USART_BREAK_11BITS + * @retval none + */ +void usart_break_bit_num_set(usart_type* usart_x, usart_break_bit_num_type break_bit) +{ + usart_x->ctrl2_bit.bfbn = break_bit; +} + +/** + * @brief enable or disable the usart lin mode. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the usart lin mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_lin_mode_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl2_bit.linen = new_state; +} + +/** + * @brief transmit single data through the usart peripheral. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param data: the data to transmit. + * @retval none + */ +void usart_data_transmit(usart_type* usart_x, uint16_t data) +{ + usart_x->dt = (data & 0x01FF); +} + +/** + * @brief return the most recent received data by the usart peripheral. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @retval the received data. + */ +uint16_t usart_data_receive(usart_type* usart_x) +{ + return (uint16_t)(usart_x->dt); +} + +/** + * @brief transmit break characters. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @retval none + */ +void usart_break_send(usart_type* usart_x) +{ + usart_x->ctrl1_bit.sbf = TRUE; +} + +/** + * @brief config the specified usart smartcard guard time. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param guard_time_val: specifies the guard time (0x00~0xFF). + * @retval none + */ +void usart_smartcard_guard_time_set(usart_type* usart_x, uint8_t guard_time_val) +{ + usart_x->gdiv_bit.scgt = guard_time_val; +} + +/** + * @brief config the irda/smartcard division. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param div_val: specifies the division. + * @retval none + */ +void usart_irda_smartcard_division_set(usart_type* usart_x, uint8_t div_val) +{ + usart_x->gdiv_bit.isdiv = div_val; +} + +/** + * @brief enable or disable the usart smart card mode. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the smart card mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_smartcard_mode_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.scmen = new_state; +} + +/** + * @brief enable or disable nack transmission in smartcard mode. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the nack transmission. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_smartcard_nack_set(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.scnacken = new_state; +} + +/** + * @brief enable or disable the usart single line bidirectional half-duplex communication. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the single line half-duplex select. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_single_line_halfduplex_select(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.slben = new_state; +} + +/** + * @brief enable or disable the usart's irda interface. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the irda mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_irda_mode_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.irdaen = new_state; +} + +/** + * @brief configure the usart's irda low power. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the irda mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_irda_low_power_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.irdalp = new_state; +} + +/** + * @brief configure the usart's hardware flow control. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param flow_state: specifies the hardware flow control. + * this parameter can be one of the following values: + * - USART_HARDWARE_FLOW_NONE + * - USART_HARDWARE_FLOW_RTS, + * - USART_HARDWARE_FLOW_CTS, + * - USART_HARDWARE_FLOW_RTS_CTS + * @retval none + */ +void usart_hardware_flow_control_set(usart_type* usart_x,usart_hardware_flow_control_type flow_state) +{ + if(flow_state == USART_HARDWARE_FLOW_NONE) + { + usart_x->ctrl3_bit.rtsen = FALSE; + usart_x->ctrl3_bit.ctsen = FALSE; + } + else if(flow_state == USART_HARDWARE_FLOW_RTS) + { + usart_x->ctrl3_bit.rtsen = TRUE; + usart_x->ctrl3_bit.ctsen = FALSE; + } + else if(flow_state == USART_HARDWARE_FLOW_CTS) + { + usart_x->ctrl3_bit.rtsen = FALSE; + usart_x->ctrl3_bit.ctsen = TRUE; + } + else if(flow_state == USART_HARDWARE_FLOW_RTS_CTS) + { + usart_x->ctrl3_bit.rtsen = TRUE; + usart_x->ctrl3_bit.ctsen = TRUE; + } +} + +/** + * @brief check whether the specified usart flag is set or not. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - USART_CTSCF_FLAG: cts change flag (not available for UART4,UART5,USART6,UART7 and UART8) + * - USART_BFF_FLAG: break frame flag + * - USART_TDBE_FLAG: transmit data buffer empty flag + * - USART_TDC_FLAG: transmit data complete flag + * - USART_RDBF_FLAG: receive data buffer full flag + * - USART_IDLEF_FLAG: idle flag + * - USART_ROERR_FLAG: receiver overflow error flag + * - USART_NERR_FLAG: noise error flag + * - USART_FERR_FLAG: framing error flag + * - USART_PERR_FLAG: parity error flag + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status usart_flag_get(usart_type* usart_x, uint32_t flag) +{ + if(usart_x->sts & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief check whether the specified usart interrupt flag is set or not. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param flag: specifies the flag to check. + * this parameter can be one of the following values: + * - USART_CTSCF_FLAG: cts change flag (not available for UART4,UART5) + * - USART_BFF_FLAG: break frame flag + * - USART_TDBE_FLAG: transmit data buffer empty flag + * - USART_TDC_FLAG: transmit data complete flag + * - USART_RDBF_FLAG: receive data buffer full flag + * - USART_IDLEF_FLAG: idle flag + * - USART_ROERR_FLAG: receiver overflow error flag + * - USART_NERR_FLAG: noise error flag + * - USART_FERR_FLAG: framing error flag + * - USART_PERR_FLAG: parity error flag + * @retval the new state of usart_flag (SET or RESET). + */ +flag_status usart_interrupt_flag_get(usart_type* usart_x, uint32_t flag) +{ + flag_status int_status = RESET; + + switch(flag) + { + case USART_CTSCF_FLAG: + int_status = (flag_status)usart_x->ctrl3_bit.ctscfien; + break; + case USART_BFF_FLAG: + int_status = (flag_status)usart_x->ctrl2_bit.bfien; + break; + case USART_TDBE_FLAG: + int_status = (flag_status)usart_x->ctrl1_bit.tdbeien; + break; + case USART_TDC_FLAG: + int_status = (flag_status)usart_x->ctrl1_bit.tdcien; + break; + case USART_RDBF_FLAG: + int_status = (flag_status)usart_x->ctrl1_bit.rdbfien; + break; + case USART_ROERR_FLAG: + int_status = (flag_status)(usart_x->ctrl1_bit.rdbfien || usart_x->ctrl3_bit.errien); + break; + case USART_IDLEF_FLAG: + int_status = (flag_status)usart_x->ctrl1_bit.idleien; + break; + case USART_NERR_FLAG: + case USART_FERR_FLAG: + int_status = (flag_status)usart_x->ctrl3_bit.errien; + break; + case USART_PERR_FLAG: + int_status = (flag_status)usart_x->ctrl1_bit.perrien; + break; + default: + int_status = RESET; + break; + } + + if(int_status != SET) + { + return RESET; + } + + if(usart_x->sts & flag) + { + return SET; + } + else + { + return RESET; + } +} + +/** + * @brief clear the usart's pending flags. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param flag: specifies the flag to clear. + * this parameter can be any combination of the following values: + * - USART_CTSCF_FLAG: (not available for UART4,UART5,USART6,UART7 and UART8). + * - USART_BFF_FLAG: + * - USART_TDC_FLAG: + * - USART_RDBF_FLAG: + * - USART_PERR_FLAG: + * - USART_FERR_FLAG: + * - USART_NERR_FLAG: + * - USART_ROERR_FLAG: + * - USART_IDLEF_FLAG: + * @note + * - USART_PERR_FLAG, USART_FERR_FLAG, USART_NERR_FLAG, USART_ROERR_FLAG and USART_IDLEF_FLAG are cleared by software + * sequence: a read operation to usart sts register (usart_flag_get()) + * followed by a read operation to usart dt register (usart_data_receive()). + * - USART_RDBF_FLAG can be also cleared by a read to the usart dt register(usart_data_receive()). + * - USART_TDC_FLAG can be also cleared by software sequence: a read operation to usart sts register (usart_flag_get()) + * followed by a write operation to usart dt register (usart_data_transmit()). + * - USART_TDBE_FLAG is cleared only by a write to the usart dt register(usart_data_transmit()). + * @retval none + */ +void usart_flag_clear(usart_type* usart_x, uint32_t flag) +{ + if(flag & (USART_PERR_FLAG | USART_FERR_FLAG | USART_NERR_FLAG | USART_ROERR_FLAG | USART_IDLEF_FLAG)) + { + UNUSED(usart_x->sts); + UNUSED(usart_x->dt); + } + else + { + usart_x->sts = ~flag; + } +} + +/** + * @brief configure the usart's rs485 transmit delay time. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 + * @param start_delay_time: transmit start delay time. + * @param complete_delay_time: transmit complete delay time. + * @retval none + */ +void usart_rs485_delay_time_config(usart_type* usart_x, uint8_t start_delay_time, uint8_t complete_delay_time) +{ + usart_x->ctrl1_bit.tsdt = start_delay_time; + usart_x->ctrl1_bit.tcdt = complete_delay_time; +} + +/** + * @brief swap the usart's transmit receive pin. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 or USART4. + * @param new_state: new state of the usart peripheral. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_transmit_receive_pin_swap(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl2_bit.trpswap = new_state; +} + +/** + * @brief set the usart's identification bit num. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3, UART4, UART5, USART6, UART7,or UART8. + * @param id_bit_num: the usart wakeup identification bit num. + * this parameter can be: USART_ID_FIXED_4_BIT or USART_ID_RELATED_DATA_BIT. + * @retval none + */ +void usart_id_bit_num_set(usart_type* usart_x, usart_identification_bit_num_type id_bit_num) +{ + usart_x->ctrl2_bit.idbn = (uint8_t)id_bit_num; +} + +/** + * @brief set the usart's de polarity. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 + * @param de_polarity: the usart de polarity selection. + * this parameter can be: USART_DE_POLARITY_HIGH or USART_DE_POLARITY_LOW. + * @retval none + */ +void usart_de_polarity_set(usart_type* usart_x, usart_de_polarity_type de_polarity) +{ + usart_x->ctrl3_bit.dep = (uint8_t)de_polarity; +} + +/** + * @brief enable or disable the usart's rs485 mode. + * @param usart_x: select the usart or the uart peripheral. + * this parameter can be one of the following values: + * USART1, USART2, USART3 + * @param new_state: new state of the irda mode. + * this parameter can be: TRUE or FALSE. + * @retval none + */ +void usart_rs485_mode_enable(usart_type* usart_x, confirm_state new_state) +{ + usart_x->ctrl3_bit.rs485en = new_state; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_usb.c b/libraries/drivers/src/at32f425_usb.c new file mode 100644 index 0000000..c87a7b8 --- /dev/null +++ b/libraries/drivers/src/at32f425_usb.c @@ -0,0 +1,1087 @@ +/** + ************************************************************************** + * @file at32f425_usb.c + * @brief contains all the functions for the usb firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup USB + * @brief USB driver modules + * @{ + */ + +#ifdef USB_MODULE_ENABLED + +/** @defgroup USB_private_functions + * @{ + */ + +#ifdef OTGFS_USB_GLOBAL +/** + * @brief usb global core soft reset + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval error status + */ +error_status usb_global_reset(otg_global_type *usbx) +{ + uint32_t timeout = 0; + while(usbx->grstctl_bit.ahbidle == RESET) + { + if(timeout ++ > 200000) + { + break; + } + } + timeout = 0; + usbx->grstctl_bit.csftrst = TRUE; + while(usbx->grstctl_bit.csftrst == SET) + { + if(timeout ++ > 200000) + { + break; + } + } + return SUCCESS; +} + +/** + * @brief usb global initialization + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_global_init(otg_global_type *usbx) +{ + /* reset otg moudle */ + usb_global_reset(usbx); + + /* exit power down mode */ + usbx->gccfg_bit.pwrdown = TRUE; +} + +/** + * @brief usb global select usb core (otg1 or otg2). + * @param usb_id: select otg1 or otg2 + * this parameter can be one of the following values: + * - USB_OTG1_ID + * - USB_OTG2_ID + * @retval usb global register type pointer + */ +otg_global_type *usb_global_select_core(uint8_t usb_id) +{ + UNUSED(usb_id); + return OTG1_GLOBAL; + +} + +/** + * @brief flush tx fifo + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param fifo_num: tx fifo num,when fifo_num=16,flush all tx fifo + * parameter as following values: 0-16 + * @retval none + */ +void usb_flush_tx_fifo(otg_global_type *usbx, uint32_t fifo_num) +{ + uint32_t timeout = 0; + /* set flush fifo number */ + usbx->grstctl_bit.txfnum = fifo_num; + + /* start flush fifo */ + usbx->grstctl_bit.txfflsh = TRUE; + + while(usbx->grstctl_bit.txfflsh == TRUE) + { + if(timeout ++ > 200000) + { + break; + } + } +} + +/** + * @brief flush rx fifo + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_flush_rx_fifo(otg_global_type *usbx) +{ + uint32_t timeout = 0; + usbx->grstctl_bit.rxfflsh = TRUE; + while(usbx->grstctl_bit.rxfflsh == TRUE) + { + if(timeout ++ > 200000) + { + break; + } + } +} + +/** + * @brief usb interrupt mask enable + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param interrupt: + * this parameter can be any combination of the following values: + * - USB_OTG_MODEMIS_INT + * - USB_OTG_OTGINT_INT + * - USB_OTG_SOF_INT + * - USB_OTG_RXFLVL_INT + * - USB_OTG_NPTXFEMP_INT + * - USB_OTG_GINNAKEFF_INT + * - USB_OTG_GOUTNAKEFF_INT + * - USB_OTG_ERLYSUSP_INT + * - USB_OTG_USBSUSP_INT + * - USB_OTG_USBRST_INT + * - USB_OTG_ENUMDONE_INT + * - USB_OTG_ISOOUTDROP_INT + * - USB_OTG_IEPT_INT + * - USB_OTG_OEPT_INT + * - USB_OTG_INCOMISOIN_INT + * - USB_OTG_INCOMPIP_INCOMPISOOUT_INT + * - USB_OTG_PRT_INT + * - USB_OTG_HCH_INT + * - USB_OTG_PTXFEMP_INT + * - USB_OTG_CONIDSCHG_INT + * - USB_OTG_DISCON_INT + * - USB_OTG_WKUP_INT + * @param new_state: TRUE or FALSE + * @retval none + */ +void usb_global_interrupt_enable(otg_global_type *usbx, uint16_t interrupt, confirm_state new_state) +{ + if(new_state == TRUE) + { + usbx->gintmsk |= interrupt; + } + else + { + usbx->gintmsk &= ~interrupt; + } +} + +/** + * @brief get all global core interrupt flag + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval intterupt flag + */ +uint32_t usb_global_get_all_interrupt(otg_global_type *usbx) +{ + uint32_t intsts = usbx->gintsts; + return intsts & usbx->gintmsk; +} + +/** + * @brief clear the global interrupt flag + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param flag: interrupt flag + * this parameter can be any combination of the following values: + * - USB_OTG_MODEMIS_FLAG + * - USB_OTG_OTGINT_FLAG + * - USB_OTG_SOF_FLAG + * - USB_OTG_RXFLVL_FLAG + * - USB_OTG_NPTXFEMP_FLAG + * - USB_OTG_GINNAKEFF_FLAG + * - USB_OTG_GOUTNAKEFF_FLAG + * - USB_OTG_ERLYSUSP_FLAG + * - USB_OTG_USBSUSP_FLAG + * - USB_OTG_USBRST_FLAG + * - USB_OTG_ENUMDONE_FLAG + * - USB_OTG_ISOOUTDROP_FLAG + * - USB_OTG_EOPF_FLAG + * - USB_OTG_IEPT_FLAG + * - USB_OTG_OEPT_FLAG + * - USB_OTG_INCOMISOIN_FLAG + * - USB_OTG_INCOMPIP_INCOMPISOOUT_FLAG + * - USB_OTG_PRT_FLAG + * - USB_OTG_HCH_FLAG + * - USB_OTG_PTXFEMP_FLAG + * - USB_OTG_CONIDSCHG_FLAG + * - USB_OTG_DISCON_FLAG + * - USB_OTG_WKUP_FLAG + * @retval none + */ +void usb_global_clear_interrupt(otg_global_type *usbx, uint32_t flag) +{ + usbx->gintsts = flag; +} + +/** + * @brief usb global interrupt enable + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * OTG1_GLOBAL , OTG2_GLOBAL + * @retval none + */ +void usb_interrupt_enable(otg_global_type *usbx) +{ + usbx->gahbcfg_bit.glbintmsk = TRUE; +} + +/** + * @brief usb global interrupt disable + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_interrupt_disable(otg_global_type *usbx) +{ + usbx->gahbcfg_bit.glbintmsk = FALSE; +} + +/** + * @brief usb set rx fifo size + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param size: rx fifo size + * @retval none + */ +void usb_set_rx_fifo(otg_global_type *usbx, uint16_t size) +{ + usbx->grxfsiz = size; +} + +/** + * @brief usb set tx fifo size + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param txfifo: the fifo number + * @param size: tx fifo size + * @retval none + */ +void usb_set_tx_fifo(otg_global_type *usbx, uint8_t txfifo, uint16_t size) +{ + uint8_t i_index = 0; + uint32_t offset = 0; + + offset = usbx->grxfsiz; + if(txfifo == 0) + { + usbx->gnptxfsiz_ept0tx = offset | (size << 16); + } + else + { + offset += usbx->gnptxfsiz_ept0tx_bit.nptxfdep; + for(i_index = 0; i_index < (txfifo - 1); i_index ++) + { + offset += usbx->dieptxfn_bit[i_index].ineptxfdep; + } + usbx->dieptxfn[txfifo - 1] = offset | (size << 16); + } +} + + +/** + * @brief set otg mode(device or host mode) + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param mode: + this parameter can be one of the following values: + * - OTG_DEVICE_MODE + * - OTG_HOST_MODE + * - OTG_DRD_MODE + * @retval none + */ +void usb_global_set_mode(otg_global_type *usbx, uint32_t mode) +{ + /* set otg to device mode */ + if(mode == OTG_DEVICE_MODE) + { + usbx->gusbcfg_bit.fhstmode = FALSE; + usbx->gusbcfg_bit.fdevmode = TRUE; + } + + /* set otg to host mode */ + if(mode == OTG_HOST_MODE) + { + usbx->gusbcfg_bit.fdevmode = FALSE; + usbx->gusbcfg_bit.fhstmode = TRUE; + } + + /* set otg to default mode */ + if(mode == OTG_DRD_MODE) + { + usbx->gusbcfg_bit.fdevmode = FALSE; + usbx->gusbcfg_bit.fhstmode = FALSE; + } +} + + +/** + * @brief disable the transceiver power down mode + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_global_power_on(otg_global_type *usbx) +{ + /* core soft reset */ + usbx->grstctl_bit.csftrst = TRUE; + while(usbx->grstctl_bit.csftrst); + + /* disable power down mode */ + usbx->gccfg_bit.pwrdown = TRUE; + +} + +/** + * @brief usb stop phy clock + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_stop_phy_clk(otg_global_type *usbx) +{ + OTG_PCGCCTL(usbx)->pcgcctl_bit.stoppclk = TRUE; +} + +/** + * @brief usb open phy clock + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_open_phy_clk(otg_global_type *usbx) +{ + OTG_PCGCCTL(usbx)->pcgcctl_bit.stoppclk = FALSE; +} + + +/** + * @brief write data from user memory to usb buffer + * @param pusr_buf: point to user buffer + * @param offset_addr: endpoint tx offset address + * @param nbytes: number of bytes data write to usb buffer + * @retval none + */ +void usb_write_packet(otg_global_type *usbx, uint8_t *pusr_buf, uint16_t num, uint16_t nbytes) +{ + uint32_t n_index; + uint32_t nhbytes = (nbytes + 3) / 4; + uint32_t *pbuf = (uint32_t *)pusr_buf; + for(n_index = 0; n_index < nhbytes; n_index ++) + { +#if defined (__ICCARM__) && (__VER__ < 7000000) + USB_FIFO(usbx, num) = *(__packed uint32_t *)pbuf; +#else + USB_FIFO(usbx, num) = __UNALIGNED_UINT32_READ(pbuf); +#endif + pbuf ++; + } +} + +/** + * @brief read data from usb buffer to user buffer + * @param pusr_buf: point to user buffer + * @param offset_addr: endpoint rx offset address + * @param nbytes: number of bytes data write to usb buffer + * @retval none + */ +void usb_read_packet(otg_global_type *usbx, uint8_t *pusr_buf, uint16_t num, uint16_t nbytes) +{ + uint32_t n_index; + uint32_t nhbytes = (nbytes + 3) / 4; + uint32_t *pbuf = (uint32_t *)pusr_buf; + UNUSED(num); + for(n_index = 0; n_index < nhbytes; n_index ++) + { +#if defined (__ICCARM__) && (__VER__ < 7000000) + *(__packed uint32_t *)pbuf = USB_FIFO(usbx, 0); +#else + __UNALIGNED_UINT32_WRITE(pbuf, (USB_FIFO(usbx, 0))); +#endif + pbuf ++; + } +} +#endif + + +#ifdef OTGFS_USB_DEVICE +/** + * @brief open usb endpoint + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_open(otg_global_type *usbx, usb_ept_info *ept_info) +{ + uint8_t mps = USB_EPT0_MPS_64; + if(ept_info->eptn == USB_EPT0) + { + if(ept_info->maxpacket == 0x40) + { + mps = USB_EPT0_MPS_64; + } + else if(ept_info->maxpacket == 0x20) + { + mps = USB_EPT0_MPS_32; + } + else if(ept_info->maxpacket == 0x10) + { + mps = USB_EPT0_MPS_16; + } + else if(ept_info->maxpacket == 0x08) + { + mps = USB_EPT0_MPS_8; + } + } + /* endpoint direction is in */ + if(ept_info->inout == EPT_DIR_IN) + { + OTG_DEVICE(usbx)->daintmsk |= 1 << ept_info->eptn; + if(ept_info->eptn == USB_EPT0) + { + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.mps = mps; + } + else + { + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.mps = ept_info->maxpacket; + } + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.eptype = ept_info->trans_type; + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.txfnum = ept_info->eptn; + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.setd0pid = TRUE; + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.usbacept = TRUE; + } + /* endpoint direction is out */ + else + { + OTG_DEVICE(usbx)->daintmsk |= (1 << ept_info->eptn) << 16; + if(ept_info->eptn == USB_EPT0) + { + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.mps = mps; + } + else + { + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.mps = ept_info->maxpacket; + } + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.eptype = ept_info->trans_type; + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.setd0pid = TRUE; + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.usbacept = TRUE; + } +} + +/** + * @brief close usb endpoint + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_close(otg_global_type *usbx, usb_ept_info *ept_info) +{ + if(ept_info->inout == EPT_DIR_IN) + { + OTG_DEVICE(usbx)->daintmsk &= ~(1 << ept_info->eptn); + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.usbacept = FALSE; + } + else + { + OTG_DEVICE(usbx)->daintmsk &= ~((1 << ept_info->eptn) << 16); + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.usbacept = FALSE; + } +} + + +/** + * @brief set endpoint tx or rx status to stall + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_stall(otg_global_type *usbx, usb_ept_info *ept_info) +{ + if(ept_info->inout == EPT_DIR_IN) + { + if(USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.eptena == RESET) + { + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.eptdis = FALSE; + } + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.stall = SET; + } + else + { + if(USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.eptena == RESET) + { + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.eptdis = FALSE; + } + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.stall = TRUE; + } +} + +/** + * @brief clear endpoint tx or rx status to stall + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param ept_info: endpoint information structure + * @retval none + */ +void usb_ept_clear_stall(otg_global_type *usbx, usb_ept_info *ept_info) +{ + if(ept_info->inout == EPT_DIR_IN) + { + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.stall = FALSE; + if(ept_info->trans_type == EPT_INT_TYPE || ept_info->trans_type == EPT_BULK_TYPE) + { + USB_INEPT(usbx, ept_info->eptn)->diepctl_bit.setd0pid = TRUE; + } + } + else + { + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.stall = FALSE; + if(ept_info->trans_type == EPT_INT_TYPE || ept_info->trans_type == EPT_BULK_TYPE) + { + USB_OUTEPT(usbx, ept_info->eptn)->doepctl_bit.setd0pid = TRUE; + } + } +} + +/** + * @brief get all out endpoint interrupt bits + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval out endpoint interrupt bits + */ +uint32_t usb_get_all_out_interrupt(otg_global_type *usbx) +{ + uint32_t intsts = OTG_DEVICE(usbx)->daint; + return ((intsts & (OTG_DEVICE(usbx)->daintmsk)) >> 16); +} + +/** + * @brief get all in endpoint interrupt bits + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval in endpoint interrupt bits + */ +uint32_t usb_get_all_in_interrupt(otg_global_type *usbx) +{ + uint32_t intsts = OTG_DEVICE(usbx)->daint; + return ((intsts & (OTG_DEVICE(usbx)->daintmsk)) & 0xFFFF); +} + + +/** + * @brief get out endpoint interrupt flag + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param eptn: endpoint number + * @retval out endpoint interrupt flags + */ +uint32_t usb_ept_out_interrupt(otg_global_type *usbx, uint32_t eptn) +{ + uint32_t intsts = USB_OUTEPT(usbx, eptn)->doepint; + return (intsts & (OTG_DEVICE(usbx)->doepmsk)); +} + +/** + * @brief get in endpoint interrupt flag + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param eptn: endpoint number + * @retval in endpoint intterupt flags + */ +uint32_t usb_ept_in_interrupt(otg_global_type *usbx, uint32_t eptn) +{ + uint32_t intsts, mask1, mask2; + mask1 = OTG_DEVICE(usbx)->diepmsk; + mask2 = OTG_DEVICE(usbx)->diepempmsk; + mask1 |= ((mask2 >> eptn) & 0x1) << 7; + intsts = USB_INEPT(usbx, eptn)->diepint & mask1; + return intsts; +} + +/** + * @brief clear out endpoint interrupt flag + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param eptn: endpoint number + * @retval flag: interrupt flag + * this parameter can be any combination of the following values: + * - USB_OTG_DOEPINT_XFERC_FLAG + * - USB_OTG_DOEPINT_EPTDISD_FLAG + * - USB_OTG_DOEPINT_SETUP_FLAG + * - USB_OTG_DOEPINT_OTEPDIS_FLAG + * - USB_OTG_DOEPINT_B2BSTUP_FLAG + */ +void usb_ept_out_clear(otg_global_type *usbx, uint32_t eptn, uint32_t flag) +{ + USB_OUTEPT(usbx, eptn)->doepint = flag; +} + +/** + * @brief clear in endpoint interrupt flag + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param eptn: endpoint number + * @retval flag: interrupt flag + * this parameter can be any combination of the following values: + * - USB_OTG_DIEPINT_XFERC_FLAG + * - USB_OTG_DIEPINT_EPTDISD_FLAG + * - USB_OTG_DIEPINT_TMROC_FLAG + * - USB_OTG_DIEPINT_INTTXFE_FLAG + * - USB_OTG_DIEPINT_INEPNE_FLAG + * - USB_OTG_DIEPINT_TXFE_FLAG + */ +void usb_ept_in_clear(otg_global_type *usbx, uint32_t eptn, uint32_t flag) +{ + USB_INEPT(usbx, eptn)->diepint = flag; +} + + +/** + * @brief set the host assignment address + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param address: host assignment address + * @retval none + */ +void usb_set_address(otg_global_type *usbx, uint8_t address) +{ + OTG_DEVICE(usbx)->dcfg_bit.devaddr = address; +} + +/** + * @brief enable endpoint 0 out + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_ept0_start(otg_global_type *usbx) +{ + otg_eptout_type *usb_outept = USB_OUTEPT(usbx, 0); + usb_outept->doeptsiz = 0; + usb_outept->doeptsiz_bit.pktcnt = 1; + usb_outept->doeptsiz_bit.xfersize = 24; + usb_outept->doeptsiz_bit.rxdpid_setupcnt = 3; +} + + +/** + * @brief endpoint 0 start setup + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_ept0_setup(otg_global_type *usbx) +{ + USB_INEPT(usbx, 0)->diepctl_bit.mps = 0; + OTG_DEVICE(usbx)->dctl_bit.cgnpinak = FALSE; +} + +/** + * @brief connect usb device by enable pull-up + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_connect(otg_global_type *usbx) +{ + /* D+ 1.5k pull-up enable */ + OTG_DEVICE(usbx)->dctl_bit.sftdiscon = FALSE; +} + +/** + * @brief disconnect usb device by disable pull-up + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_disconnect(otg_global_type *usbx) +{ + /* D+ 1.5k pull-up disable */ + OTG_DEVICE(usbx)->dctl_bit.sftdiscon = TRUE; +} + + +/** + * @brief usb remote wakeup set + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_remote_wkup_set(otg_global_type *usbx) +{ + OTG_DEVICE(usbx)->dctl_bit.rwkupsig = TRUE; +} + +/** + * @brief usb remote wakeup clear + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_remote_wkup_clear(otg_global_type *usbx) +{ + OTG_DEVICE(usbx)->dctl_bit.rwkupsig = FALSE; +} + +/** + * @brief usb suspend status get + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval usb suspend status + */ +uint8_t usb_suspend_status_get(otg_global_type *usbx) +{ + return OTG_DEVICE(usbx)->dsts_bit.suspsts; +} +#endif + +#ifdef OTGFS_USB_HOST +/** + * @brief usb port power on + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param state: state (TRUE or FALSE) + * @retval none + */ +void usb_port_power_on(otg_global_type *usbx, confirm_state state) +{ + otg_host_type *usb_host = OTG_HOST(usbx); + uint32_t hprt_val = usb_host->hprt; + + hprt_val &= ~(USB_OTG_HPRT_PRTENA | USB_OTG_HPRT_PRTENCHNG | + USB_OTG_HPRT_PRTOVRCACT | USB_OTG_HPRT_PRTCONDET); + + if(state == TRUE) + { + usb_host->hprt = hprt_val | USB_OTG_HPRT_PRTPWR; + } + else + { + usb_host->hprt = hprt_val & (~USB_OTG_HPRT_PRTPWR); + } +} + +/** + * @brief get current frame number + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +uint32_t usbh_get_frame(otg_global_type *usbx) +{ + otg_host_type *usb_host = OTG_HOST(usbx); + return usb_host->hfnum & 0xFFFF; +} + +/** + * @brief enable one host channel + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param chn: host channel number + * @param ept_num: devvice endpoint number + * @param dev_address: device address + * @param type: channel transfer type + * this parameter can be one of the following values: + * - EPT_CONTROL_TYPE + * - EPT_BULK_TYPE + * - EPT_INT_TYPE + * - EPT_ISO_TYPE + * @param maxpacket: support max packe size for this channel + * @param speed: device speed + * this parameter can be one of the following values: + * - USB_PRTSPD_FULL_SPEED + * - USB_PRTSPD_LOW_SPEED + * @retval none + */ +void usb_hc_enable(otg_global_type *usbx, + uint8_t chn, + uint8_t ept_num, + uint8_t dev_address, + uint8_t type, + uint16_t maxpacket, + uint8_t speed) +{ + otg_hchannel_type *hch = USB_CHL(usbx, chn); + otg_host_type *usb_host = OTG_HOST(usbx); + + switch(type) + { + case EPT_CONTROL_TYPE: + case EPT_BULK_TYPE: + hch->hcintmsk |= USB_OTG_HC_XFERCM_INT | USB_OTG_HC_STALLM_INT | + USB_OTG_HC_XACTERRM_INT | USB_OTG_HC_NAKM_INT | + USB_OTG_HC_DTGLERRM_INT; + if(ept_num & 0x80) + { + hch->hcintmsk_bit.bblerrmsk = TRUE; + } + break; + case EPT_INT_TYPE: + hch->hcintmsk |= USB_OTG_HC_XFERCM_INT | USB_OTG_HC_STALLM_INT | + USB_OTG_HC_XACTERRM_INT | USB_OTG_HC_NAKM_INT | + USB_OTG_HC_DTGLERRM_INT | USB_OTG_HC_FRMOVRRUN_INT; + break; + case EPT_ISO_TYPE: + + hch->hcintmsk |= USB_OTG_HC_XFERCM_INT | USB_OTG_HC_ACKM_INT | + USB_OTG_HC_FRMOVRRUN_INT; + break; + } + usb_host->haintmsk |= 1 << chn; + usbx->gintmsk_bit.hchintmsk = TRUE; + + hch->hcchar_bit.devaddr = dev_address; + hch->hcchar_bit.eptnum = ept_num & 0x7F; + hch->hcchar_bit.eptdir = (ept_num & 0x80)?1:0; + hch->hcchar_bit.lspddev = (speed == USB_PRTSPD_LOW_SPEED)?1:0; + hch->hcchar_bit.eptype = type; + hch->hcchar_bit.mps = maxpacket; + + if(type == EPT_INT_TYPE) + { + hch->hcchar_bit.oddfrm = TRUE; + } +} + +/** + * @brief host read channel interrupt + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval interrupt flag + */ +uint32_t usb_hch_read_interrupt(otg_global_type *usbx) +{ + otg_host_type *usb_host = OTG_HOST(usbx); + return usb_host->haint & 0xFFFF; +} + +/** + * @brief disable host + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @retval none + */ +void usb_host_disable(otg_global_type *usbx) +{ + uint32_t i_index = 0, count = 0; + otg_hchannel_type *hch; + otg_host_type *usb_host = OTG_HOST(usbx); + + usbx->gahbcfg_bit.glbintmsk = FALSE; + usb_flush_rx_fifo(usbx); + usb_flush_tx_fifo(usbx, 0x10); + + for(i_index = 0; i_index < 16; i_index ++) + { + hch = USB_CHL(usbx, i_index); + hch->hcchar_bit.chdis = TRUE; + hch->hcchar_bit.chena = FALSE; + hch->hcchar_bit.eptdir = 0; + } + + for(i_index = 0; i_index < 16; i_index ++) + { + hch = USB_CHL(usbx, i_index); + hch->hcchar_bit.chdis = TRUE; + hch->hcchar_bit.chena = TRUE; + hch->hcchar_bit.eptdir = 0; + do + { + if(count ++ > 1000) + break; + }while(hch->hcchar_bit.chena); + } + usb_host->haint = 0xFFFFFFFF; + usbx->gintsts = 0xFFFFFFFF; + usbx->gahbcfg_bit.glbintmsk = TRUE; +} + +/** + * @brief halt channel + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param chn: channel number + * @retval none + */ +void usb_hch_halt(otg_global_type *usbx, uint8_t chn) +{ + uint32_t count = 0; + otg_hchannel_type *usb_chh = USB_CHL(usbx, chn); + otg_host_type *usb_host = OTG_HOST(usbx); + + /* endpoint type is control or bulk */ + if(usb_chh->hcchar_bit.eptype == EPT_CONTROL_TYPE || + usb_chh->hcchar_bit.eptype == EPT_BULK_TYPE) + { + usb_chh->hcchar_bit.chdis = TRUE; + if((usbx->gnptxsts_bit.nptxqspcavail) == 0) + { + usb_chh->hcchar_bit.chena = FALSE; + usb_chh->hcchar_bit.chena = TRUE; + do + { + if(count ++ > 1000) + break; + }while(usb_chh->hcchar_bit.chena == SET); + } + else + { + usb_chh->hcchar_bit.chena = TRUE; + } + } + else + { + usb_chh->hcchar_bit.chdis = TRUE; + if((usb_host->hptxsts_bit.ptxqspcavil) == 0) + { + usb_chh->hcchar_bit.chena = FALSE; + usb_chh->hcchar_bit.chena = TRUE; + do + { + if(count ++ > 1000) + break; + }while(usb_chh->hcchar_bit.chena == SET); + } + else + { + usb_chh->hcchar_bit.chena = TRUE; + } + } +} +/** + * @brief select full or low speed clock + * @param usbx: to select the otgfs peripheral. + * this parameter can be one of the following values: + * - OTG1_GLOBAL + * - OTG2_GLOBAL + * @param clk: clock frequency + * @retval none + */ +void usbh_fsls_clksel(otg_global_type *usbx, uint8_t clk) +{ + otg_host_type *usb_host = OTG_HOST(usbx); + + usb_host->hcfg_bit.fslspclksel = clk; + if(clk == USB_HCFG_CLK_6M) + { + usb_host->hfir = 6000; + } + else + { + usb_host->hfir = 48000; + } +} +#endif + + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_wdt.c b/libraries/drivers/src/at32f425_wdt.c new file mode 100644 index 0000000..42e4e80 --- /dev/null +++ b/libraries/drivers/src/at32f425_wdt.c @@ -0,0 +1,154 @@ +/** + ************************************************************************** + * @file at32f425_wdt.c + * @brief contains all the functions for the wdt firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup WDT + * @brief WDT driver modules + * @{ + */ + +#ifdef WDT_MODULE_ENABLED + +/** @defgroup WDT_private_functions + * @{ + */ + +/** + * @brief wdt enable ,the reload value will be sent to the counter + * @param none + * @retval none + */ +void wdt_enable(void) +{ + WDT->cmd = WDT_CMD_ENABLE; +} + +/** + * @brief reload wdt counter + * @param none + * @retval none + */ +void wdt_counter_reload(void) +{ + WDT->cmd = WDT_CMD_RELOAD; +} + +/** + * @brief set wdt counter reload value + * @param reload_value (0x0000~0x0FFF) + * @retval none + */ +void wdt_reload_value_set(uint16_t reload_value) +{ + WDT->rld = reload_value; +} + +/** + * @brief set wdt division divider + * @param division + * this parameter can be one of the following values: + * - WDT_CLK_DIV_4 + * - WDT_CLK_DIV_8 + * - WDT_CLK_DIV_16 + * - WDT_CLK_DIV_32 + * - WDT_CLK_DIV_64 + * - WDT_CLK_DIV_128 + * - WDT_CLK_DIV_256 + * @retval none + */ +void wdt_divider_set(wdt_division_type division) +{ + WDT->div_bit.div = division; +} + +/** + * @brief enable or disable wdt cmd register write + * @param new_state (TRUE or FALSE) + * @retval none + */ +void wdt_register_write_enable( confirm_state new_state) +{ + if(new_state == FALSE) + { + WDT->cmd = WDT_CMD_LOCK; + } + else + { + WDT->cmd = WDT_CMD_UNLOCK; + } +} + +/** + * @brief get wdt flag + * @param wdt_flag + * this parameter can be one of the following values: + * - WDT_DIVF_UPDATE_FLAG: division value update complete flag. + * - WDT_RLDF_UPDATE_FLAG: reload value update complete flag. + * - WDT_WINF_UPDATE_FLAG: window value update complete flag. + * @retval state of wdt flag + */ +flag_status wdt_flag_get(uint16_t wdt_flag) +{ + flag_status status = RESET; + + if ((WDT->sts & wdt_flag) != (uint16_t)RESET) + { + status = SET; + } + else + { + status = RESET; + } + + return status; +} + +/** + * @brief wdt window counter value set + * @param window_cnt (0x0000~0x0FFF) + * @retval none + */ +void wdt_window_counter_set(uint16_t window_cnt) +{ + WDT->win_bit.win = window_cnt; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/libraries/drivers/src/at32f425_wwdt.c b/libraries/drivers/src/at32f425_wwdt.c new file mode 100644 index 0000000..c1d824a --- /dev/null +++ b/libraries/drivers/src/at32f425_wwdt.c @@ -0,0 +1,149 @@ +/** + ************************************************************************** + * @file at32f425_wwdt.c + * @brief contains all the functions for the wwdt firmware library + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "at32f425_conf.h" + +/** @addtogroup AT32F425_periph_driver + * @{ + */ + +/** @defgroup WWDT + * @brief WWDT driver modules + * @{ + */ + +#ifdef WWDT_MODULE_ENABLED + +/** @defgroup WWDT_private_functions + * @{ + */ + +/** + * @brief wwdt reset by crm reset register + * @retval none + */ +void wwdt_reset(void) +{ + crm_periph_reset(CRM_WWDT_PERIPH_RESET, TRUE); + crm_periph_reset(CRM_WWDT_PERIPH_RESET, FALSE); +} + +/** + * @brief wwdt division set + * @param division + * this parameter can be one of the following values: + * - WWDT_PCLK1_DIV_4096 (wwdt counter clock = (pclk1/4096)/1) + * - WWDT_PCLK1_DIV_8192 (wwdt counter clock = (pclk1/4096)/2) + * - WWDT_PCLK1_DIV_16384 (wwdt counter clock = (pclk1/4096)/4) + * - WWDT_PCLK1_DIV_32768 (wwdt counter clock = (pclk1/4096)/8) + * @retval none + */ +void wwdt_divider_set(wwdt_division_type division) +{ + WWDT->cfg_bit.div = division; +} + +/** + * @brief wwdt reload counter interrupt flag clear + * @param none + * @retval none + */ +void wwdt_flag_clear(void) +{ + WWDT->sts = 0; +} + +/** + * @brief wwdt enable and the counter value load + * @param wwdt_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_enable(uint8_t wwdt_cnt) +{ + WWDT->ctrl = wwdt_cnt | WWDT_EN_BIT; +} + +/** + * @brief wwdt reload counter interrupt enable + * @param none + * @retval none + */ +void wwdt_interrupt_enable(void) +{ + WWDT->cfg_bit.rldien = TRUE; +} + +/** + * @brief wwdt reload counter interrupt flag get + * @param none + * @retval state of reload counter interrupt flag + */ +flag_status wwdt_flag_get(void) +{ + return (flag_status)WWDT->sts_bit.rldf; +} + +/** + * @brief wwdt reload counter interrupt flag get + * @param none + * @retval state of reload counter interrupt flag + */ +flag_status wwdt_interrupt_flag_get(void) +{ + return (flag_status)(WWDT->sts_bit.rldf && WWDT->cfg_bit.rldien); +} + +/** + * @brief wwdt counter value set + * @param wwdt_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_counter_set(uint8_t wwdt_cnt) +{ + WWDT->ctrl_bit.cnt = wwdt_cnt; +} + +/** + * @brief wwdt window counter value set + * @param window_cnt (0x40~0x7f) + * @retval none + */ +void wwdt_window_counter_set(uint8_t window_cnt) +{ + WWDT->cfg_bit.win = window_cnt; +} + +/** + * @} + */ + +#endif + +/** + * @} + */ + +/** + * @} + */ diff --git a/project/MDK_V5/BC5D.uvoptx b/project/MDK_V5/BC5D.uvoptx new file mode 100644 index 0000000..ddd7189 --- /dev/null +++ b/project/MDK_V5/BC5D.uvoptx @@ -0,0 +1,493 @@ + + + 1.0 +
### uVision Project, (C) Keil Software
+ + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + 0 + 0 + + + BC5D + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 3 + + + + + + + + + + + BIN\CMSIS_AGDI.dll + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + user + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\src\at32f425_int.c + at32f425_int.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + ..\src\at32f425_wk_config.c + at32f425_wk_config.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ..\src\main.c + main.c + 0 + 0 + + + + firmware + 0 + 0 + 0 + 0 + + 2 + 4 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_acc.c + at32f425_acc.c + 0 + 0 + + + 2 + 5 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_adc.c + at32f425_adc.c + 0 + 0 + + + 2 + 6 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_can.c + at32f425_can.c + 0 + 0 + + + 2 + 7 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_crc.c + at32f425_crc.c + 0 + 0 + + + 2 + 8 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_crm.c + at32f425_crm.c + 0 + 0 + + + 2 + 9 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_debug.c + at32f425_debug.c + 0 + 0 + + + 2 + 10 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_dma.c + at32f425_dma.c + 0 + 0 + + + 2 + 11 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_ertc.c + at32f425_ertc.c + 0 + 0 + + + 2 + 12 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_exint.c + at32f425_exint.c + 0 + 0 + + + 2 + 13 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_flash.c + at32f425_flash.c + 0 + 0 + + + 2 + 14 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_gpio.c + at32f425_gpio.c + 0 + 0 + + + 2 + 15 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_i2c.c + at32f425_i2c.c + 0 + 0 + + + 2 + 16 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_misc.c + at32f425_misc.c + 0 + 0 + + + 2 + 17 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_pwc.c + at32f425_pwc.c + 0 + 0 + + + 2 + 18 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_scfg.c + at32f425_scfg.c + 0 + 0 + + + 2 + 19 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_spi.c + at32f425_spi.c + 0 + 0 + + + 2 + 20 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_tmr.c + at32f425_tmr.c + 0 + 0 + + + 2 + 21 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_usart.c + at32f425_usart.c + 0 + 0 + + + 2 + 22 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_usb.c + at32f425_usb.c + 0 + 0 + + + 2 + 23 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_wdt.c + at32f425_wdt.c + 0 + 0 + + + 2 + 24 + 1 + 0 + 0 + 0 + ..\..\libraries\drivers\src\at32f425_wwdt.c + at32f425_wwdt.c + 0 + 0 + + + + cmsis + 0 + 0 + 0 + 0 + + 3 + 25 + 2 + 0 + 0 + 0 + .\startup_at32f425.s + startup_at32f425.s + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\libraries\cmsis\cm4\device_support\system_at32f425.c + system_at32f425.c + 0 + 0 + + +
diff --git a/project/MDK_V5/BC5D.uvprojx b/project/MDK_V5/BC5D.uvprojx new file mode 100644 index 0000000..9afe69f --- /dev/null +++ b/project/MDK_V5/BC5D.uvprojx @@ -0,0 +1,481 @@ + + + 2.1 +
### uVision Project, (C) Keil Software
+ + + BC5D + 0x4 + ARM-ADS + 5060960::V5.06 update 7 (build 960)::.\ARMCC + 0 + + + -AT32F425C8T7 + ArteryTek + ArteryTek.AT32F425_DFP.2.1.0 + IRAM(0x20000000,0x1400000) IROM(0x08000000,0x4000000) CPUTYPE("Cortex-M4") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0AT32F425_64 -FS08000000 -FL010000 -FP0($$Device:-AT32F425C8T7$Flash\AT32F425_64.FLM)) + 0 + $$Device:-AT32F425C8T7$Device\Include\at32f425.h + + + + + + + + + + $$Device:-AT32F425C8T7$SVD\AT32F425xx_v2.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\objects\ + BC5D + 1 + 0 + 1 + 1 + 1 + .\listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 0 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x5000 + + + 1 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x5000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + AT32F425C8T7,USE_STDPERIPH_DRIVER + + ..\..\libraries\drivers\inc;..\..\libraries\cmsis\cm4\core_support;..\..\libraries\cmsis\cm4\device_support;..\inc + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + + + + + + + + + user + + + at32f425_int.c + 1 + ..\src\at32f425_int.c + + + at32f425_wk_config.c + 1 + ..\src\at32f425_wk_config.c + + + main.c + 1 + ..\src\main.c + + + + + firmware + + + at32f425_can.c + 1 + ..\..\libraries\drivers\src\at32f425_can.c + + + at32f425_crm.c + 1 + ..\..\libraries\drivers\src\at32f425_crm.c + + + at32f425_debug.c + 1 + ..\..\libraries\drivers\src\at32f425_debug.c + + + at32f425_flash.c + 1 + ..\..\libraries\drivers\src\at32f425_flash.c + + + at32f425_gpio.c + 1 + ..\..\libraries\drivers\src\at32f425_gpio.c + + + at32f425_misc.c + 1 + ..\..\libraries\drivers\src\at32f425_misc.c + + + at32f425_pwc.c + 1 + ..\..\libraries\drivers\src\at32f425_pwc.c + + + at32f425_tmr.c + 1 + ..\..\libraries\drivers\src\at32f425_tmr.c + + + at32f425_usart.c + 1 + ..\..\libraries\drivers\src\at32f425_usart.c + + + + + cmsis + + + startup_at32f425.s + 2 + .\startup_at32f425.s + + + system_at32f425.c + 1 + ..\..\libraries\cmsis\cm4\device_support\system_at32f425.c + + + + + + + + + + + + + + + BC5D + 0 + 1 + + + +
diff --git a/project/MDK_V5/startup_at32f425.s b/project/MDK_V5/startup_at32f425.s new file mode 100644 index 0000000..34d4d69 --- /dev/null +++ b/project/MDK_V5/startup_at32f425.s @@ -0,0 +1,261 @@ +;************************************************************************** +;* @file startup_at32f425.s +;* @brief startup_at32f425 startup file for keil +;* <<< Use Configuration Wizard in Context Menu >>> +;************************************************************************** +; + +; Amount of memory (in bytes) allocated for Stack +; Tailor this value to your application needs +; Stack Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Stack_Size EQU 0x00000400 + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + +; Heap Configuration +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + +Heap_Size EQU 0x00000200 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + + +; Vector Table Mapped to Address 0 at Reset + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDT_IRQHandler ; Window Watchdog Timer + DCD PVM_IRQHandler ; PVM through EXINT Line detect + DCD ERTC_IRQHandler ; ERTC + DCD FLASH_IRQHandler ; Flash + DCD CRM_IRQHandler ; CRM + DCD EXINT1_0_IRQHandler ; EXINT Line 1 & 0 + DCD EXINT3_2_IRQHandler ; EXINT Line 3 & 2 + DCD EXINT15_4_IRQHandler ; EXINT Line 15 ~ 4 + DCD ACC_IRQHandler ; ACC + DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 + DCD DMA1_Channel3_2_IRQHandler ; DMA1 Channel 3 & 2 + DCD DMA1_Channel7_4_IRQHandler ; DMA1 Channel 7 & 4 + DCD ADC1_IRQHandler ; ADC1 + DCD TMR1_BRK_OVF_TRG_HALL_IRQHandler ; TMR1 brake overflow trigger and hall + DCD TMR1_CH_IRQHandler ; TMR1 channel + DCD TMR2_GLOBAL_IRQHandler ; TMR2 + DCD TMR3_GLOBAL_IRQHandler ; TMR3 + DCD TMR6_GLOBAL_IRQHandler ; TMR6 + DCD TMR7_GLOBAL_IRQHandler ; TMR7 + DCD TMR14_GLOBAL_IRQHandler ; TMR14 + DCD TMR15_GLOBAL_IRQHandler ; TMR15 + DCD TMR16_GLOBAL_IRQHandler ; TMR16 + DCD TMR17_GLOBAL_IRQHandler ; TMR17 + DCD I2C1_EVT_IRQHandler ; I2C1 Event + DCD I2C2_EVT_IRQHandler ; I2C2 Event + DCD SPI1_IRQHandler ; SPI1 + DCD SPI2_IRQHandler ; SPI2 + DCD USART1_IRQHandler ; USART1 + DCD USART2_IRQHandler ; USART2 + DCD USART4_3_IRQHandler ; USART3 & USART4 + DCD CAN1_IRQHandler ; CAN1 + DCD OTGFS1_IRQHandler ; OTGFS1 + DCD I2C1_ERR_IRQHandler ; I2C1 Error + DCD SPI3_IRQHandler ; SPI3 + DCD I2C2_ERR_IRQHandler ; I2C2 Error + DCD TMR13_GLOBAL_IRQHandler ; TMR13 +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset handler +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT __main + IMPORT SystemInit + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemManage_Handler\ + PROC + EXPORT MemManage_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + EXPORT WWDT_IRQHandler [WEAK] + EXPORT PVM_IRQHandler [WEAK] + EXPORT ERTC_IRQHandler [WEAK] + EXPORT FLASH_IRQHandler [WEAK] + EXPORT CRM_IRQHandler [WEAK] + EXPORT EXINT1_0_IRQHandler [WEAK] + EXPORT EXINT3_2_IRQHandler [WEAK] + EXPORT EXINT15_4_IRQHandler [WEAK] + EXPORT ACC_IRQHandler [WEAK] + EXPORT DMA1_Channel1_IRQHandler [WEAK] + EXPORT DMA1_Channel3_2_IRQHandler [WEAK] + EXPORT DMA1_Channel7_4_IRQHandler [WEAK] + EXPORT ADC1_IRQHandler [WEAK] + EXPORT TMR1_BRK_OVF_TRG_HALL_IRQHandler [WEAK] + EXPORT TMR1_CH_IRQHandler [WEAK] + EXPORT TMR2_GLOBAL_IRQHandler [WEAK] + EXPORT TMR3_GLOBAL_IRQHandler [WEAK] + EXPORT TMR6_GLOBAL_IRQHandler [WEAK] + EXPORT TMR7_GLOBAL_IRQHandler [WEAK] + EXPORT TMR14_GLOBAL_IRQHandler [WEAK] + EXPORT TMR15_GLOBAL_IRQHandler [WEAK] + EXPORT TMR16_GLOBAL_IRQHandler [WEAK] + EXPORT TMR17_GLOBAL_IRQHandler [WEAK] + EXPORT I2C1_EVT_IRQHandler [WEAK] + EXPORT I2C2_EVT_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT SPI2_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT USART2_IRQHandler [WEAK] + EXPORT USART4_3_IRQHandler [WEAK] + EXPORT CAN1_IRQHandler [WEAK] + EXPORT OTGFS1_IRQHandler [WEAK] + EXPORT I2C1_ERR_IRQHandler [WEAK] + EXPORT SPI3_IRQHandler [WEAK] + EXPORT I2C2_ERR_IRQHandler [WEAK] + EXPORT TMR13_GLOBAL_IRQHandler [WEAK] +WWDT_IRQHandler +PVM_IRQHandler +ERTC_IRQHandler +FLASH_IRQHandler +CRM_IRQHandler +EXINT1_0_IRQHandler +EXINT3_2_IRQHandler +EXINT15_4_IRQHandler +ACC_IRQHandler +DMA1_Channel1_IRQHandler +DMA1_Channel3_2_IRQHandler +DMA1_Channel7_4_IRQHandler +ADC1_IRQHandler +TMR1_BRK_OVF_TRG_HALL_IRQHandler +TMR1_CH_IRQHandler +TMR2_GLOBAL_IRQHandler +TMR3_GLOBAL_IRQHandler +TMR6_GLOBAL_IRQHandler +TMR7_GLOBAL_IRQHandler +TMR14_GLOBAL_IRQHandler +TMR15_GLOBAL_IRQHandler +TMR16_GLOBAL_IRQHandler +TMR17_GLOBAL_IRQHandler +I2C1_EVT_IRQHandler +I2C2_EVT_IRQHandler +SPI1_IRQHandler +SPI2_IRQHandler +USART1_IRQHandler +USART2_IRQHandler +USART4_3_IRQHandler +CAN1_IRQHandler +OTGFS1_IRQHandler +I2C1_ERR_IRQHandler +SPI3_IRQHandler +I2C2_ERR_IRQHandler +TMR13_GLOBAL_IRQHandler + B . + + ENDP + + ALIGN + +;******************************************************************************* +; User Stack and Heap initialization +;******************************************************************************* + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap + + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + + ALIGN + + ENDIF + + END diff --git a/project/inc/at32f425_conf.h b/project/inc/at32f425_conf.h new file mode 100644 index 0000000..5be8405 --- /dev/null +++ b/project/inc/at32f425_conf.h @@ -0,0 +1,147 @@ +/* add user code begin Header */ +/** + ************************************************************************** + * @file at32f425_conf.h + * @brief at32f425 config header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ +/* add user code end Header */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_CONF_H +#define __AT32F425_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief in the following line adjust the value of high speed external crystal (hext) + * used in your application + * + * tip: to avoid modifying this file each time you need to use different hext, you + * can define the hext value in your toolchain compiler preprocessor. + * + */ +#if !defined HEXT_VALUE +#define HEXT_VALUE ((uint32_t)16000000) /*!< value of the high speed external crystal in hz */ +#endif + +/** + * @brief in the following line adjust the high speed external crystal (hext) startup + * timeout value + */ +#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */ +#define HICK_VALUE ((uint32_t)8000000) /*!< value of the high speed internal clock in hz */ +#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed external clock in hz */ + +/* module define -------------------------------------------------------------*/ +/*#define ACC_MODULE_ENABLED----------------------*/ +#define CRM_MODULE_ENABLED +#define TMR_MODULE_ENABLED +/*#define ERTC_MODULE_ENABLED---------------------*/ +#define GPIO_MODULE_ENABLED +/*#define I2C_MODULE_ENABLED----------------------*/ +#define CAN_MODULE_ENABLED +/*#define USB_MODULE_ENABLED----------------------*/ +#define USART_MODULE_ENABLED +#define PWC_MODULE_ENABLED +/*#define ADC_MODULE_ENABLED----------------------*/ +/*#define SPI_MODULE_ENABLED----------------------*/ +/*#define DMA_MODULE_ENABLED----------------------*/ +#define DEBUG_MODULE_ENABLED +#define FLASH_MODULE_ENABLED +/*#define CRC_MODULE_ENABLED----------------------*/ +/*#define WWDT_MODULE_ENABLED---------------------*/ +/*#define WDT_MODULE_ENABLED----------------------*/ +/*#define EXINT_MODULE_ENABLED--------------------*/ +#define MISC_MODULE_ENABLED +/*#define SCFG_MODULE_ENABLED---------------------*/ + +/* includes ------------------------------------------------------------------*/ +#ifdef ACC_MODULE_ENABLED +#include "at32f425_acc.h" +#endif +#ifdef CRM_MODULE_ENABLED +#include "at32f425_crm.h" +#endif +#ifdef CAN_MODULE_ENABLED +#include "at32f425_can.h" +#endif +#ifdef USB_MODULE_ENABLED +#include "at32f425_usb.h" +#endif +#ifdef TMR_MODULE_ENABLED +#include "at32f425_tmr.h" +#endif +#ifdef ERTC_MODULE_ENABLED +#include "at32f425_ertc.h" +#endif +#ifdef GPIO_MODULE_ENABLED +#include "at32f425_gpio.h" +#endif +#ifdef I2C_MODULE_ENABLED +#include "at32f425_i2c.h" +#endif +#ifdef USART_MODULE_ENABLED +#include "at32f425_usart.h" +#endif +#ifdef PWC_MODULE_ENABLED +#include "at32f425_pwc.h" +#endif +#ifdef ADC_MODULE_ENABLED +#include "at32f425_adc.h" +#endif +#ifdef SPI_MODULE_ENABLED +#include "at32f425_spi.h" +#endif +#ifdef DMA_MODULE_ENABLED +#include "at32f425_dma.h" +#endif +#ifdef DEBUG_MODULE_ENABLED +#include "at32f425_debug.h" +#endif +#ifdef FLASH_MODULE_ENABLED +#include "at32f425_flash.h" +#endif +#ifdef CRC_MODULE_ENABLED +#include "at32f425_crc.h" +#endif +#ifdef WWDT_MODULE_ENABLED +#include "at32f425_wwdt.h" +#endif +#ifdef WDT_MODULE_ENABLED +#include "at32f425_wdt.h" +#endif +#ifdef EXINT_MODULE_ENABLED +#include "at32f425_exint.h" +#endif +#ifdef MISC_MODULE_ENABLED +#include "at32f425_misc.h" +#endif +#ifdef SCFG_MODULE_ENABLED +#include "at32f425_scfg.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/inc/at32f425_int.h b/project/inc/at32f425_int.h new file mode 100644 index 0000000..8c1f8a3 --- /dev/null +++ b/project/inc/at32f425_int.h @@ -0,0 +1,79 @@ +/* add user code begin Header */ +/** + ************************************************************************** + * @file at32f425_int.h + * @brief header file of main interrupt service routines. + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ +/* add user code end Header */ + +/* define to prevent recursive inclusion -------------------------------------*/ +#ifndef __AT32F425_INT_H +#define __AT32F425_INT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* includes ------------------------------------------------------------------*/ +#include "at32f425.h" + +/* private includes ----------------------------------------------------------*/ +/* add user code begin private includes */ + +/* add user code end private includes */ + +/* exported types ------------------------------------------------------------*/ +/* add user code begin exported types */ + +/* add user code end exported types */ + +/* exported constants --------------------------------------------------------*/ +/* add user code begin exported constants */ + +/* add user code end exported constants */ + +/* exported macro ------------------------------------------------------------*/ +/* add user code begin exported macro */ + +/* add user code end exported macro */ + +/* exported functions ------------------------------------------------------- */ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); + +void TMR6_GLOBAL_IRQHandler(void); +void TMR7_GLOBAL_IRQHandler(void); +void CAN1_IRQHandler(void); +/* add user code begin exported functions */ + +/* add user code end exported functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/inc/at32f425_wk_config.h b/project/inc/at32f425_wk_config.h new file mode 100644 index 0000000..c52fe1e --- /dev/null +++ b/project/inc/at32f425_wk_config.h @@ -0,0 +1,100 @@ +/* add user code begin Header */ +/** + ************************************************************************** + * @file at32f425_wk_config.h + * @brief header file of work bench config + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ +/* add user code end Header */ + +/* define to prevent recursive inclusion -----------------------------------*/ +#ifndef __AT32F425_WK_CONFIG_H +#define __AT32F425_WK_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* includes -----------------------------------------------------------------------*/ +#include "at32f425.h" + +/* private includes -------------------------------------------------------------*/ +/* add user code begin private includes */ + +/* add user code end private includes */ + +/* exported types -------------------------------------------------------------*/ +/* add user code begin exported types */ + +/* add user code end exported types */ + +/* exported constants --------------------------------------------------------*/ +/* add user code begin exported constants */ + +/* add user code end exported constants */ + +/* exported macro ------------------------------------------------------------*/ +/* add user code begin exported macro */ + +/* add user code end exported macro */ + +/* exported functions ------------------------------------------------------- */ + /* system clock config. */ + void wk_system_clock_config(void); + + /* config periph clock. */ + void wk_periph_clock_config(void); + + /* nvic config. */ + void wk_nvic_config(void); + + /* init gpio function. */ + void wk_gpio_config(void); + + /* init can1 function. */ + void wk_can1_init(void); + + /* init tmr1 function. */ + void wk_tmr1_init(void); + + /* init tmr2 function. */ + void wk_tmr2_init(void); + + /* init tmr3 function. */ + void wk_tmr3_init(void); + + /* init tmr6 function. */ + void wk_tmr6_init(void); + + /* init tmr7 function. */ + void wk_tmr7_init(void); + + /* init usart1 function. */ + void wk_usart1_init(void); + +/* add user code begin exported functions */ + +/* add user code end exported functions */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/project/inc/by_debug.h b/project/inc/by_debug.h new file mode 100644 index 0000000..2d1403b --- /dev/null +++ b/project/inc/by_debug.h @@ -0,0 +1,35 @@ +#ifndef _BY_DEBUG_H__ +#define _BY_DEBUG_H__ + +#include +#include "at32f425.h" +#include "lwprintf.h" + +#define BY_DEBUG_USART_INDEX (USART1) + +#define BY_DEBUG_LOG_MODE (2) // 0-not log, 1-no debug log, 2-all + +#if (BY_DEBUG_LOG_MODE == 2) +#define LOGI(format, ...) lwprintf("[INFO] " format "\r\n", ##__VA_ARGS__) +#define LOGW(format, ...) lwprintf("[WARN] " format "\r\n", ##__VA_ARGS__) +#define LOGE(format, ...) lwprintf("[ERR] " format "\r\n", ##__VA_ARGS__) +#define LOGD(format, ...) lwprintf("[DEBUG] " format "\r\n", ##__VA_ARGS__) +#elif (BY_DEBUG_LOG_MODE == 1) +#define LOGI(format, ...) lwprintf("[INFO] " format "\r\n", ##__VA_ARGS__) +#define LOGW(format, ...) lwprintf("[WARN] " format "\r\n", ##__VA_ARGS__) +#define LOGE(format, ...) lwprintf("[ERR] " format "\r\n", ##__VA_ARGS__) +#define LOGD(format, ...) +#elif (BY_DEBUG_LOG_MODE == 0) +#define LOGI(format, ...) +#define LOGW(format, ...) +#define LOGE(format, ...) +#define LOGD(format, ...) +#endif + +extern void by_debug_init(void); +extern void delay_init(void); +extern void delay_us(uint32_t nus); +extern void delay_ms(uint16_t nms); +extern void delay_sec(uint16_t sec); + +#endif diff --git a/project/src/at32f425_int.c b/project/src/at32f425_int.c new file mode 100644 index 0000000..7fc230b --- /dev/null +++ b/project/src/at32f425_int.c @@ -0,0 +1,264 @@ +/* add user code begin Header */ +/** + ************************************************************************** + * @file at32f425_int.c + * @brief main interrupt service routines. + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ +/* add user code end Header */ + +/* includes ------------------------------------------------------------------*/ +#include "at32f425_int.h" + +/* private includes ----------------------------------------------------------*/ +/* add user code begin private includes */ +#include "by_debug.h" +#include "by_motion.h" +/* add user code end private includes */ + +/* private typedef -----------------------------------------------------------*/ +/* add user code begin private typedef */ + +/* add user code end private typedef */ + +/* private define ------------------------------------------------------------*/ +/* add user code begin private define */ + +/* add user code end private define */ + +/* private macro -------------------------------------------------------------*/ +/* add user code begin private macro */ + +/* add user code end private macro */ + +/* private variables ---------------------------------------------------------*/ +/* add user code begin private variables */ + +/* add user code end private variables */ + +/* private function prototypes --------------------------------------------*/ +/* add user code begin function prototypes */ + +/* add user code end function prototypes */ + +/* private user code ---------------------------------------------------------*/ +/* add user code begin 0 */ + +/* add user code end 0 */ + +/* external variables ---------------------------------------------------------*/ +/* add user code begin external variables */ + +/* add user code end external variables */ + +/** + * @brief this function handles nmi exception. + * @param none + * @retval none + */ +void NMI_Handler(void) +{ + /* add user code begin NonMaskableInt_IRQ 0 */ + + /* add user code end NonMaskableInt_IRQ 0 */ + + /* add user code begin NonMaskableInt_IRQ 1 */ + + /* add user code end NonMaskableInt_IRQ 1 */ +} + +/** + * @brief this function handles hard fault exception. + * @param none + * @retval none + */ +void HardFault_Handler(void) +{ + /* add user code begin HardFault_IRQ 0 */ + + /* add user code end HardFault_IRQ 0 */ + /* go to infinite loop when hard fault exception occurs */ + while (1) { + /* add user code begin W1_HardFault_IRQ 0 */ + + /* add user code end W1_HardFault_IRQ 0 */ + } +} + +/** + * @brief this function handles memory manage exception. + * @param none + * @retval none + */ +void MemManage_Handler(void) +{ + /* add user code begin MemoryManagement_IRQ 0 */ + + /* add user code end MemoryManagement_IRQ 0 */ + /* go to infinite loop when memory manage exception occurs */ + while (1) { + /* add user code begin W1_MemoryManagement_IRQ 0 */ + + /* add user code end W1_MemoryManagement_IRQ 0 */ + } +} + +/** + * @brief this function handles bus fault exception. + * @param none + * @retval none + */ +void BusFault_Handler(void) +{ + /* add user code begin BusFault_IRQ 0 */ + + /* add user code end BusFault_IRQ 0 */ + /* go to infinite loop when bus fault exception occurs */ + while (1) { + /* add user code begin W1_BusFault_IRQ 0 */ + + /* add user code end W1_BusFault_IRQ 0 */ + } +} + +/** + * @brief this function handles usage fault exception. + * @param none + * @retval none + */ +void UsageFault_Handler(void) +{ + /* add user code begin UsageFault_IRQ 0 */ + + /* add user code end UsageFault_IRQ 0 */ + /* go to infinite loop when usage fault exception occurs */ + while (1) { + /* add user code begin W1_UsageFault_IRQ 0 */ + + /* add user code end W1_UsageFault_IRQ 0 */ + } +} + +/** + * @brief this function handles svcall exception. + * @param none + * @retval none + */ +void SVC_Handler(void) +{ + /* add user code begin SVCall_IRQ 0 */ + + /* add user code end SVCall_IRQ 0 */ + /* add user code begin SVCall_IRQ 1 */ + + /* add user code end SVCall_IRQ 1 */ +} + +/** + * @brief this function handles debug monitor exception. + * @param none + * @retval none + */ +void DebugMon_Handler(void) +{ + /* add user code begin DebugMonitor_IRQ 0 */ + + /* add user code end DebugMonitor_IRQ 0 */ + /* add user code begin DebugMonitor_IRQ 1 */ + + /* add user code end DebugMonitor_IRQ 1 */ +} + +/** + * @brief this function handles pendsv_handler exception. + * @param none + * @retval none + */ +void PendSV_Handler(void) +{ + /* add user code begin PendSV_IRQ 0 */ + + /* add user code end PendSV_IRQ 0 */ + /* add user code begin PendSV_IRQ 1 */ + + /* add user code end PendSV_IRQ 1 */ +} + +/** + * @brief this function handles TMR6 handler. + * @param none + * @retval none + */ +void TMR6_GLOBAL_IRQHandler(void) +{ + /* add user code begin TMR6_GLOBAL_IRQ 0 */ + if (SET == tmr_interrupt_flag_get(TMR6, TMR_OVF_FLAG)) { + by_motion_run(); + tmr_flag_clear(TMR6, TMR_OVF_FLAG); + } + /* add user code end TMR6_GLOBAL_IRQ 0 */ + /* add user code begin TMR6_GLOBAL_IRQ 1 */ + + /* add user code end TMR6_GLOBAL_IRQ 1 */ +} + +/** + * @brief this function handles TMR7 handler. + * @param none + * @retval none + */ +void TMR7_GLOBAL_IRQHandler(void) +{ + /* add user code begin TMR7_GLOBAL_IRQ 0 */ + if (SET == tmr_interrupt_flag_get(TMR7, TMR_OVF_FLAG)) { + by_motion_tmr_handle(); + tmr_flag_clear(TMR7, TMR_OVF_FLAG); + } + /* add user code end TMR7_GLOBAL_IRQ 0 */ + /* add user code begin TMR7_GLOBAL_IRQ 1 */ + + /* add user code end TMR7_GLOBAL_IRQ 1 */ +} + +/** + * @brief this function handles CAN1 handler. + * @param none + * @retval none + */ +void CAN1_IRQHandler(void) +{ + /* add user code begin CAN1_IRQ 0 */ + if (SET == can_flag_get(CAN1, CAN_RF0MN_FLAG)) { + + can_rx_message_type can_rx_message; + can_message_receive(CAN1, CAN_RX_FIFO0, &can_rx_message); + by_motion_can_handle((uint16_t)can_rx_message.standard_id, can_rx_message.data, can_rx_message.dlc); + + can_flag_clear(CAN1, CAN_RF0MN_FLAG); + } + /* add user code end CAN1_IRQ 0 */ + /* add user code begin CAN1_IRQ 1 */ + + /* add user code end CAN1_IRQ 1 */ +} + +/* add user code begin 1 */ + +/* add user code end 1 */ diff --git a/project/src/at32f425_wk_config.c b/project/src/at32f425_wk_config.c new file mode 100644 index 0000000..cf41fd3 --- /dev/null +++ b/project/src/at32f425_wk_config.c @@ -0,0 +1,746 @@ +/* add user code begin Header */ +/** + ************************************************************************** + * @file at32f425_wk_config.c + * @brief work bench config program + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ +/* add user code end Header */ + +#include "at32f425_wk_config.h" + +/* private includes ----------------------------------------------------------*/ +/* add user code begin private includes */ + +/* add user code end private includes */ + +/* private typedef -----------------------------------------------------------*/ +/* add user code begin private typedef */ + +/* add user code end private typedef */ + +/* private define ------------------------------------------------------------*/ +/* add user code begin private define */ + +/* add user code end private define */ + +/* private macro -------------------------------------------------------------*/ +/* add user code begin private macro */ + +/* add user code end private macro */ + +/* private variables ---------------------------------------------------------*/ +/* add user code begin private variables */ + +/* add user code end private variables */ + +/* private function prototypes --------------------------------------------*/ +/* add user code begin function prototypes */ + +/* add user code end function prototypes */ + +/* private user code ---------------------------------------------------------*/ +/* add user code begin 0 */ + +/* add user code end 0 */ + +/** + * @brief system clock config program + * @note the system clock is configured as follow: + * system clock (sclk) = hext * pll_mult + * system clock source = HEXT_VALUE + * - hext = HEXT_VALUE + * - sclk = 96000000 + * - ahbdiv = 1 + * - ahbclk = 96000000 + * - apb1div = 1 + * - apb1clk = 96000000 + * - apb2div = 1 + * - apb2clk = 96000000 + * - pll_mult = 6 + * - flash_wtcyc = 2 cycle + * @param none + * @retval none + */ +void wk_system_clock_config(void) +{ + /* reset crm */ + crm_reset(); + + /* config flash psr register */ + flash_psr_set(FLASH_WAIT_CYCLE_2); + + /* enable lick */ + crm_clock_source_enable(CRM_CLOCK_SOURCE_LICK, TRUE); + + /* wait till lick is ready */ + while (crm_flag_get(CRM_LICK_STABLE_FLAG) != SET) { + } + + /* enable hext */ + crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE); + + /* wait till hext is ready */ + while (crm_hext_stable_wait() == ERROR) { + } + + /* enable hick */ + crm_clock_source_enable(CRM_CLOCK_SOURCE_HICK, TRUE); + + /* wait till hick is ready */ + while (crm_flag_get(CRM_HICK_STABLE_FLAG) != SET) { + } + + /* config pll clock resource */ + crm_pll_config(CRM_PLL_SOURCE_HEXT, CRM_PLL_MULT_6); + + /* enable pll */ + crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE); + + /* wait till pll is ready */ + while (crm_flag_get(CRM_PLL_STABLE_FLAG) != SET) { + } + + /* config ahbclk */ + crm_ahb_div_set(CRM_AHB_DIV_1); + + /* config apb2clk */ + crm_apb2_div_set(CRM_APB2_DIV_1); + + /* config apb1clk */ + crm_apb1_div_set(CRM_APB1_DIV_1); + + /* select pll as system clock source */ + crm_sysclk_switch(CRM_SCLK_PLL); + + /* wait till pll is used as system clock source */ + while (crm_sysclk_switch_status_get() != CRM_SCLK_PLL) { + } + + /* update system_core_clock global variable */ + system_core_clock_update(); +} + +/** + * @brief config periph clock + * @param none + * @retval none + */ +void wk_periph_clock_config(void) +{ + /* enable gpioa periph clock */ + crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); + + /* enable gpiob periph clock */ + crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); + + /* enable gpiof periph clock */ + crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, TRUE); + + /* enable tmr1 periph clock */ + crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE); + + /* enable usart1 periph clock */ + crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE); + + /* enable tmr2 periph clock */ + crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE); + + /* enable tmr3 periph clock */ + crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE); + + /* enable tmr6 periph clock */ + crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, TRUE); + + /* enable tmr7 periph clock */ + crm_periph_clock_enable(CRM_TMR7_PERIPH_CLOCK, TRUE); + + /* enable can1 periph clock */ + crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE); +} + +/** + * @brief nvic config + * @param none + * @retval none + */ +void wk_nvic_config(void) +{ + nvic_priority_group_config(NVIC_PRIORITY_GROUP_4); + + nvic_irq_enable(TMR6_GLOBAL_IRQn, 0, 0); + nvic_irq_enable(TMR7_GLOBAL_IRQn, 0, 0); + nvic_irq_enable(CAN1_IRQn, 0, 0); +} + +/** + * @brief init gpio_input/gpio_output/gpio_analog/eventout function. + * @param none + * @retval none + */ +void wk_gpio_config(void) +{ + /* add user code begin gpio_config 0 */ + + /* add user code end gpio_config 0 */ + + gpio_init_type gpio_init_struct; + gpio_default_para_init(&gpio_init_struct); + + /* add user code begin gpio_config 1 */ + + /* add user code end gpio_config 1 */ + + /* gpio input config */ + gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; + gpio_init_struct.gpio_pins = GPIO_PINS_4 | GPIO_PINS_5; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init(GPIOB, &gpio_init_struct); + + /* gpio output config */ + gpio_bits_reset(GPIOA, GPIO_PINS_12); + + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; + gpio_init_struct.gpio_pins = GPIO_PINS_12; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init(GPIOA, &gpio_init_struct); + + /* add user code begin gpio_config 2 */ + + /* add user code end gpio_config 2 */ +} + +/** + * @brief init tmr1 function. + * @param none + * @retval none + */ +void wk_tmr1_init(void) +{ + /* add user code begin tmr1_init 0 */ + + /* add user code end tmr1_init 0 */ + + gpio_init_type gpio_init_struct; + tmr_output_config_type tmr_output_struct; + tmr_brkdt_config_type tmr_brkdt_struct; + + gpio_default_para_init(&gpio_init_struct); + + /* add user code begin tmr1_init 1 */ + + /* add user code end tmr1_init 1 */ + + /* configure the tmr1 CH1 pin */ + gpio_init_struct.gpio_pins = GPIO_PINS_8; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE8, GPIO_MUX_2); + + /* configure the tmr1 CH2 pin */ + gpio_init_struct.gpio_pins = GPIO_PINS_9; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE9, GPIO_MUX_2); + + /* configure the tmr1 CH3 pin */ + gpio_init_struct.gpio_pins = GPIO_PINS_10; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE10, GPIO_MUX_2); + + /* configure the tmr1 CH4 pin */ + gpio_init_struct.gpio_pins = GPIO_PINS_11; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE11, GPIO_MUX_2); + + /* configure counter settings */ + tmr_base_init(TMR1, 999, 5); + tmr_cnt_dir_set(TMR1, TMR_COUNT_UP); + tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1); + tmr_repetition_counter_set(TMR1, 0); + tmr_period_buffer_enable(TMR1, FALSE); + + /* configure primary mode settings */ + tmr_sub_sync_mode_set(TMR1, FALSE); + tmr_primary_mode_select(TMR1, TMR_PRIMARY_SEL_RESET); + + /* configure channel 1 output settings */ + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; + tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.occ_output_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; + tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_output_struct); + tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, 0); + tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_1, FALSE); + + tmr_output_channel_immediately_set(TMR1, TMR_SELECT_CHANNEL_1, FALSE); + + /* configure channel 2 output settings */ + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; + tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.occ_output_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; + tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_2, &tmr_output_struct); + tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_2, 0); + tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_2, FALSE); + + tmr_output_channel_immediately_set(TMR1, TMR_SELECT_CHANNEL_2, FALSE); + + /* configure channel 3 output settings */ + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; + tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.occ_output_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; + tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_3, &tmr_output_struct); + tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_3, 0); + tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_3, FALSE); + + tmr_output_channel_immediately_set(TMR1, TMR_SELECT_CHANNEL_3, FALSE); + + /* configure channel 4 output settings */ + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; + tmr_output_struct.oc_output_state = TRUE; + tmr_output_struct.occ_output_state = FALSE; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_idle_state = FALSE; + tmr_output_struct.occ_idle_state = FALSE; + tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_4, &tmr_output_struct); + tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_4, 0); + tmr_output_channel_buffer_enable(TMR1, TMR_SELECT_CHANNEL_4, FALSE); + + tmr_output_channel_immediately_set(TMR1, TMR_SELECT_CHANNEL_4, FALSE); + + /* configure break and dead-time settings */ + tmr_brkdt_struct.brk_enable = FALSE; + tmr_brkdt_struct.auto_output_enable = FALSE; + tmr_brkdt_struct.brk_polarity = TMR_BRK_INPUT_ACTIVE_LOW; + tmr_brkdt_struct.fcsoen_state = FALSE; + tmr_brkdt_struct.fcsodis_state = FALSE; + tmr_brkdt_struct.wp_level = TMR_WP_OFF; + tmr_brkdt_struct.deadtime = 0; + tmr_brkdt_config(TMR1, &tmr_brkdt_struct); + + tmr_brk_filter_value_set(TMR1, 0); + + tmr_output_enable(TMR1, TRUE); + + tmr_counter_enable(TMR1, TRUE); + + /* add user code begin tmr1_init 2 */ + + /* add user code end tmr1_init 2 */ +} + +/** + * @brief init tmr2 function. + * @param none + * @retval none + */ +void wk_tmr2_init(void) +{ + /* add user code begin tmr2_init 0 */ + + /* add user code end tmr2_init 0 */ + + gpio_init_type gpio_init_struct; + tmr_input_config_type tmr_input_struct; + + gpio_default_para_init(&gpio_init_struct); + + /* add user code begin tmr2_init 1 */ + + /* add user code end tmr2_init 1 */ + + /* configure the tmr2 CH1 pin */ + gpio_init_struct.gpio_pins = GPIO_PINS_0; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE0, GPIO_MUX_2); + + /* configure the tmr2 CH2 pin */ + gpio_init_struct.gpio_pins = GPIO_PINS_1; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE1, GPIO_MUX_2); + + /* configure counter settings */ + tmr_base_init(TMR2, 65535, 0); + tmr_cnt_dir_set(TMR2, TMR_COUNT_UP); + tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1); + tmr_period_buffer_enable(TMR2, FALSE); + + /* configure primary mode settings */ + tmr_sub_sync_mode_set(TMR2, FALSE); + tmr_primary_mode_select(TMR2, TMR_PRIMARY_SEL_RESET); + + /* configure encoder mode */ + tmr_input_struct.input_channel_select = TMR_SELECT_CHANNEL_1; + tmr_input_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT; + tmr_input_struct.input_polarity_select = TMR_INPUT_RISING_EDGE; + tmr_input_struct.input_filter_value = 0; + tmr_input_channel_init(TMR2, &tmr_input_struct, TMR_CHANNEL_INPUT_DIV_1); + + tmr_input_struct.input_channel_select = TMR_SELECT_CHANNEL_2; + tmr_input_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT; + tmr_input_struct.input_polarity_select = TMR_INPUT_RISING_EDGE; + tmr_input_struct.input_filter_value = 0; + tmr_input_channel_init(TMR2, &tmr_input_struct, TMR_CHANNEL_INPUT_DIV_1); + + tmr_encoder_mode_config(TMR2, TMR_ENCODER_MODE_A, TMR_INPUT_RISING_EDGE, TMR_INPUT_RISING_EDGE); + + tmr_counter_enable(TMR2, TRUE); + + /* add user code begin tmr2_init 2 */ + + /* add user code end tmr2_init 2 */ +} + +/** + * @brief init tmr3 function. + * @param none + * @retval none + */ +void wk_tmr3_init(void) +{ + /* add user code begin tmr3_init 0 */ + + /* add user code end tmr3_init 0 */ + + gpio_init_type gpio_init_struct; + tmr_input_config_type tmr_input_struct; + + gpio_default_para_init(&gpio_init_struct); + + /* add user code begin tmr3_init 1 */ + + /* add user code end tmr3_init 1 */ + + /* configure the tmr3 CH1 pin */ + gpio_init_struct.gpio_pins = GPIO_PINS_6; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_1); + + /* configure the tmr3 CH2 pin */ + gpio_init_struct.gpio_pins = GPIO_PINS_7; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_1); + + /* configure counter settings */ + tmr_base_init(TMR3, 65535, 0); + tmr_cnt_dir_set(TMR3, TMR_COUNT_UP); + tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1); + tmr_period_buffer_enable(TMR3, FALSE); + + /* configure primary mode settings */ + tmr_sub_sync_mode_set(TMR3, FALSE); + tmr_primary_mode_select(TMR3, TMR_PRIMARY_SEL_RESET); + + /* configure encoder mode */ + tmr_input_struct.input_channel_select = TMR_SELECT_CHANNEL_1; + tmr_input_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT; + tmr_input_struct.input_polarity_select = TMR_INPUT_RISING_EDGE; + tmr_input_struct.input_filter_value = 0; + tmr_input_channel_init(TMR3, &tmr_input_struct, TMR_CHANNEL_INPUT_DIV_1); + + tmr_input_struct.input_channel_select = TMR_SELECT_CHANNEL_2; + tmr_input_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT; + tmr_input_struct.input_polarity_select = TMR_INPUT_RISING_EDGE; + tmr_input_struct.input_filter_value = 0; + tmr_input_channel_init(TMR3, &tmr_input_struct, TMR_CHANNEL_INPUT_DIV_1); + + tmr_encoder_mode_config(TMR3, TMR_ENCODER_MODE_A, TMR_INPUT_RISING_EDGE, TMR_INPUT_RISING_EDGE); + + tmr_counter_enable(TMR3, TRUE); + + /* add user code begin tmr3_init 2 */ + + /* add user code end tmr3_init 2 */ +} + +/** + * @brief init tmr6 function. + * @param none + * @retval none + */ +void wk_tmr6_init(void) +{ + /* add user code begin tmr6_init 0 */ + + /* add user code end tmr6_init 0 */ + + /* add user code begin tmr6_init 1 */ + + /* add user code end tmr6_init 1 */ + + /* configure counter settings */ + tmr_base_init(TMR6, 1999, 959); + tmr_cnt_dir_set(TMR6, TMR_COUNT_UP); + tmr_period_buffer_enable(TMR6, FALSE); + + /* configure primary mode settings */ + tmr_primary_mode_select(TMR6, TMR_PRIMARY_SEL_RESET); + + tmr_counter_enable(TMR6, TRUE); + + /** + * Users need to configure TMR6 interrupt functions according to the actual application. + * 1. Call the below function to enable the corresponding TMR6 interrupt. + * --tmr_interrupt_enable(...) + * 2. Add the user's interrupt handler code into the below function in the at32f425_int.c file. + * --void TMR6_GLOBAL_IRQHandler(void) + */ + + /* add user code begin tmr6_init 2 */ + tmr_interrupt_enable(TMR6, TMR_OVF_INT, TRUE); + /* add user code end tmr6_init 2 */ +} + +/** + * @brief init tmr7 function. + * @param none + * @retval none + */ +void wk_tmr7_init(void) +{ + /* add user code begin tmr7_init 0 */ + + /* add user code end tmr7_init 0 */ + + /* add user code begin tmr7_init 1 */ + + /* add user code end tmr7_init 1 */ + + /* configure counter settings */ + tmr_base_init(TMR7, 99, 19199); + tmr_cnt_dir_set(TMR7, TMR_COUNT_UP); + tmr_period_buffer_enable(TMR7, FALSE); + + /* configure primary mode settings */ + tmr_primary_mode_select(TMR7, TMR_PRIMARY_SEL_RESET); + + tmr_counter_enable(TMR7, TRUE); + + /** + * Users need to configure TMR7 interrupt functions according to the actual application. + * 1. Call the below function to enable the corresponding TMR7 interrupt. + * --tmr_interrupt_enable(...) + * 2. Add the user's interrupt handler code into the below function in the at32f425_int.c file. + * --void TMR7_GLOBAL_IRQHandler(void) + */ + + /* add user code begin tmr7_init 2 */ + tmr_interrupt_enable(TMR7, TMR_OVF_INT, TRUE); + /* add user code end tmr7_init 2 */ +} + +/** + * @brief init usart1 function + * @param none + * @retval none + */ +void wk_usart1_init(void) +{ + /* add user code begin usart1_init 0 */ + + /* add user code end usart1_init 0 */ + + gpio_init_type gpio_init_struct; + gpio_default_para_init(&gpio_init_struct); + + /* add user code begin usart1_init 1 */ + + /* add user code end usart1_init 1 */ + + /* configure the TX pin */ + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_6; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init(GPIOB, &gpio_init_struct); + + gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE6, GPIO_MUX_0); + + /* configure the RX pin */ + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_7; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init(GPIOB, &gpio_init_struct); + + gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE7, GPIO_MUX_0); + + /* configure param */ + usart_init(USART1, 115200, USART_DATA_8BITS, USART_STOP_1_BIT); + usart_transmitter_enable(USART1, TRUE); + usart_receiver_enable(USART1, TRUE); + usart_parity_selection_config(USART1, USART_PARITY_NONE); + + usart_hardware_flow_control_set(USART1, USART_HARDWARE_FLOW_NONE); + + usart_enable(USART1, TRUE); + + /* add user code begin usart1_init 2 */ + + /* add user code end usart1_init 2 */ +} + +/** + * @brief init can1 function. + * @param none + * @retval none + */ +void wk_can1_init(void) +{ + /* add user code begin can1_init 0 */ + + /* add user code end can1_init 0 */ + + gpio_init_type gpio_init_struct; + can_base_type can_base_struct; + can_baudrate_type can_baudrate_struct; + can_filter_init_type can_filter_init_struct; + + /* add user code begin can1_init 1 */ + + /* add user code end can1_init 1 */ + + /*gpio-----------------------------------------------------------------------------*/ + gpio_default_para_init(&gpio_init_struct); + + /* configure the CAN1 TX pin */ + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_3; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE3, GPIO_MUX_4); + + /* configure the CAN1 RX pin */ + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = GPIO_PINS_2; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init(GPIOA, &gpio_init_struct); + + gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE2, GPIO_MUX_4); + + /*can_base_init--------------------------------------------------------------------*/ + can_default_para_init(&can_base_struct); + can_base_struct.mode_selection = CAN_MODE_COMMUNICATE; + can_base_struct.ttc_enable = FALSE; + can_base_struct.aebo_enable = TRUE; + can_base_struct.aed_enable = TRUE; + can_base_struct.prsf_enable = FALSE; + can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED; + can_base_struct.mmssr_selection = CAN_SENDING_BY_ID; + + can_base_init(CAN1, &can_base_struct); + + /*can_baudrate_setting-------------------------------------------------------------*/ + /*set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size))------------------*/ + can_baudrate_struct.baudrate_div = 24; /*value: 1~0xFFF*/ + can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ; /*value: 1~4*/ + can_baudrate_struct.bts1_size = CAN_BTS1_6TQ; /*value: 1~16*/ + can_baudrate_struct.bts2_size = CAN_BTS2_1TQ; /*value: 1~8*/ + can_baudrate_set(CAN1, &can_baudrate_struct); + + /*can_filter_0_config--------------------------------------------------------------*/ + can_filter_init_struct.filter_activate_enable = TRUE; + can_filter_init_struct.filter_number = 0; + can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0; + can_filter_init_struct.filter_bit = CAN_FILTER_16BIT; + can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK; + /*Standard identifier + Mask Mode + Data/Remote frame: id/mask 11bit --------------*/ + can_filter_init_struct.filter_id_high = 0x0 << 5; + can_filter_init_struct.filter_id_low = 0x0 << 5; + can_filter_init_struct.filter_mask_high = 0x0 << 5; + can_filter_init_struct.filter_mask_low = 0x0 << 5; + + can_filter_init(CAN1, &can_filter_init_struct); + + /** + * Users need to configure CAN1 interrupt functions according to the actual application. + * 1. Call the below function to enable the corresponding CAN1 interrupt. + * --can_interrupt_enable(...) + * 2. Add the user's interrupt handler code into the below function in the at32f402_405_int.c file. + * --void CAN1_IRQHandler(void) + */ + + /* add user code begin can1_init 2 */ + can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE); + /* add user code end can1_init 2 */ +} + +/* add user code begin 1 */ + +/* add user code end 1 */ diff --git a/project/src/by_debug.c b/project/src/by_debug.c new file mode 100644 index 0000000..5b7d36f --- /dev/null +++ b/project/src/by_debug.c @@ -0,0 +1,98 @@ +#include "by_debug.h" + +#include "at32f425.h" +#include "lwprintf.h" + +/* delay macros */ +#define STEP_DELAY_MS 50 + +/* delay variable */ +static __IO uint32_t fac_us; +static __IO uint32_t fac_ms; + +int lwprintf_out(int ch, lwprintf_t *lwp) +{ + + /* May use printf to output it for test */ + + if (ch != '\0') { + while (usart_flag_get(BY_DEBUG_USART_INDEX, USART_TDC_FLAG) == RESET); + usart_data_transmit(BY_DEBUG_USART_INDEX, (char)ch); + } + + return ch; +} + +void by_debug_init(void) +{ + lwprintf_init(lwprintf_out); +} + +void delay_init(void) +{ + systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_DIV8); + crm_clocks_freq_type clocks; + crm_clocks_freq_get(&clocks); + fac_us = clocks.sclk_freq / (8000000U); + fac_ms = fac_us * (1000U); +} + +/** + * @brief inserts a delay time. + * @param nus: specifies the delay time length, in microsecond. + * @retval none + */ +void delay_us(uint32_t nus) +{ + uint32_t temp = 0; + SysTick->LOAD = (uint32_t)(nus * fac_us); + SysTick->VAL = 0x00; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + do { + temp = SysTick->CTRL; + } while ((temp & 0x01) && !(temp & (1 << 16))); + + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + SysTick->VAL = 0x00; +} + +/** + * @brief inserts a delay time. + * @param nms: specifies the delay time length, in milliseconds. + * @retval none + */ +void delay_ms(uint16_t nms) +{ + uint32_t temp = 0; + while (nms) { + if (nms > STEP_DELAY_MS) { + SysTick->LOAD = (uint32_t)(STEP_DELAY_MS * fac_ms); + nms -= STEP_DELAY_MS; + } else { + SysTick->LOAD = (uint32_t)(nms * fac_ms); + nms = 0; + } + SysTick->VAL = 0x00; + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + do { + temp = SysTick->CTRL; + } while ((temp & 0x01) && !(temp & (1 << 16))); + + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + SysTick->VAL = 0x00; + } +} + +/** + * @brief inserts a delay time. + * @param sec: specifies the delay time, in seconds. + * @retval none + */ +void delay_sec(uint16_t sec) +{ + uint16_t index; + for (index = 0; index < sec; index++) { + delay_ms(500); + delay_ms(500); + } +} \ No newline at end of file diff --git a/project/src/main.c b/project/src/main.c new file mode 100644 index 0000000..8cf0b8e --- /dev/null +++ b/project/src/main.c @@ -0,0 +1,124 @@ +/* add user code begin Header */ +/** + ************************************************************************** + * @file main.c + * @brief main program + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ +/* add user code end Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "at32f425_wk_config.h" + +/* private includes ----------------------------------------------------------*/ +/* add user code begin private includes */ +#include "by_debug.h" +#include "by_motion.h" +/* add user code end private includes */ + +/* private typedef -----------------------------------------------------------*/ +/* add user code begin private typedef */ + +/* add user code end private typedef */ + +/* private define ------------------------------------------------------------*/ +/* add user code begin private define */ + +/* add user code end private define */ + +/* private macro -------------------------------------------------------------*/ +/* add user code begin private macro */ + +/* add user code end private macro */ + +/* private variables ---------------------------------------------------------*/ +/* add user code begin private variables */ + +/* add user code end private variables */ + +/* private function prototypes --------------------------------------------*/ +/* add user code begin function prototypes */ + +/* add user code end function prototypes */ + +/* private user code ---------------------------------------------------------*/ +/* add user code begin 0 */ + +/* add user code end 0 */ + +/** + * @brief main function. + * @param none + * @retval none + */ +int main(void) +{ + /* add user code begin 1 */ + by_debug_init(); + /* add user code end 1 */ + + /* system clock config. */ + wk_system_clock_config(); + + /* config periph clock. */ + wk_periph_clock_config(); + + /* nvic config. */ + wk_nvic_config(); + + /* init usart1 function. */ + wk_usart1_init(); + + /* init can1 function. */ + wk_can1_init(); + + /* init gpio function. */ + wk_gpio_config(); + + /* init tmr1 function. */ + wk_tmr1_init(); + + /* init tmr2 function. */ + wk_tmr2_init(); + + /* init tmr3 function. */ + wk_tmr3_init(); + + /* init tmr6 function. */ + wk_tmr6_init(); + + /* init tmr7 function. */ + wk_tmr7_init(); + + /* add user code begin 2 */ + delay_init(); + LOGD("init delay"); + + by_motion_init(); + LOGD("init motion"); + /* add user code end 2 */ + + while(1) + { + /* add user code begin 3 */ + lwprintf("%f, %f, %f\r\n", param_m1.real_speed, param_m1.target_speed, param_m1.out_pwm); + /* add user code end 3 */ + } +}