diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ebe85c735e..1f83ff9475 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,7 +31,8 @@ jobs: -//software/ai/hl/... \ -//software/field_tests/... \ -//software/embedded/... \ - -//toolchains/cc/... + -//toolchains/cc/... \ + -//firmware/... - name: Jetson Nano Build Test run: | @@ -43,6 +44,22 @@ jobs: cd src bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=PI --platforms=//toolchains/cc:robot + - name: Motor Firmware build Test + run: | + cd src + bazel build //firmware/motor:mdv6_firmware_main --platforms=//toolchains/cc:motor_board + + motor-firmare: + name: Motor Firmware + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/environment-setup + + - name: Build Motor Firmware + run: | + cd src + bazel build //firmware/motor:mdv6_firmware_main --platforms=//toolchains/cc:motor_board software-tests: name: Software Tests @@ -60,7 +77,8 @@ jobs: -//software/ai/hl/... \ -//software/field_tests/... \ -//software/ai/navigator/... \ - -//toolchains/cc/... + -//toolchains/cc/... \ + -//firmware/... robot-tests: name: Robot Software Tests diff --git a/environment_setup/setup_software.sh b/environment_setup/setup_software.sh index f3701b7087..ac1768905d 100755 --- a/environment_setup/setup_software.sh +++ b/environment_setup/setup_software.sh @@ -196,4 +196,8 @@ print_status_msg "Set up ansible-lint" /opt/tbotspython/bin/ansible-galaxy collection install ansible.posix print_status_msg "Finished setting up ansible-lint" +print_status_msg "Setting up STM32 cross-compiler" +install_stm32_cross_compiler $g_arch +print_status_msg "Done setting up STM32 cross-compiler" + print_status_msg "Done Software Setup, please reboot for changes to take place" diff --git a/environment_setup/util.sh b/environment_setup/util.sh index e3603b5510..d0999698cd 100755 --- a/environment_setup/util.sh +++ b/environment_setup/util.sh @@ -90,6 +90,19 @@ install_python_dev_cross_compile_headers() { rm -rf /tmp/tbots_download_cache/python-3.12.0.tar.xz } +install_stm32_cross_compiler() { + arch="aarch64" + if is_x86 $1; then + arch="x86_64" + fi + download_link=https://developer.arm.com/-/media/Files/downloads/gnu/14.3.rel1/binrel/arm-gnu-toolchain-14.3.rel1-${arch}-arm-none-eabi.tar.xz + + wget -N $download_link -O /tmp/tbots_download_cache/arm-gnu-toolchain.tar.xz + tar -xf /tmp/tbots_download_cache/arm-gnu-toolchain.tar.xz -C /tmp/tbots_download_cache/ + sudo mv /tmp/tbots_download_cache/arm-gnu-toolchain-14.3.rel1-${arch}-arm-none-eabi /opt/tbotspython/arm-none-eabi-gcc + rm /tmp/tbots_download_cache/arm-gnu-toolchain.tar.xz +} + is_x86() { if [[ $1 == "x86_64" ]]; then return 0 diff --git a/src/MODULE.bazel b/src/MODULE.bazel index 7c1597ca68..7954f4ca98 100644 --- a/src/MODULE.bazel +++ b/src/MODULE.bazel @@ -202,6 +202,17 @@ http_archive( url = "https://github.com/saebyn/munkres-cpp/archive/61086fcf5b3a8ad4bda578cdc2d1dca57b548786.tar.gz", ) +# For flashing the motor driver board +http_archive( + name = "bazel_embedded", + sha256 = "91a78efbb0f94479fe9ca2912aced712be9e7028325bada9a73e7d325427b404", + strip_prefix = "bazel-embedded-cf5b240d510313b3383e0cdb550eb9f32be7244e", + url = "https://github.com/bazelembedded/bazel-embedded/archive/cf5b240d510313b3383e0cdb550eb9f32be7244e.zip", +) + +openocd = use_extension("//:defs.bzl", "openocd_extension") +use_repo(openocd, "com_openocd") + http_archive( name = "LTC4151", build_file = "@//extlibs:LTC4151.BUILD", @@ -233,6 +244,7 @@ register_toolchains( "//toolchains/cc:cc_toolchain_for_k8_jetson_nano_cross_compile", "//toolchains/cc:cc_toolchain_for_k8", "//toolchains/cc:cc_toolchain_for_aarch64", + "//toolchains/cc:cc_toolchain_for_stm32", ) ############################################## @@ -265,6 +277,12 @@ new_local_repository( path = "/opt/tbotspython/aarch64-tbots-linux-gnu/", ) +new_local_repository( + name = "motor_board_gcc", + build_file = "@//extlibs:motor_board_gcc.BUILD", + path = "/opt/tbotspython/arm-none-eabi-gcc/", +) + new_local_repository( name = "py_cc_toolchain_host", build_file = "@//extlibs:py_cc_toolchain.BUILD", diff --git a/src/MODULE.bazel.lock b/src/MODULE.bazel.lock index ce4bc12db9..1c385ec43f 100644 --- a/src/MODULE.bazel.lock +++ b/src/MODULE.bazel.lock @@ -257,6 +257,33 @@ }, "selectedYankedVersions": {}, "moduleExtensions": { + "//:defs.bzl%openocd_extension": { + "general": { + "bzlTransitiveDigest": "l1SGMlXmT2O5uZ3b+SaOae1+V2JtUSstC+YGj7hdP3I=", + "usagesDigest": "5oNc47N2R0Rr/jGGzqVE3rovJeggLoEAhjTYWYAyQKM=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_openocd": { + "repoRuleId": "@@+_repo_rules+bazel_embedded//tools/openocd:openocd_repository.bzl%openocd_repository", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "", + "bazel_embedded", + "+_repo_rules+bazel_embedded" + ], + [ + "", + "rules_pkg", + "rules_pkg+" + ] + ] + } + }, "@@apple_support+//crosstool:setup.bzl%apple_cc_configure_extension": { "general": { "bzlTransitiveDigest": "E970FlMbwpgJPdPUQzatKh6BMfeE0ZpWABvwshh7Tmg=", diff --git a/src/extlibs/motor_board_gcc.BUILD b/src/extlibs/motor_board_gcc.BUILD new file mode 100644 index 0000000000..3e87eea155 --- /dev/null +++ b/src/extlibs/motor_board_gcc.BUILD @@ -0,0 +1,9 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "includes", + srcs = glob([ + "arm-none-eabi/include", + "lib/gcc/arm-none-eabi/14.3.1/include", + ]), +) diff --git a/src/firmware/BUILD b/src/firmware/BUILD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/firmware/motor/BUILD b/src/firmware/motor/BUILD new file mode 100644 index 0000000000..be918ecb65 --- /dev/null +++ b/src/firmware/motor/BUILD @@ -0,0 +1,60 @@ +load("@bazel_embedded//tools/openocd:defs.bzl", "openocd_flash") + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "mdv6_firmware_srcs", + srcs = glob(["**/*.c"]), +) + +filegroup( + name = "mdv6_firmware_hdrs", + srcs = glob(["**/*.h"]), +) + +cc_binary( + name = "mdv6_firmware_main", + # Linker file informs the toolchain how much RAM and flash you have as well as its locations on the chip + additional_linker_inputs = [ + "mdv6_firmware.ld", + ], + linkopts = ["-T $(location mdv6_firmware.ld)"], + target_compatible_with = [ + "@platforms//cpu:armv6-m", + "@platforms//os:none", + ], + deps = [ + ":mdv6_firmware", + ], +) + +cc_library( + name = "mdv6_firmware", + srcs = glob(["**/*.c"]), + hdrs = glob(["**/*.h"]), + defines = [ + # Our MCU is the STM32F0251: https://www.st.com/resource/en/datasheet/stspin32f0251.pdf + "STM32F031x6", + # Use the Low-Layer APIs because it gives us more control over the hardware (as opposed to the HAL). + # https://www.st.com/content/ccc/resource/technical/document/user_manual/56/32/53/cb/69/86/49/0e/DM00223149.pdf/files/DM00223149.pdf/jcr:content/translations/en.DM00223149.pdf + "USE_FULL_LL_DRIVER", + ], +) + +openocd_flash( + name = "mdv6_firmware_flash", + device_configs = [ + # Part of the STM32F0 family + # https://www.st.com/resource/en/reference_manual/rm0091-stm32f0x1stm32f0x2stm32f0x8-advanced-armbased-32bit-mcus-stmicroelectronics.pdf + "target/stm32f0x.cfg", + ], + # WARNING! `flash_offset` attribute is broken in the Bazel rule. The .elf file (mdv6_firmware_main.stripped) + # contains the memory mappings already, so this attribute is necessary. + flash_offset = "", + # .stripped strips debug symbols to reduce the size of the binary. + # see: https://bazel.build/reference/be/c-cpp#cc_binary + image = ":mdv6_firmware_main.stripped", + interface_configs = [ + "interface/stlink.cfg", # The ST-Link V2 programmer is used to flash the firmware. + ], +) diff --git a/src/firmware/motor/cmsis/cmsis_compiler.h b/src/firmware/motor/cmsis/cmsis_compiler.h new file mode 100644 index 0000000000..febb8eeeb5 --- /dev/null +++ b/src/firmware/motor/cmsis/cmsis_compiler.h @@ -0,0 +1,330 @@ +/**************************************************************************/ /** + * @file + *cmsis_compiler.h + * @brief + *CMSIS + *compiler + *generic + *header file + * @version + *V5.0.4 + * @date 10. + *January + *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 (armclang) + */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#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 +#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. +#define __RESTRICT +#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 + + +/* + * 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 + + +#else +#error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ diff --git a/src/firmware/motor/cmsis/cmsis_gcc.h b/src/firmware/motor/cmsis/cmsis_gcc.h new file mode 100644 index 0000000000..15c37e2e04 --- /dev/null +++ b/src/firmware/motor/cmsis/cmsis_gcc.h @@ -0,0 +1,2152 @@ +/**************************************************************************/ /** + * @file + *cmsis_gcc.h + * @brief + *CMSIS + *compiler + *GCC header + *file + * @version + *V5.0.4 + * @date 09. + *April 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_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 + + +/* ########################### 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)::"memory"); + 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)::"memory"); + 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") + + +/** + \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") + + +/** + \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 volatile("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 volatile("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 volatile("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 volatile("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 + */ +#define __CLZ (uint8_t) __builtin_clz + + +#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("ssat %0, %1, %2" : "=r"(__RES) : "I"(ARG2), "r"(__ARG1)); \ + __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("usat %0, %1, %2" : "=r"(__RES) : "I"(ARG2), "r"(__ARG1)); \ + __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)); + 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)); + 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)); + 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)); +} + + +/** + \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)); +} + + +/** + \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)); +} + + +/** + \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)); + 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)); + 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)); + 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)); + 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)); + 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)); + 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 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); +} + +#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 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 */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/src/firmware/motor/cmsis/cmsis_version.h b/src/firmware/motor/cmsis/cmsis_version.h new file mode 100644 index 0000000000..f1962b0fcf --- /dev/null +++ b/src/firmware/motor/cmsis/cmsis_version.h @@ -0,0 +1,47 @@ +/**************************************************************************/ /** + * @file + *cmsis_version.h + * @brief + *CMSIS + *Core(M) + *Version + *definitions + * @version + *V5.0.2 + * @date 19. + *April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 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 (1U) /*!< [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/src/firmware/motor/cmsis/core_cm0.h b/src/firmware/motor/cmsis/core_cm0.h new file mode 100644 index 0000000000..c740b398fc --- /dev/null +++ b/src/firmware/motor/cmsis/core_cm0.h @@ -0,0 +1,1043 @@ +/**************************************************************************/ /** + * @file + *core_cm0.h + * @brief + *CMSIS + *Cortex-M0 + *Core + *Peripheral + *Access + *Layer + *Header File + * @version + *V5.0.5 + * @date 28. + *May 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. + */ + +#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_CM0_H_GENERIC +#define __CORE_CM0_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_M0 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN \ + (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB \ + (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION \ + ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined(__CC_ARM) +#if defined __TARGET_FPU_VFP +#error \ + "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#if defined __ARM_PCS_VFP +#error \ + "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined(__GNUC__) +#if defined(__VFP_FP__) && !defined(__SOFTFP__) +#error \ + "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined(__ICCARM__) +#if defined __ARMVFP__ +#error \ + "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined(__TI_ARM__) +#if defined __TI_VFP_SUPPORT__ +#error \ + "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined(__TASKING__) +#if defined __FPU_VFP__ +#error \ + "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#elif defined(__CSMC__) +#if (__CSMC__ & 0x400U) +#error \ + "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" +#endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES +#ifndef __CM0_REV +#define __CM0_REV 0x0000U +#warning "__CM0_REV not defined in device header file; using default!" +#endif + +#ifndef __NVIC_PRIO_BITS +#define __NVIC_PRIO_BITS 2U +#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_M0 */ + + + + /******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick 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 : 28; /*!< bit: 0..27 Reserved */ + 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 */ + + + /** + \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 : 15; /*!< bit: 9..23 Reserved */ + uint32_t T : 1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1 : 3; /*!< bit: 25..27 Reserved */ + 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_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T 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 _reserved0 : 1; /*!< bit: 0 Reserved */ + uint32_t SPSEL : 1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1 : 30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ + } CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL 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[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t + ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t + ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t + ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ + } NVIC_Type; + + /*@} 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 */ + uint32_t RESERVED0; + __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 */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority + Registers. [0] is RESERVED */ + __IOM uint32_t + SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State 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_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk \ + (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE 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_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 */ + +/* 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_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 */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk \ + (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + + /*@} end of group CMSIS_SCB */ + + + /** + \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_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only + accessible over DAP and not via processor. Therefore they are not covered by the + Cortex-M0 header file. + @{ + */ +/*@} 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 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 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 */ + + + /*@} */ + + + + /******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick 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 not available for + * Cortex-M0 */ +#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 */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) (((((uint32_t)(int32_t)(IRQn))) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ((((((uint32_t)(int32_t)(IRQn)) & 0x0FUL) - 8UL) >> 2UL)) +#define _IP_IDX(IRQn) ((((uint32_t)(int32_t)(IRQn)) >> 2UL)) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + + /** + \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) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } + } + + + /** + \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[0U] & (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[0U] = (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[0U] & (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[0U] = (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[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } + } + + + /** + \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[_IP_IDX(IRQn)] = + ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) + << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = + ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) + << _BIT_SHIFT(IRQn))); + } + } + + + /** + \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[_IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & + (uint32_t)0xFFUL) >> + (8U - __NVIC_PRIO_BITS))); + } + else + { + return ((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn)) & + (uint32_t)0xFFUL) >> + (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. Address 0 must be mapped to + SRAM. \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 *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; + } + + + /** + \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 *)0x0U; + 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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for (;;) /* wait until reset */ + { + __NOP(); + } + } + + /*@} end of CMSIS_Core_NVICFunctions */ + + + /* ########################## 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) + { + 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 */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/src/firmware/motor/common_defs.h b/src/firmware/motor/common_defs.h new file mode 100644 index 0000000000..5ee5d98bee --- /dev/null +++ b/src/firmware/motor/common_defs.h @@ -0,0 +1,20 @@ +#ifndef COMMON_DEFS_H +#define COMMON_DEFS_H + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif +#ifndef __packed +#define __packed __attribute__((packed)) +#endif +#elif defined(__GNUC__) && !defined(__CC_ARM) /* GNU Compiler */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + +#endif diff --git a/src/firmware/motor/crc.c b/src/firmware/motor/crc.c new file mode 100644 index 0000000000..1a394d20c4 --- /dev/null +++ b/src/firmware/motor/crc.c @@ -0,0 +1,16 @@ +#include "crc.h" + +#include + +const uint8_t crc_table[] = CRC_TABLE; + +uint8_t crc_gen_checksum(enum OPCODES opcode, uint16_t data) +{ + uint8_t crc = 0xFF; + + crc = crc_table[crc ^ opcode]; + crc = crc_table[crc ^ ((uint8_t)(data >> 8))]; + crc = crc_table[crc ^ ((uint8_t)data & 0xFF)]; + + return crc ^ 0xFF; +} diff --git a/src/firmware/motor/crc.h b/src/firmware/motor/crc.h new file mode 100644 index 0000000000..c07bd8f764 --- /dev/null +++ b/src/firmware/motor/crc.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +#include "firmware/motor/types.h" + +/** + * @brief the CRC-8/AUTOSAR poly. + */ +#define CRC_POLY 0x2F + +/** + * @brief Generated with @ref docs/crc_generate_table.py + * CRC table for poly 0x2F init value 0xFF + */ +#define CRC_TABLE \ + ((const uint8_t[]){ \ + 0x00, 0x2F, 0x5E, 0x71, 0xBC, 0x93, 0xE2, 0xCD, 0x57, 0x78, 0x09, 0x26, 0xEB, \ + 0xC4, 0xB5, 0x9A, 0xAE, 0x81, 0xF0, 0xDF, 0x12, 0x3D, 0x4C, 0x63, 0xF9, 0xD6, \ + 0xA7, 0x88, 0x45, 0x6A, 0x1B, 0x34, 0x73, 0x5C, 0x2D, 0x02, 0xCF, 0xE0, 0x91, \ + 0xBE, 0x24, 0x0B, 0x7A, 0x55, 0x98, 0xB7, 0xC6, 0xE9, 0xDD, 0xF2, 0x83, 0xAC, \ + 0x61, 0x4E, 0x3F, 0x10, 0x8A, 0xA5, 0xD4, 0xFB, 0x36, 0x19, 0x68, 0x47, 0xE6, \ + 0xC9, 0xB8, 0x97, 0x5A, 0x75, 0x04, 0x2B, 0xB1, 0x9E, 0xEF, 0xC0, 0x0D, 0x22, \ + 0x53, 0x7C, 0x48, 0x67, 0x16, 0x39, 0xF4, 0xDB, 0xAA, 0x85, 0x1F, 0x30, 0x41, \ + 0x6E, 0xA3, 0x8C, 0xFD, 0xD2, 0x95, 0xBA, 0xCB, 0xE4, 0x29, 0x06, 0x77, 0x58, \ + 0xC2, 0xED, 0x9C, 0xB3, 0x7E, 0x51, 0x20, 0x0F, 0x3B, 0x14, 0x65, 0x4A, 0x87, \ + 0xA8, 0xD9, 0xF6, 0x6C, 0x43, 0x32, 0x1D, 0xD0, 0xFF, 0x8E, 0xA1, 0xE3, 0xCC, \ + 0xBD, 0x92, 0x5F, 0x70, 0x01, 0x2E, 0xB4, 0x9B, 0xEA, 0xC5, 0x08, 0x27, 0x56, \ + 0x79, 0x4D, 0x62, 0x13, 0x3C, 0xF1, 0xDE, 0xAF, 0x80, 0x1A, 0x35, 0x44, 0x6B, \ + 0xA6, 0x89, 0xF8, 0xD7, 0x90, 0xBF, 0xCE, 0xE1, 0x2C, 0x03, 0x72, 0x5D, 0xC7, \ + 0xE8, 0x99, 0xB6, 0x7B, 0x54, 0x25, 0x0A, 0x3E, 0x11, 0x60, 0x4F, 0x82, 0xAD, \ + 0xDC, 0xF3, 0x69, 0x46, 0x37, 0x18, 0xD5, 0xFA, 0x8B, 0xA4, 0x05, 0x2A, 0x5B, \ + 0x74, 0xB9, 0x96, 0xE7, 0xC8, 0x52, 0x7D, 0x0C, 0x23, 0xEE, 0xC1, 0xB0, 0x9F, \ + 0xAB, 0x84, 0xF5, 0xDA, 0x17, 0x38, 0x49, 0x66, 0xFC, 0xD3, 0xA2, 0x8D, 0x40, \ + 0x6F, 0x1E, 0x31, 0x76, 0x59, 0x28, 0x07, 0xCA, 0xE5, 0x94, 0xBB, 0x21, 0x0E, \ + 0x7F, 0x50, 0x9D, 0xB2, 0xC3, 0xEC, 0xD8, 0xF7, 0x86, 0xA9, 0x64, 0x4B, 0x3A, \ + 0x15, 0x8F, 0xA0, 0xD1, 0xFE, 0x33, 0x1C, 0x6D, 0x42, \ + }) + +/** + * @brief Generates a CRC-8 checksum using the AUTOSAR polynomial (0x2F) + * + * @param opcode The command opcode from @ref OPCODES enum + * @param data 16-bit data value to include in the CRC calculation + * @return uint8_t The calculated 8-bit CRC checksum + * + * This CRC calculation is based off the AUTOSAR Specificiation. + * It has poly 0x2F, initial value 0xFF, and is finally xor'd with 0xFF. + */ +uint8_t crc_gen_checksum(enum OPCODES opcode, uint16_t data); diff --git a/src/firmware/motor/drive_parameters.h b/src/firmware/motor/drive_parameters.h new file mode 100644 index 0000000000..c9e3ed36d3 --- /dev/null +++ b/src/firmware/motor/drive_parameters.h @@ -0,0 +1,162 @@ + +/** + ****************************************************************************** + * @file drive_parameters.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains the parameters needed for the Motor Control SDK + * in order to configure a motor drive. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef DRIVE_PARAMETERS_H +#define DRIVE_PARAMETERS_H + +/************************ + *** Motor Parameters *** + ************************/ + +/******** MAIN AND AUXILIARY SPEED/POSITION SENSOR(S) SETTINGS SECTION ********/ + +/*** Speed measurement settings ***/ +#define MAX_APPLICATION_SPEED_RPM 4840 /*!< rpm, mechanical */ +#define MIN_APPLICATION_SPEED_RPM 0 /*!< rpm, mechanical, absolute value */ +#define M1_SS_MEAS_ERRORS_BEFORE_FAULTS \ + 3 /*!< Number of speed measurement errors before main sensor goes in fault */ + +/****** Hall sensors ************/ +#define HALL_AVERAGING_FIFO_DEPTH \ + 16 /*!< depth of the FIFO used to average mechanical speed in 0.1Hz resolution */ +#define HALL_MTPA false + +/* USER CODE BEGIN angle reconstruction M1 */ +#define PARK_ANGLE_COMPENSATION_FACTOR 0 +#define REV_PARK_ANGLE_COMPENSATION_FACTOR 0 +/* USER CODE END angle reconstruction M1 */ + +/************************** DRIVE SETTINGS SECTION **********************/ +/* PWM generation and current reading */ +#define PWM_FREQUENCY 13000 +#define PWM_FREQ_SCALING 1 +#define LOW_SIDE_SIGNALS_ENABLING LS_PWM_TIMER +#define SW_DEADTIME_NS \ + 600 /*!< Dead-time to be inserted by FW, only if low side signals are enabled */ + +/* Torque and flux regulation loops */ +#define REGULATION_EXECUTION_RATE 1 /*!< FOC execution rate in number of PWM cycles */ +#define ISR_FREQUENCY_HZ \ + (PWM_FREQUENCY / REGULATION_EXECUTION_RATE) /*!< @brief FOC execution rate in Hz */ + +/* Gains values for torque and flux control loops */ +#define PID_TORQUE_KP_DEFAULT 2841 +#define PID_TORQUE_KI_DEFAULT 2072 +#define PID_TORQUE_KD_DEFAULT 100 +#define PID_FLUX_KP_DEFAULT 1420 +#define PID_FLUX_KI_DEFAULT 1036 +#define PID_FLUX_KD_DEFAULT 100 + +/* Torque/Flux control loop gains dividers*/ +#define TF_KPDIV 1024 +#define TF_KIDIV 4096 +#define TF_KDDIV 8192 +#define TF_KPDIV_LOG LOG2((1024)) +#define TF_KIDIV_LOG LOG2((4096)) +#define TF_KDDIV_LOG LOG2((8192)) +#define TFDIFFERENTIAL_TERM_ENABLING DISABLE + +#define PID_SPEED_KP_DEFAULT \ + 2932 / (SPEED_UNIT / 10) /* Workbench compute the gain for 01Hz unit*/ +#define PID_SPEED_KI_DEFAULT \ + 290 / (SPEED_UNIT / 10) /* Workbench compute the gain for 01Hz unit*/ +#define PID_SPEED_KD_DEFAULT \ + 0 / (SPEED_UNIT / 10) /* Workbench compute the gain for 01Hz unit*/ + +/* Speed control loop */ +#define SPEED_LOOP_FREQUENCY_HZ \ + (uint16_t)1000 /*! + +#include "firmware/motor/crc.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_hal.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_hal_spi.h" +#include "firmware/motor/types.h" + +#define SPI_TIMEOUT HAL_MAX_DELAY + +#define CRC_FAIL \ + (uint8_t[]) \ + { \ + FRAME_SOF, NACK, 0x0, 0x0, 0xA4, FRAME_EOF \ + } + +void MC_SPI_ReceiveMessage(SPI_HandleTypeDef *hspi, uint8_t *msgBuf); +/** + * Checks if a byte value is a valid member of the @ref OPCODES enum. + * + * @param x The byte value to check + * @return 1 if the value is a valid opcode, 0 otherwise + * @see OPCODES + */ +int isOpcode(uint8_t x); + +#endif diff --git a/src/firmware/motor/main.c b/src/firmware/motor/main.c new file mode 100644 index 0000000000..838387e1da --- /dev/null +++ b/src/firmware/motor/main.c @@ -0,0 +1,863 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/main.h" + +#include + +#include "firmware/motor/crc.h" +#include "firmware/motor/firmware.h" +#include "firmware/motor/mc_api.h" +#include "firmware/motor/mc_interface.h" +#include "firmware/motor/stm32f0xx/legacy/stm32_hal_legacy.h" +#include "firmware/motor/stm32f0xx/stm32f031x6.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_hal_spi.h" +#include "firmware/motor/types.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +SPI_HandleTypeDef hspi1; + +int16_t ax = 0, bx = 0; +uint8_t TX_Buffer[FRAME_SIZE] = {0}; +uint8_t RX_Buffer[FRAME_SIZE] = {0}; + +volatile uint8_t new_data_received = 0; +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void MX_DMA_Init(void); +static void MX_ADC_Init(void); +static void MX_TIM1_Init(void); +static void MX_TIM2_Init(void); +static void MX_USART1_UART_Init(void); +static void MX_NVIC_Init(void); +/* USER CODE BEGIN PFP */ +static void MX_SPI1_Init(void); + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration --------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_DMA_Init(); + MX_ADC_Init(); + MX_TIM1_Init(); + MX_TIM2_Init(); + // MX_USART1_UART_Init(); + MX_MotorControl_Init(); + + /* Initialize interrupts */ + MX_NVIC_Init(); + /* USER CODE BEGIN 2 */ + MX_SPI1_Init(); + + // call it once for live expression + // MC_GetSTMStateMotor1(); // set a breakpoint on the line if reading the + // // state via Debugger + // MC_GetOccurredFaultsMotor1(); + + // Initial arm of SPI recv + if (HAL_SPI_TransmitReceive_IT(&hspi1, TX_Buffer, RX_Buffer, FRAME_SIZE) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE END 2 */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + /* USER CODE END WHILE */ + /* USER CODE BEGIN 3 */ + // TODO: Need 2 add double buffering to prevent race condition + if (new_data_received) + { + // frame integrity check + if (RX_Buffer[0] != FRAME_SOF || RX_Buffer[5] != FRAME_EOF || + RX_Buffer[4] != + crc_gen_checksum(RX_Buffer[1], (RX_Buffer[2] << 8) + RX_Buffer[3])) + { + TX_Buffer[3] = 0; + // send the NACK + new_data_received = false; + continue; + } + + uint16_t data = 0; + + switch (RX_Buffer[1]) + { + case MOV_AX: + ax = (RX_Buffer[2] << 8) + RX_Buffer[3]; + break; + case GET_AX: + data = ax; + break; + case MOV_BX: + bx = (RX_Buffer[2] << 8) + RX_Buffer[3]; + break; + case GET_BX: + data = bx; + break; + case SET_SPEEDRAMP: + MC_ProgramSpeedRampMotor1(ax, bx); + break; + case GET_SPEED: + data = MC_GetMecSpeedReferenceMotor1(); + break; + case GET_ENCODER: + // TODO: Implement GET_ENCODER FUNCTION + // ax = MC_ + break; + case START_MOTOR: + MC_StartMotor1(); + break; + case STOP_MOTOR: + MC_StopMotor1(); + break; + case ACK_FAULTS: + MC_AcknowledgeFaultMotor1(); + break; + case GET_FAULT: + data = MC_GetOccurredFaultsMotor1(); + break; + case SET_CURRENT: + case GET_CURRENT: + default: + break; + } + + uint8_t checksum = crc_gen_checksum(ACK, data); + TX_Buffer[0] = FRAME_SOF; + TX_Buffer[1] = ACK; + TX_Buffer[2] = (data >> 8) & 0xFF; + TX_Buffer[3] = data & 0xFF; + TX_Buffer[4] = checksum; + TX_Buffer[5] = FRAME_EOF; + + new_data_received = 0; + } + } + /* USER CODE END 3 */ +} + +/** + * @brief TxRx Transfer completed callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure. + * @retval None + */ +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef* hspi) +{ + // let main thread know new data has been recv + if (hspi->Instance == SPI1) + { + new_data_received = 1; + } + + // rearm the receiver + if (HAL_SPI_TransmitReceive_IT(&hspi1, TX_Buffer, RX_Buffer, FRAME_SIZE) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief SPI error callback. + * @param hspi: pointer to a SPI_HandleTypeDef structure. + * @retval None + */ +void HAL_SPI_ErrorCallback(SPI_HandleTypeDef* hspi) +{ + if (hspi->Instance == SPI1) + { + Error_Handler(); + } +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); + while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1) + { + } + LL_RCC_HSE_Enable(); + + /* Wait till HSE is ready */ + while (LL_RCC_HSE_IsReady() != 1) + { + } + LL_RCC_HSI14_Enable(); + + /* Wait till HSI14 is ready */ + while (LL_RCC_HSI14_IsReady() != 1) + { + } + LL_RCC_HSI14_SetCalibTrimming(16); + LL_RCC_HSE_EnableCSS(); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE_DIV_1, LL_RCC_PLL_MUL_6); + LL_RCC_PLL_Enable(); + + /* Wait till PLL is ready */ + while (LL_RCC_PLL_IsReady() != 1) + { + } + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + + /* Wait till System clock is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) + { + } + LL_SetSystemCoreClock(48000000); + + /* Update the time base */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) + { + Error_Handler(); + } + LL_RCC_HSI14_EnableADCControl(); + LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK1); +} + +/** + * @brief NVIC Configuration. + * @retval None + */ +static void MX_NVIC_Init(void) +{ + /* USART1_IRQn interrupt configuration */ + // NVIC_SetPriority(USART1_IRQn, 3); + // NVIC_EnableIRQ(USART1_IRQn); + /* SPI1_IRQn interrupt configuration */ + NVIC_SetPriority(SPI1_IRQn, 3); + NVIC_EnableIRQ(SPI1_IRQn); + /* DMA1_Channel1_IRQn interrupt configuration */ + NVIC_SetPriority(DMA1_Channel1_IRQn, 1); + NVIC_EnableIRQ(DMA1_Channel1_IRQn); + /* DMA1_Channel4_5_IRQn interrupt configuration */ + NVIC_SetPriority(DMA1_Channel4_5_IRQn, 0); + NVIC_EnableIRQ(DMA1_Channel4_5_IRQn); + /* DMA1_Channel2_3_IRQn interrupt configuration */ + NVIC_SetPriority(DMA1_Channel2_3_IRQn, 3); + NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); + /* TIM1_BRK_UP_TRG_COM_IRQn interrupt configuration */ + NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 0); + NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); + /* TIM2_IRQn interrupt configuration */ + NVIC_SetPriority(TIM2_IRQn, 3); + NVIC_EnableIRQ(TIM2_IRQn); +} + +/** + * @brief ADC Initialization Function + * @param None + * @retval None + */ +static void MX_ADC_Init(void) +{ + /* USER CODE BEGIN ADC_Init 0 */ + + /* USER CODE END ADC_Init 0 */ + + LL_ADC_InitTypeDef ADC_InitStruct = {0}; + LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC1); + + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + /**ADC GPIO Configuration + PA5 ------> ADC_IN5 + */ + GPIO_InitStruct.Pin = M1_CURR_AMPL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(M1_CURR_AMPL_GPIO_Port, &GPIO_InitStruct); + + /* ADC DMA Init */ + + /* ADC Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, + LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW); + + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR); + + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT); + + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT); + + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD); + + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD); + + /* USER CODE BEGIN ADC_Init 1 */ + + /* USER CODE END ADC_Init 1 */ + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_5); + + /** Configure the global features of the ADC (Clock, Resolution, Data + * Alignment and number of conversion) + */ + ADC_InitStruct.Clock = LL_ADC_CLOCK_ASYNC; + ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B; + ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_LEFT; + ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE; + LL_ADC_Init(ADC1, &ADC_InitStruct); + ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_EXT_TIM1_TRGO; + ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; + ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE; + ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED; + ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED; + LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct); + LL_ADC_REG_SetSequencerScanDirection(ADC1, LL_ADC_REG_SEQ_SCAN_DIR_FORWARD); + LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_7CYCLES_5); + LL_ADC_REG_SetTriggerEdge(ADC1, LL_ADC_REG_TRIG_EXT_RISING); + /* USER CODE BEGIN ADC_Init 2 */ + + /* USER CODE END ADC_Init 2 */ +} + +/** + * @brief TIM1 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM1_Init(void) +{ + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1); + + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**TIM1 GPIO Configuration + PB12 ------> TIM1_BKIN + */ + GPIO_InitStruct.Pin = M1_OCP_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_OCP_GPIO_Port, &GPIO_InitStruct); + + /* TIM1 DMA Init */ + + /* TIM1_CH4_TRIG_COM Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_4, + LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PRIORITY_HIGH); + + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MODE_CIRCULAR); + + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PERIPH_NOINCREMENT); + + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MEMORY_INCREMENT); + + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_4, LL_DMA_PDATAALIGN_HALFWORD); + + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_4, LL_DMA_MDATAALIGN_HALFWORD); + + /* TIM1_CH3_UP Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_5, + LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PRIORITY_HIGH); + + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MODE_CIRCULAR); + + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PERIPH_NOINCREMENT); + + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MEMORY_INCREMENT); + + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_5, LL_DMA_PDATAALIGN_HALFWORD); + + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_5, LL_DMA_MDATAALIGN_HALFWORD); + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + TIM_InitStruct.Prescaler = ((TIM_CLOCK_DIVIDER)-1); + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_CENTER_UP; + TIM_InitStruct.Autoreload = ((PWM_PERIOD_CYCLES) / 2); + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV2; + TIM_InitStruct.RepetitionCounter = (REP_COUNTER); + LL_TIM_Init(TIM1, &TIM_InitStruct); + LL_TIM_DisableARRPreload(TIM1); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = ((PWM_PERIOD_CYCLES) / 4); + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_LOW; + TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_LOW; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_HIGH; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_HIGH; + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH2); + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH2); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3); + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH3, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3); + LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH4); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM2; + TIM_OC_InitStruct.CompareValue = (((PWM_PERIOD_CYCLES) / 2) - (HTMIN)); + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH4); + LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_UPDATE); + LL_TIM_DisableMasterSlaveMode(TIM1); + TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_ENABLE; + TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_ENABLE; + TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct.DeadTime = ((DEAD_TIME_COUNTS) / 2); + TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_ENABLE; + TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_LOW; + TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; + LL_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct); + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + /**TIM1 GPIO Configuration + PB13 ------> TIM1_CH1N + PB14 ------> TIM1_CH2N + PB15 ------> TIM1_CH3N + PA8 ------> TIM1_CH1 + PA9 ------> TIM1_CH2 + PA10 ------> TIM1_CH3 + */ + GPIO_InitStruct.Pin = M1_PWM_UL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_PWM_UL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = M1_PWM_VL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_PWM_VL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = M1_PWM_WL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_PWM_WL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = M1_PWM_UH_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_PWM_UH_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = M1_PWM_VH_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_PWM_VH_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = M1_PWM_WH_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_PWM_WH_GPIO_Port, &GPIO_InitStruct); +} + +/** + * @brief TIM2 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM2_Init(void) +{ + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + /**TIM2 GPIO Configuration + PA0 ------> TIM2_CH1 + PA1 ------> TIM2_CH2 + PA2 ------> TIM2_CH3 + */ + GPIO_InitStruct.Pin = M1_HALL_H1_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_HALL_H1_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = M1_HALL_H2_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_HALL_H2_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = M1_HALL_H3_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_2; + LL_GPIO_Init(M1_HALL_H3_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + TIM_InitStruct.Prescaler = 0; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = M1_HALL_TIM_PERIOD; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_DisableARRPreload(TIM2); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_CC_DisableChannel(TIM2, LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH2); + LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_TRC); + LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); + LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, M1_HALL_IC_FILTER); + LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING); + LL_TIM_IC_EnableXORCombination(TIM2); + LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI1F_ED); + LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM2; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 0; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + + LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH2, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2); + LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_OC2REF); + LL_TIM_DisableMasterSlaveMode(TIM2); + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ +} + +/** + * @brief USART1 Initialization Function + * @param None + * @retval None + */ +static void MX_USART1_UART_Init(void) +{ + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + LL_USART_InitTypeDef USART_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1); + + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + /**USART1 GPIO Configuration + PB6 ------> USART1_TX + PB7 ------> USART1_RX + */ + GPIO_InitStruct.Pin = UART_TX_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(UART_TX_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = UART_RX_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(UART_RX_GPIO_Port, &GPIO_InitStruct); + + /* USART1 DMA Init */ + + /* USART1_RX Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3, + LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PRIORITY_LOW); + + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_NORMAL); + + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PERIPH_NOINCREMENT); + + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MEMORY_INCREMENT); + + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PDATAALIGN_BYTE); + + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE); + + /* USART1_TX Init */ + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2, + LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PRIORITY_LOW); + + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MODE_NORMAL); + + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PERIPH_NOINCREMENT); + + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MEMORY_INCREMENT); + + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PDATAALIGN_BYTE); + + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MDATAALIGN_BYTE); + + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ + USART_InitStruct.BaudRate = 1843200; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); + LL_USART_DisableIT_CTS(USART1); + LL_USART_ConfigAsyncMode(USART1); + LL_USART_Enable(USART1); + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ +} + +/** + * Enable DMA controller clock + */ +static void MX_DMA_Init(void) +{ + /* Init with LL driver */ + /* DMA controller clock enable */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); +} + +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* USER CODE BEGIN MX_GPIO_Init_1 */ + /* USER CODE END MX_GPIO_Init_1 */ + + /* GPIO Ports Clock Enable */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOF); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB); + + /**/ + LL_GPIO_SetOutputPin(M1_EN_DRIVER_GPIO_Port, M1_EN_DRIVER_Pin); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_0; + GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = M1_EN_DRIVER_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; + LL_GPIO_Init(M1_EN_DRIVER_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN MX_GPIO_Init_2 */ + /* USER CODE END MX_GPIO_Init_2 */ +} + +/* USER CODE BEGIN 4 */ + +static void MX_SPI1_Init(void) +{ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_SLAVE; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_HARD_INPUT; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 7; + hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; + hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; + + if (HAL_SPI_Init(&hspi1) != HAL_OK) + { + Error_Handler(); + } +} + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state + */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line + number, ex printf("Wrong parameters value: file %s on line %d\r\n", file, + line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/src/firmware/motor/main.h b/src/firmware/motor/main.h new file mode 100644 index 0000000000..b92ff1dd9a --- /dev/null +++ b/src/firmware/motor/main.h @@ -0,0 +1,116 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/motorcontrol.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_hal.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_adc.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_bus.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_cortex.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_crs.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_dma.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_exti.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_gpio.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_pwr.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_rcc.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_system.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_tim.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_usart.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_utils.h" + + /* Private includes ----------------------------------------------------------*/ + /* USER CODE BEGIN Includes */ + + /* USER CODE END Includes */ + + /* Exported types ------------------------------------------------------------*/ + /* USER CODE BEGIN ET */ + + /* USER CODE END ET */ + + /* Exported constants --------------------------------------------------------*/ + /* USER CODE BEGIN EC */ + + /* USER CODE END EC */ + + /* Exported macro ------------------------------------------------------------*/ + /* USER CODE BEGIN EM */ + + /* USER CODE END EM */ + + /* Exported functions prototypes ---------------------------------------------*/ + void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define M1_HALL_H1_Pin LL_GPIO_PIN_0 +#define M1_HALL_H1_GPIO_Port GPIOA +#define M1_HALL_H2_Pin LL_GPIO_PIN_1 +#define M1_HALL_H2_GPIO_Port GPIOA +#define M1_HALL_H3_Pin LL_GPIO_PIN_2 +#define M1_HALL_H3_GPIO_Port GPIOA +#define M1_CURR_AMPL_Pin LL_GPIO_PIN_5 +#define M1_CURR_AMPL_GPIO_Port GPIOA +#define M1_OCP_Pin LL_GPIO_PIN_12 +#define M1_OCP_GPIO_Port GPIOB +#define M1_PWM_UL_Pin LL_GPIO_PIN_13 +#define M1_PWM_UL_GPIO_Port GPIOB +#define M1_PWM_VL_Pin LL_GPIO_PIN_14 +#define M1_PWM_VL_GPIO_Port GPIOB +#define M1_PWM_WL_Pin LL_GPIO_PIN_15 +#define M1_PWM_WL_GPIO_Port GPIOB +#define M1_PWM_UH_Pin LL_GPIO_PIN_8 +#define M1_PWM_UH_GPIO_Port GPIOA +#define M1_PWM_VH_Pin LL_GPIO_PIN_9 +#define M1_PWM_VH_GPIO_Port GPIOA +#define M1_PWM_WH_Pin LL_GPIO_PIN_10 +#define M1_PWM_WH_GPIO_Port GPIOA +#define M1_EN_DRIVER_Pin LL_GPIO_PIN_11 +#define M1_EN_DRIVER_GPIO_Port GPIOA +#define TMS_Pin LL_GPIO_PIN_13 +#define TMS_GPIO_Port GPIOA +#define TCK_Pin LL_GPIO_PIN_14 +#define TCK_GPIO_Port GPIOA +#define UART_TX_Pin LL_GPIO_PIN_6 +#define UART_TX_GPIO_Port GPIOB +#define UART_RX_Pin LL_GPIO_PIN_7 +#define UART_RX_GPIO_Port GPIOB + +/* USER CODE BEGIN Private defines */ +#define FRAME_SIZE 6 + /* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/src/firmware/motor/mc_api.c b/src/firmware/motor/mc_api.c new file mode 100644 index 0000000000..9839fe0fa1 --- /dev/null +++ b/src/firmware/motor/mc_api.c @@ -0,0 +1,763 @@ + +/** + ****************************************************************************** + * @file mc_api.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file implements the high level interface of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCIAPI + */ + +#include "mc_api.h" + +#include "mc_config.h" +#include "mc_interface.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** + * @defgroup CAI Application Programming Interface + * @brief Interface for Motor Control applications using the classic SDK + * + * @{ + */ + +/** @defgroup MCIAPI Motor Control API + * + * @brief High level Programming Interface of the Motor Control SDK + * + * This interface allows for performing basic operations on the motor(s) driven by an + * Motor Control SDK based application. With it, motors can be started and stopped, speed + * or torque ramps can be programmed and executed and information on the state of the + * motors can be retrieved, among others. + * + * This interface consists in functions that target a specific motor, indicated in their + * name. These functions aims at being the main interface used by an Application to + * control motors. + * + * The current Motor Control API can cope with up to 2 motors. + * @{ + */ + +/** + * @brief Initiates the start-up procedure for Motor 1 + * + * If the state machine of Motor 1 is in #IDLE state, the command is immediately + * executed. Otherwise the command is discarded. The Application can check the + * return value to know whether the command was executed or discarded. + * + * One of the following commands must be executed before calling MC_StartMotor1() + * in order to set a torque or a speed reference: + * + * - MC_ProgramSpeedRampMotor1() + * - MC_ProgramTorqueRampMotor1() + * - MC_SetCurrentReferenceMotor1() + * + * Failing to do so results in an unpredictable behaviour. + * + * If the offsets of the current measurement circuitry offsets are not known yet, + * an offset calibration procedure is executed to measure them prior to acutally + * starting up the motor. + * + * @note The MCI_StartMotor1 command only triggers the execution of the start-up + * procedure (or eventually the offset calibration procedure) and returns + * immediately after. It is not blocking the execution of the application until + * the motor is indeed running in steady state. If the application needs to wait + * for the motor to be running in steady state, the application has to check the + * state machine of the motor and verify that the #RUN state has been reached. + * Note also that if the startup sequence fails the #RUN state may never be reached. + * + * @retval returns true if the command is successfully executed, false otherwise. + */ +__weak bool MC_StartMotor1(void) +{ + return (MCI_StartMotor(pMCI[M1])); +} + +/** + * @brief Initiates the stop procedure for Motor 1. + * + * If the state machine is in any state but the #ICLWAIT, #IDLE, FAULT_NOW and + * #FAULT_OVER states, the command is immediately executed. Otherwise, it is + * discarded. The Application can check the return value to know whether the + * command was executed or discarded. + * + * @note The MC_StopMotor1() command only triggers the stop motor procedure + * and then returns. It is not blocking the application until the motor is indeed + * stopped. To know if it has stopped, the application can query the motor's state + * machine and check if the #IDLE state has been reached. + * + * @retval returns true if the command is successfully executed, false otherwise. + */ +__weak bool MC_StopMotor1(void) +{ + return (MCI_StopMotor(pMCI[M1])); +} + +/** + * @brief Programs a speed ramp for Motor 1 for later or immediate execution. + * + * A speed ramp is a linear change from the current speed reference to the @p hFinalSpeed + * target speed in the given @p hDurationms time. + * + * Invoking the MC_ProgramSpeedRampMotor1() function programs a new speed ramp + * with the provided parameters. The programmed ramp is executed immediately if + * Motor 1's state machine is in the #RUN states. Otherwise, the ramp is buffered + * and will be executed when the state machine reaches any of the aforementioned state. + * + * The Application can check the status of the command with the + * MC_GetCommandStateMotor1() to know whether the last command was executed immediately or + * not. + * + * Only one command can be buffered at any given time. If another ramp - whether a + * speed or a torque one - or if another buffered command is programmed before the + * current one has completed, the latter replaces the former. + * + * @note A ramp cannot reverse the rotation direction if the Application is using + * sensorless motor control techniques. If the sign of the hFinalSpeed parameter + * differs from that of the current speed, the ramp will not complete and a Speed + * Feedback error (#MC_SPEED_FDBK) will occur when the rotation speed is about to + * reach 0 rpm. + * + * @param hFinalSpeed Mechanical rotor speed reference at the end of the ramp. + * Expressed in the unit defined by #SPEED_UNIT. + * @param hDurationms Duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the speed + * value. + */ +__weak void MC_ProgramSpeedRampMotor1(int16_t hFinalSpeed, uint16_t hDurationms) +{ + MCI_ExecSpeedRamp(pMCI[M1], hFinalSpeed, hDurationms); +} + +/** + * @brief Programs a speed ramp for Motor 1 for later or immediate execution. + * + * A speed ramp is a linear change from the current speed reference to the @p FinalSpeed + * target speed in the given @p hDurationms time. + * + * Invoking the MC_ProgramSpeedRampMotor1() function programs a new speed ramp + * with the provided parameters. The programmed ramp is executed immediately if + * Motor 1's state machine is in the #RUN states. Otherwise, the ramp is buffered + * and will be executed when the state machine reaches any of the aforementioned state. + * + * The Application can check the status of the command with the + * MC_GetCommandStateMotor1() to know whether the last command was executed immediately or + * not. + * + * Only one command can be buffered at any given time. If another ramp - whether a + * speed or a torque one - or if another buffered command is programmed before the + * current one has completed, the latter replaces the former. + * + * @note A ramp cannot reverse the rotation direction if the Application is using + * sensorless motor control techniques. If the sign of the hFinalSpeed parameter + * differs from that of the current speed, the ramp will not complete and a Speed + * Feedback error (#MC_SPEED_FDBK) will occur when the rotation speed is about to + * reach 0 rpm. + * + * @param FinalSpeed Mechanical rotor speed reference at the end of the ramp. + * Expressed in rpm. + * @param hDurationms Duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the speed + * value. + */ +__weak void MC_ProgramSpeedRampMotor1_F(float_t FinalSpeed, uint16_t hDurationms) +{ + MCI_ExecSpeedRamp_F(pMCI[M1], FinalSpeed, hDurationms); +} + +/** + * @brief Programs a torque ramp for Motor 1 for later or immediate execution. + * + * A torque ramp is a linear change from the current torque reference to the @p + * hFinalTorque target torque reference in the given @p hDurationms time. + * + * Invoking the MC_ProgramTorqueRampMotor1() function programs a new torque ramp + * with the provided parameters. The programmed ramp is executed immediately if + * Motor 1's state machine is in the #RUN states. Otherwise, the ramp is buffered + * and will be executed when the state machine reaches any of the aforementioned state. + * + * The Application can check the status of the command with the + * MC_GetCommandStateMotor1() to know whether the last command was executed immediately or + * not. + * + * Only one command can be buffered at any given time. If another ramp - whether a + * torque or a speed one - or if another buffered command is programmed before the + * current one has completed, the latter replaces the former. + * + * @note A ramp cannot reverse the rotation direction if the Application is using + * sensorless motor control techniques. If the sign of the hFinalTorque parameter + * differs from that of the current torque, the ramp will not complete and a Speed + * Feedback error (#MC_SPEED_FDBK) will occur when the rotation speed is about to + * reach 0 rpm. + * + * @param hFinalTorque Mechanical motor torque reference at the end of the ramp. + * This value represents actually the Iq current expressed in digit. + * @param hDurationms Duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the torque + * value. + */ +__weak void MC_ProgramTorqueRampMotor1(int16_t hFinalTorque, uint16_t hDurationms) +{ + MCI_ExecTorqueRamp(pMCI[M1], hFinalTorque, hDurationms); +} + +/** + * @brief Programs a torque ramp for Motor 1 for later or immediate execution. + * + * A torque ramp is a linear change from the current torque reference to the @p + * FinalTorque target torque reference in the given @p hDurationms time. + * + * Invoking the MC_ProgramTorqueRampMotor1() function programs a new torque ramp + * with the provided parameters. The programmed ramp is executed immediately if + * Motor 1's state machine is in the #RUN states. Otherwise, the ramp is buffered + * and will be executed when the state machine reaches any of the aforementioned state. + * + * The Application can check the status of the command with the + * MC_GetCommandStateMotor1() to know whether the last command was executed immediately or + * not. + * + * Only one command can be buffered at any given time. If another ramp - whether a + * torque or a speed one - or if another buffered command is programmed before the + * current one has completed, the latter replaces the former. + * + * @note A ramp cannot reverse the rotation direction if the Application is using + * sensorless motor control techniques. If the sign of the FinalTorque parameter + * differs from that of the current torque, the ramp will not complete and a Speed + * Feedback error (#MC_SPEED_FDBK) will occur when the rotation speed is about to + * reach 0 rpm. + * + * @param FinalTorque Mechanical motor torque reference at the end of the ramp. + * This value represents actually the Iq current expressed in Ampere. + * @param hDurationms Duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the torque + * value. + */ +__weak void MC_ProgramTorqueRampMotor1_F(float_t FinalTorque, uint16_t hDurationms) +{ + MCI_ExecTorqueRamp_F(pMCI[M1], FinalTorque, hDurationms); +} + +/** + * @brief Programs the current reference to Motor 1 for later or immediate execution. + * + * The current reference to consider is made of the $I_d$ and $I_q$ current components. + * + * Invoking the MC_SetCurrentReferenceMotor1() function programs a current reference + * with the provided parameters. The programmed reference is executed immediately if + * Motor 1's state machine is in the #RUN states. Otherwise, the command is buffered + * and will be executed when the state machine reaches any of the aforementioned state. + * + * The Application can check the status of the command with the + * MC_GetCommandStateMotor1() to know whether the last command was executed immediately or + * not. + * + * Only one command can be buffered at any given time. If another buffered command is + * programmed before the current one has completed, the latter replaces the former. + * + * @param Iqdref current reference in the Direct-Quadratic reference frame. Expressed + * in the qd_t format. + */ +__weak void MC_SetCurrentReferenceMotor1(qd_t Iqdref) +{ + MCI_SetCurrentReferences(pMCI[M1], Iqdref); +} + +/** + * @brief Programs the current reference to Motor 1 for later or immediate execution. + * + * The current reference to consider is made of the $I_d$ and $I_q$ current components. + * + * Invoking the MC_SetCurrentReferenceMotor1_F() function programs a current reference + * with the provided parameters. The programmed reference is executed immediately if + * Motor 1's state machine is in the #RUN states. Otherwise, the command is buffered + * and will be executed when the state machine reaches any of the aforementioned state. + * + * The Application can check the status of the command with the + * MC_GetCommandStateMotor1() to know whether the last command was executed immediately or + * not. + * + * Only one command can be buffered at any given time. If another buffered command is + * programmed before the current one has completed, the latter replaces the former. + * + * @param IqdRef current reference in the Direct-Quadratic reference frame. Expressed + * in the qd_f_t format. + */ +__weak void MC_SetCurrentReferenceMotor1_F(qd_f_t IqdRef) +{ + MCI_SetCurrentReferences_F(pMCI[M1], IqdRef); +} + +/** + * @brief Returns the status of the last buffered command for Motor 1. + * + * The status can be one of the following values: + * - #MCI_BUFFER_EMPTY: no buffered command is currently programmed. + * - #MCI_COMMAND_NOT_ALREADY_EXECUTED: A command has been buffered but the conditions for + * its execution have not occurred yet. The command is still in the buffer, pending + * execution. + * - #MCI_COMMAND_EXECUTED_SUCCESSFULLY: the last buffered command has been executed + * successfully. In this case calling this function resets the command state to + * #MCI_BUFFER_EMPTY. + * - #MCI_COMMAND_EXECUTED_UNSUCCESSFULLY: the buffered command has been executed + * unsuccessfully. In this case calling this function resets the command state to + * #MCI_BUFFER_EMPTY. + */ +__weak MCI_CommandState_t MC_GetCommandStateMotor1(void) +{ + return (MCI_IsCommandAcknowledged(pMCI[M1])); +} + +/** + * @brief Stops the execution of the on-going speed ramp for Motor 1, if any. + * + * If a speed ramp is currently being executed, it is immediately stopped, the rotation + * speed of Motor 1 is maintained to its current value and true is returned. If no speed + * ramp is on-going, nothing is done and false is returned. + * + * @deprecated This function is deprecated and should not be used anymore. It will be + * removed in a future version of the MCSDK. Use MC_StopRampMotor1() instead. + */ +__weak bool MC_StopSpeedRampMotor1(void) +{ + return (MCI_StopSpeedRamp(pMCI[M1])); +} + +/** + * @brief Stops the execution of the on-going ramp for Motor 1, if any. + * + * If a ramp is currently being executed, it is immediately stopped, the torque or the + * speed of Motor 1 is maintained to its current value. + */ +__weak void MC_StopRampMotor1(void) +{ + MCI_StopRamp(pMCI[M1]); +} + +/** + * @brief Returns true if the last ramp submited for Motor 1 has completed, false + * otherwise + */ +__weak bool MC_HasRampCompletedMotor1(void) +{ + return (MCI_RampCompleted(pMCI[M1])); +} + +/** + * @brief Returns the current mechanical rotor speed reference set for Motor 1, expressed + * in the unit defined by #SPEED_UNIT + */ +__weak int16_t MC_GetMecSpeedReferenceMotor1(void) +{ + return (MCI_GetMecSpeedRefUnit(pMCI[M1])); +} + +/** + * @brief Returns the current mechanical rotor speed reference set for Motor 1, expressed + * in rpm. + */ +__weak float_t MC_GetMecSpeedReferenceMotor1_F(void) +{ + return (MCI_GetMecSpeedRef_F(pMCI[M1])); +} + +/** + * @brief Returns the last computed average mechanical rotor speed for Motor 1, expressed + * in the unit defined by #SPEED_UNIT + */ +__weak int16_t MC_GetMecSpeedAverageMotor1(void) +{ + return (MCI_GetAvrgMecSpeedUnit(pMCI[M1])); +} + +/** + * @brief Returns the last computed average mechanical rotor speed for Motor 1, expressed + * in rpm. + */ +__weak float_t MC_GetAverageMecSpeedMotor1_F(void) +{ + return (MCI_GetAvrgMecSpeed_F(pMCI[M1])); +} + +/** + * @brief Returns the final speed of the last ramp programmed for Motor 1 if this ramp was + * a speed ramp, 0 otherwise. + */ +__weak int16_t MC_GetLastRampFinalSpeedMotor1(void) +{ + return (MCI_GetLastRampFinalSpeed(pMCI[M1])); +} + +/** + * @brief Returns the final speed of the last ramp programmed for Motor 1 if this ramp was + * a speed ramp, 0 otherwise. + */ +__weak float_t MC_GetLastRampFinalSpeedM1_F(void) +{ + return (MCI_GetLastRampFinalSpeed_F(pMCI[M1])); +} +/** + * @brief Returns the final torque reference for Motor 1, expressed in Ampere. + */ +__weak float_t MC_GetFinalTorqueReferenceMotor1_F(void) +{ + return (MCI_GetLastRampFinalTorque_F(pMCI[M1])); +} + +/** + * @brief Returns the final torque reference for Motor 1, expressed in digit. + */ +__weak int16_t MC_GetFinalTorqueReferenceMotor1(void) +{ + return (MCI_GetLastRampFinalTorque(pMCI[M1])); +} +/** + * @brief Returns the Control Mode used for Motor 1 (either Speed or Torque) + */ +__weak MC_ControlMode_t MC_GetControlModeMotor1(void) +{ + return (MCI_GetControlMode(pMCI[M1])); +} + +/** + * @brief Returns the rotation direction imposed by the last command on Motor 1 + * + * The last command is either MC_ProgramSpeedRampMotor1(), MC_ProgramTorqueRampMotor1() or + * MC_SetCurrentReferenceMotor1(). + * + * The function returns -1 if the sign of the final speed, the final torque or the Iq + * current reference component of the last command is negative. Otherwise, 1 is returned. + * + * @note if no such command has ever been submitted, 1 is returned as well. + */ +__weak int16_t MC_GetImposedDirectionMotor1(void) +{ + return (MCI_GetImposedMotorDirection(pMCI[M1])); +} + +/** + * @brief Returns true if the speed sensor used for Motor 1 is reliable, false otherwise + */ +__weak bool MC_GetSpeedSensorReliabilityMotor1(void) +{ + return (MCI_GetSpdSensorReliability(pMCI[M1])); +} + +/** + * @brief returns the amplitude of the phase current injected in Motor 1 + * + * The returned amplitude (0-to-peak) is expressed in s16A unit. To convert it to amperes, + * use the following formula: + * + * @f[ + * I_{Amps} = \frac{ I_{s16A} \times V_{dd}}{ 65536 \times R_{shunt} \times A_{op} } + * @f] + * + */ +__weak int16_t MC_GetPhaseCurrentAmplitudeMotor1(void) +{ + return (MCI_GetPhaseCurrentAmplitude(pMCI[M1])); +} + +/** + * @brief returns the amplitude of the phase voltage applied to Motor 1 + * + * The returned amplitude (0-to-peak) is expressed in s16V unit. To convert it to volts, + * use the following formula: + * + * @f[ + * U_{Volts} = \frac{ U_{s16V} \times V_{bus}}{ \sqrt{3} \times 32768 } + * @f] + * + */ +__weak int16_t MC_GetPhaseVoltageAmplitudeMotor1(void) +{ + return (MCI_GetPhaseVoltageAmplitude(pMCI[M1])); +} + +/** + * @brief returns Ia and Ib current values for Motor 1 in ab_t format + */ +__weak ab_t MC_GetIabMotor1(void) +{ + return (MCI_GetIab(pMCI[M1])); +} + +/** + * @brief returns Ia and Ib current values for Motor 1 in ab_f_t format + */ +__weak ab_f_t MC_GetIabMotor1_F(void) +{ + return (MCI_GetIab_F(pMCI[M1])); +} + +/** + * @brief returns Ialpha and Ibeta current values for Motor 1 in alphabeta_t format + */ +__weak alphabeta_t MC_GetIalphabetaMotor1(void) +{ + return (MCI_GetIalphabeta(pMCI[M1])); +} + +/** + * @brief returns Iq and Id current values for Motor 1 in qd_t format + */ +__weak qd_t MC_GetIqdMotor1(void) +{ + return (MCI_GetIqd(pMCI[M1])); +} + +/** + * @brief returns Iq and Id current values for Motor 1 in float_t type + */ +__weak qd_f_t MC_GetIqdMotor1_F(void) +{ + return (MCI_GetIqd_F(pMCI[M1])); +} + +/** + * @brief returns Iq and Id reference current values for Motor 1 in qd_t format + */ +__weak qd_t MC_GetIqdrefMotor1(void) +{ + return (MCI_GetIqdref(pMCI[M1])); +} + +/** + * @brief returns Iq and Id reference current values for Motor 1 in float_t type + */ +__weak qd_f_t MC_GetIqdrefMotor1_F(void) +{ + return (MCI_GetIqdref_F(pMCI[M1])); +} + +/** + * @brief returns Vq and Vd voltage values for Motor 1 in qd_t format + */ +__weak qd_t MC_GetVqdMotor1(void) +{ + return (MCI_GetVqd(pMCI[M1])); +} + +/** + * @brief returns Valpha and Vbeta voltage values for Motor 1 in alphabeta_t format + */ +__weak alphabeta_t MC_GetValphabetaMotor1(void) +{ + return (MCI_GetValphabeta(pMCI[M1])); +} + +/** + * @brief returns the electrical angle of the rotor of Motor 1, in DDP format + */ +__weak int16_t MC_GetElAngledppMotor1(void) +{ + return (MCI_GetElAngledpp(pMCI[M1])); +} + +/** + * @brief returns the electrical torque reference for Motor 1 + */ +__weak int16_t MC_GetTerefMotor1(void) +{ + return (MCI_GetTeref(pMCI[M1])); +} + +/** + * @brief returns the electrical torque reference for Motor 1 + */ +__weak float_t MC_GetTerefMotor1_F(void) +{ + return (MCI_GetTeref_F(pMCI[M1])); +} + +/** + * @brief re-initializes Iq and Id references to their default values for Motor 1 + * + * The default values for the Iq and Id references are coming from the Speed + * or the Torque controller depending on the control mode. + * + * @see SpeednTorqCtrl for more details. + */ +__weak void MC_Clear_IqdrefMotor1(void) +{ + MCI_Clear_Iqdref(pMCI[M1]); +} + +/** + * @brief Acknowledge a Motor Control fault that occured on Motor 1 + * + * This function informs Motor 1's state machine that the Application has taken + * the error condition that occured into account. If no error condition exists when + * the function is called, nothing is done and false is returned. Otherwise, true is + * returned. + */ +__weak bool MC_AcknowledgeFaultMotor1(void) +{ + return (MCI_FaultAcknowledged(pMCI[M1])); +} + +/** + * @brief Returns a bit-field showing non acknowledged faults that occurred on Motor 1. + * + * This function returns a 16 bit fields containing the Motor Control faults + * that have occurred on Motor 1 since its state machine moved to the #FAULT_NOW state. + * + * See @ref fault_codes "Motor Control Faults" for a list of + * of all possible faults codes. + */ +__weak uint16_t MC_GetOccurredFaultsMotor1(void) +{ + return (MCI_GetOccurredFaults(pMCI[M1])); +} + +/** + * @brief returns a bitfield showing all current faults on Motor 1 + * + * This function returns a 16 bit fields containing the Motor Control faults + * that are currently active. + * + * See @ref fault_codes "Motor Control Faults" for a list of + * of all possible faults codes. + */ +__weak uint16_t MC_GetCurrentFaultsMotor1(void) +{ + return (MCI_GetCurrentFaults(pMCI[M1])); +} + +/** + * @brief returns the current state of Motor 1 state machine + */ +__weak MCI_State_t MC_GetSTMStateMotor1(void) +{ + return (MCI_GetSTMState(pMCI[M1])); +} + +/** + * @brief Sets the polarization offset values to use for Motor 1 + * + * The Motor Control algorithm relies on a number of current and voltage measures. The + * hardware parts that make these measurements need to be characterized at least once in + * the course of product life, prior to its first activation. This characterization + * consists in measuring the voltage presented to the ADC channels when either no current + * flows into the phases of the motor or no voltage is applied to them. This + * characterization is named polarization offsets measurement and its results are the + * polarization offsets. + * + * The Motor Control Firmware can performs this polarization offsets measurement procedure + * which results in a number of offset values that the application can store in a non + * volatile memory and then set into the Motor Control subsystem at power-on or after a + * reset. + * + * The application uses this function to set the polarization offset values that the Motor + * Control subsystem is to use in the current session. This function can only be used when + * the state machine of the motor is in the #IDLE state in which case it returns + * #MC_SUCCESS. Otherwise, it does nothing and returns the #MC_WRONG_STATE_ERROR error + * code. + * + * The Motor Control subsystem needs to know the polarization offsets before the motor + * can be controlled. The MC_SetPolarizationOffsetsMotor1() function provides a way to set + * these offsets. Alternatively, the application can either: + * + * * Execute the polarization offsets measurement procedure with a call to + * MC_StartPolarizationOffsetsMeasurementMotor1() after a reset or a power on; + * * Start the motor control with the MC_StartWithPolarizationMotor1() that will execute + * the procedure before actually starting the motor, on the first time it is called after + * a reset or a power on. + * + * When this function completes successfully, the state of the polarization offsets + * measurement procedure is set to #COMPLETED. See MC_GetPolarizationState(). + * + * @param PolarizationOffsets an pointer on a structure containing the offset values + */ +bool MC_SetPolarizationOffsetsMotor1(PolarizationOffsets_t* PolarizationOffsets) +{ + return (MCI_SetCalibratedOffsetsMotor(pMCI[M1], PolarizationOffsets)); +} + +/** + * @brief Returns the polarization offset values measured or set for Motor 1 + * + * See MC_SetPolarizationOffsetsMotor1() for more details. + * + * If the Motor Control Firmware knows the polarization offset values, they are copied + * into the + * @p PolarizationOffsets structure and #MC_SUCCESS is returned. Otherwise, nothing is + * done and #MC_NO_POLARIZATION_OFFSETS_ERROR is returned. + * + * @param PolarizationOffsets an pointer on the structure into which the polarization + * offsets will be copied + * @return #MC_SUCCESS if calibration data were present and could be copied into @p + * PolarizationOffsets, #MC_NO_POLARIZATION_OFFSETS_ERROR otherwise. + */ +bool MC_GetPolarizationOffsetsMotor1(PolarizationOffsets_t* PolarizationOffsets) +{ + return (MCI_GetCalibratedOffsetsMotor(pMCI[M1], PolarizationOffsets)); +} + +/** + * @brief Starts the polarization offsets measurement procedure. + * + * See MC_SetPolarizationOffsetsMotor1() for more details. + * + * If the Motor Control Firmware is in the #IDLE state, the procedure is started, the + * state machine of the motor switches to #OFFSET_CALIB and #MC_SUCCESS is returned. + * Otherwise, nothing is done and the #MC_WRONG_STATE_ERROR error code is returned. + * + * The polarization offsets measurement procedure is only triggered by this function and + * it is has not completed when this function returns. The application can use the + * MC_GetPolarizationState() function to query the state of the procedure. + * + * @see MC_GetPolarizationState() + */ +bool MC_StartPolarizationOffsetsMeasurementMotor1(void) +{ + return (MCI_StartOffsetMeasurments(pMCI[M1])); +} + +/** + * @brief This method is used to get the average measured motor power + * expressed in watt for Motor 1. + + * @retval float_t The average measured motor power expressed in watt. + */ +__weak float_t MC_GetAveragePowerMotor1_F(void) +{ + return (PQD_GetAvrgElMotorPowerW(pMPM[M1])); +} + +/** + * @brief Not implemented MC_Profiler function. + * */ //cstat !MISRAC2012-Rule-2.7 !RED-unused-param !MISRAC2012-Rule-2.7 !MISRAC2012-Rule-8.13 +// __weak uint8_t MC_ProfilerCommand(uint16_t rxLength, uint8_t *rxBuffer, int16_t +// txSyncFreeSpace, uint16_t *txLength, uint8_t *txBuffer) +// { +// return (MCP_CMD_UNKNOWN); +// } + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_api.h b/src/firmware/motor/mc_api.h new file mode 100644 index 0000000000..ea94e885ae --- /dev/null +++ b/src/firmware/motor/mc_api.h @@ -0,0 +1,202 @@ + +/** + ****************************************************************************** + * @file mc_api.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file defines the high level interface of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCIAPI + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MC_API_H +#define MC_API_H + +#include "firmware/motor/mc_interface.h" +#include "firmware/motor/mcsdk/mc_type.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup MCIAPI + * @{ + */ + + /* Starts Motor 1 */ + bool MC_StartMotor1(void); + + /* Stops Motor 1 */ + bool MC_StopMotor1(void); + + /* Programs a Speed ramp for Motor 1 */ + void MC_ProgramSpeedRampMotor1(int16_t hFinalSpeed, uint16_t hDurationms); + + /* Programs a Speed ramp for Motor 1 */ + void MC_ProgramSpeedRampMotor1_F(float FinalSpeed, uint16_t hDurationms); + + /* Programs a Torque ramp for Motor 1 */ + void MC_ProgramTorqueRampMotor1(int16_t hFinalTorque, uint16_t hDurationms); + + /* Programs a Torque ramp for Motor 1 */ + void MC_ProgramTorqueRampMotor1_F(float FinalTorque, uint16_t hDurationms); + + /* Programs a current reference for Motor 1 */ + void MC_SetCurrentReferenceMotor1(qd_t Iqdref); + + /* Programs a current reference for Motor 1 */ + void MC_SetCurrentReferenceMotor1_F(qd_f_t IqdRef); + + /* Returns the state of the last submited command for Motor 1 */ + MCI_CommandState_t MC_GetCommandStateMotor1(void); + + /* Stops the execution of the current speed ramp for Motor 1 if any */ + bool MC_StopSpeedRampMotor1(void); + + /* Stops the execution of the on going ramp for Motor 1 if any. + Note: this function is deprecated and should not be used anymore. It will be + removed in a future version. */ + void MC_StopRampMotor1(void); + + /* Returns true if the last submited ramp for Motor 1 has completed, false otherwise + */ + bool MC_HasRampCompletedMotor1(void); + + /* Returns the current mechanical rotor speed reference set for Motor 1, expressed in + * the unit defined by #SPEED_UNIT */ + int16_t MC_GetMecSpeedReferenceMotor1(void); + + /* Returns the current mechanical rotor speed reference set for Motor 1, expressed in + * rpm */ + // float MC_GetMecSpeedReferenceMotor1_F(void); + + /* Returns the last computed average mechanical rotor speed for Motor 1, expressed in + * the unit defined by #SPEED_UNIT */ + int16_t MC_GetMecSpeedAverageMotor1(void); + + /* Returns the last computed average mechanical rotor speed for Motor 1, expressed in + * rpm */ + // float MC_GetAverageMecSpeedMotor1_F(void); + + /* Returns the final speed of the last ramp programmed for Motor 1, if this ramp was a + * speed ramp */ + int16_t MC_GetLastRampFinalSpeedMotor1(void); + + /* Returns the final speed of the last ramp programmed for Motor 1, if this ramp was a + * speed ramp */ + float MC_GetLastRampFinalSpeedMotor1_F(void); + + /* Returns the current Control Mode for Motor 1 (either Speed or Torque) */ + MC_ControlMode_t MC_GetControlModeMotor1(void); + + /* Returns the direction imposed by the last command on Motor 1 */ + int16_t MC_GetImposedDirectionMotor1(void); + + /* Returns the current reliability of the speed sensor used for Motor 1 */ + bool MC_GetSpeedSensorReliabilityMotor1(void); + + /* returns the amplitude of the phase current injected in Motor 1 */ + int16_t MC_GetPhaseCurrentAmplitudeMotor1(void); + + /* returns the amplitude of the phase voltage applied to Motor 1 */ + int16_t MC_GetPhaseVoltageAmplitudeMotor1(void); + + /* returns current Ia and Ib values for Motor 1 */ + ab_t MC_GetIabMotor1(void); + + /* returns current Ia and Ib values in Ampere for Motor 1 */ + ab_f_t MC_GetIabMotor1_F(void); + + /* returns current Ialpha and Ibeta values for Motor 1 */ + alphabeta_t MC_GetIalphabetaMotor1(void); + + /* returns current Iq and Id values for Motor 1 */ + qd_t MC_GetIqdMotor1(void); + + /* returns current Iq and Id values in Ampere for Motor 1 */ + qd_f_t MC_GetIqdMotor1_F(void); + + /* returns Iq and Id reference values for Motor 1 */ + qd_t MC_GetIqdrefMotor1(void); + + /* returns Iq and Id reference values for Motor 1 */ + qd_f_t MC_GetIqdrefMotor1_F(void); + + /* returns current Vq and Vd values for Motor 1 */ + qd_t MC_GetVqdMotor1(void); + + /* returns current Valpha and Vbeta values for Motor 1 */ + alphabeta_t MC_GetValphabetaMotor1(void); + + /* returns the electrical angle of the rotor of Motor 1, in DDP format */ + int16_t MC_GetElAngledppMotor1(void); + + /* returns the current electrical torque reference for Motor 1 */ + int16_t MC_GetTerefMotor1(void); + + /* returns the current electrical torque reference in Ampere for Motor 1 */ + float MC_GetTerefMotor1_F(void); + + /* re-initializes Iq and Id references to their default values */ + void MC_Clear_IqdrefMotor1(void); + + /* Sets the polarization offset values to use for Motor 1*/ + bool MC_SetPolarizationOffsetsMotor1(PolarizationOffsets_t *PolarizationOffsets); + + /* @brief Returns the polarization offset values measured or set for Motor 1 */ + bool MC_GetPolarizationOffsetsMotor1(PolarizationOffsets_t *PolarizationOffsets); + + /* Starts the polarization offsets measurement procedure for Motor 1. */ + bool MC_StartPolarizationOffsetsMeasurementMotor1(void); + + /* Acknowledge a Motor Control fault on Motor 1 */ + bool MC_AcknowledgeFaultMotor1(void); + + /* Returns a bitfiled showing faults that occured since the State Machine of Motor 1 + * was moved to FAULT_NOW state */ + uint16_t MC_GetOccurredFaultsMotor1(void); + + /* Returns a bitfield showing all current faults on Motor 1 */ + uint16_t MC_GetCurrentFaultsMotor1(void); + + /* returns the current state of Motor 1 state machine */ + MCI_State_t MC_GetSTMStateMotor1(void); + + /* returns the current power of Motor 1 in float format */ + float MC_GetAveragePowerMotor1_F(void); + + /* Call the Profiler command */ + uint8_t MC_ProfilerCommand(uint16_t rxLength, uint8_t *rxBuffer, + int16_t txSyncFreeSpace, uint16_t *txLength, + uint8_t *txBuffer); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* MC_API_H */ +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_app_hooks.c b/src/firmware/motor/mc_app_hooks.c new file mode 100644 index 0000000000..a0c84a8310 --- /dev/null +++ b/src/firmware/motor/mc_app_hooks.c @@ -0,0 +1,87 @@ +/** + ****************************************************************************** + * @file mc_app_hooks.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file implements default motor control app hooks. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCAppHooks + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mc_app_hooks.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup MCTasks + * @{ + */ + +/** + * @defgroup MCAppHooks Motor Control Applicative hooks + * @brief User defined functions that are called in the Motor Control tasks + * + * + * @{ + */ + +/** + * @brief Hook function called right after the Medium Frequency Task + * + * + * + */ +__weak void MC_APP_BootHook(void) +{ + /* + * This function can be overloaded or the application can inject + * code into it that will be executed at the end of MCboot(). + */ + + /* USER CODE BEGIN BootHook */ + + /* USER CODE END BootHook */ +} + +/** + * @brief Hook function called right after the Medium Frequency Task + * + * + * + */ +__weak void MC_APP_PostMediumFrequencyHook_M1(void) +{ + /* + * This function can be overloaded or the application can inject + * code into it that will be executed right after the Medium + * Frequency Task of Motor 1. + */ + + /* USER SECTION BEGIN PostMediumFrequencyHookM1 */ + + /* USER SECTION END PostMediumFrequencyHookM1 */ +} + +/** @} */ + +/** @} */ + +/** @} */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_app_hooks.h b/src/firmware/motor/mc_app_hooks.h new file mode 100644 index 0000000000..29847b813c --- /dev/null +++ b/src/firmware/motor/mc_app_hooks.h @@ -0,0 +1,64 @@ +/** + ****************************************************************************** + * @file mc_app_hooks.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file implements tasks definition. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCAppHooks + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MC_APP_HOOKS_H +#define MC_APP_HOOKS_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + /* Includes ------------------------------------------------------------------*/ + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup MCTasks + * @{ + */ + + /** @addtogroup MCAppHooks + * @{ + */ + + /* Exported functions ------------------------------------------------------- */ + + /* Hook function called at end of MCboot() */ + void MC_APP_BootHook(void); + + /* Hook function called right after the Medium Frequency Task of Motor 1 */ + void MC_APP_PostMediumFrequencyHook_M1(void); + + /** @} */ + + /** @} */ + + /** @} */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* MC_APP_HOOKS_H */ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_config.c b/src/firmware/motor/mc_config.c new file mode 100644 index 0000000000..072a6c4bbe --- /dev/null +++ b/src/firmware/motor/mc_config.c @@ -0,0 +1,262 @@ + +/** + ****************************************************************************** + * @file mc_config.c + * @author Motor Control SDK Team,ST Microelectronics + * @brief Motor Control Subsystem components configuration and handler structures. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044,the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +// cstat -MISRAC2012-Rule-21.1 +#include "firmware/motor/main.h" //cstat !MISRAC2012-Rule-21.1 +// cstat +MISRAC2012-Rule-21.1 +#include "firmware/motor/mc_config.h" +#include "firmware/motor/mc_parameters.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/pqd_motor_power_measurement.h" +#include "firmware/motor/parameters_conversion.h" + +/* USER CODE BEGIN Additional include */ + +/* USER CODE END Additional include */ + +#define FREQ_RATIO 1 /* Dummy value for single drive */ +#define FREQ_RELATION HIGHEST_FREQ /* Dummy value for single drive */ + +/* USER CODE BEGIN Additional define */ + +/* USER CODE END Additional define */ + +PQD_MotorPowMeas_Handle_t PQD_MotorPowMeasM1 = {.ConvFact = PQD_CONVERSION_FACTOR}; + +/** + * @brief PI / PID Speed loop parameters Motor 1. + */ +PID_Handle_t PIDSpeedHandle_M1 = { + .hDefKpGain = (int16_t)PID_SPEED_KP_DEFAULT, + .hDefKiGain = (int16_t)PID_SPEED_KI_DEFAULT, + .wUpperIntegralLimit = (int32_t)(IQMAX * SP_KIDIV), + .wLowerIntegralLimit = -(int32_t)(IQMAX * SP_KIDIV), + .hUpperOutputLimit = (int16_t)IQMAX, + .hLowerOutputLimit = -(int16_t)IQMAX, + .hKpDivisor = (uint16_t)SP_KPDIV, + .hKiDivisor = (uint16_t)SP_KIDIV, + .hKpDivisorPOW2 = (uint16_t)SP_KPDIV_LOG, + .hKiDivisorPOW2 = (uint16_t)SP_KIDIV_LOG, + .hDefKdGain = 0x0000U, + .hKdDivisor = 0x0000U, + .hKdDivisorPOW2 = 0x0000U, +}; + +/** + * @brief PI / PID Iq loop parameters Motor 1. + */ +PID_Handle_t PIDIqHandle_M1 = { + .hDefKpGain = (int16_t)PID_TORQUE_KP_DEFAULT, + .hDefKiGain = (int16_t)PID_TORQUE_KI_DEFAULT, + .wUpperIntegralLimit = (int32_t)(INT16_MAX * TF_KIDIV), + .wLowerIntegralLimit = (int32_t)(-INT16_MAX * TF_KIDIV), + .hUpperOutputLimit = INT16_MAX, + .hLowerOutputLimit = -INT16_MAX, + .hKpDivisor = (uint16_t)TF_KPDIV, + .hKiDivisor = (uint16_t)TF_KIDIV, + .hKpDivisorPOW2 = (uint16_t)TF_KPDIV_LOG, + .hKiDivisorPOW2 = (uint16_t)TF_KIDIV_LOG, + .hDefKdGain = 0x0000U, + .hKdDivisor = 0x0000U, + .hKdDivisorPOW2 = 0x0000U, +}; + +/** + * @brief PI / PID Id loop parameters Motor 1. + */ +PID_Handle_t PIDIdHandle_M1 = { + .hDefKpGain = (int16_t)PID_FLUX_KP_DEFAULT, + .hDefKiGain = (int16_t)PID_FLUX_KI_DEFAULT, + .wUpperIntegralLimit = (int32_t)(INT16_MAX * TF_KIDIV), + .wLowerIntegralLimit = (int32_t)(-INT16_MAX * TF_KIDIV), + .hUpperOutputLimit = INT16_MAX, + .hLowerOutputLimit = -INT16_MAX, + .hKpDivisor = (uint16_t)TF_KPDIV, + .hKiDivisor = (uint16_t)TF_KIDIV, + .hKpDivisorPOW2 = (uint16_t)TF_KPDIV_LOG, + .hKiDivisorPOW2 = (uint16_t)TF_KIDIV_LOG, + .hDefKdGain = 0x0000U, + .hKdDivisor = 0x0000U, + .hKdDivisorPOW2 = 0x0000U, +}; + +/** + * @brief SpeednTorque Controller parameters Motor 1. + */ +SpeednTorqCtrl_Handle_t SpeednTorqCtrlM1 = { + .STCFrequencyHz = MEDIUM_FREQUENCY_TASK_RATE, + .MaxAppPositiveMecSpeedUnit = (uint16_t)(MAX_APPLICATION_SPEED_UNIT), + .MinAppPositiveMecSpeedUnit = (uint16_t)(MIN_APPLICATION_SPEED_UNIT), + .MaxAppNegativeMecSpeedUnit = (int16_t)(-MIN_APPLICATION_SPEED_UNIT), + .MinAppNegativeMecSpeedUnit = (int16_t)(-MAX_APPLICATION_SPEED_UNIT), + .MaxPositiveTorque = (int16_t)NOMINAL_CURRENT, + .MinNegativeTorque = -(int16_t)NOMINAL_CURRENT, + .ModeDefault = DEFAULT_CONTROL_MODE, + .MecSpeedRefUnitDefault = (int16_t)(DEFAULT_TARGET_SPEED_UNIT), + .TorqueRefDefault = (int16_t)DEFAULT_TORQUE_COMPONENT, + .IdrefDefault = (int16_t)DEFAULT_FLUX_COMPONENT, +}; + +PWMC_R1_Handle_t PWM_Handle_M1 = { + { + .pFctGetPhaseCurrents = &R1_GetPhaseCurrents, + .pFctSetOffsetCalib = &R1_SetOffsetCalib, + .pFctGetOffsetCalib = &R1_GetOffsetCalib, + .pFctSwitchOffPwm = &R1_SwitchOffPWM, + .pFctSwitchOnPwm = &R1_SwitchOnPWM, + .pFctCurrReadingCalib = &R1_CurrentReadingCalibration, + .pFctTurnOnLowSides = &R1_TurnOnLowSides, + .pFctSetADCSampPointSectX = &R1_CalcDutyCycles, + .pFctOCPSetReferenceVoltage = MC_NULL, + .pFctRLDetectionModeEnable = MC_NULL, + .pFctRLDetectionModeDisable = MC_NULL, + .pFctRLDetectionModeSetDuty = MC_NULL, + .pFctRLTurnOnLowSidesAndStart = MC_NULL, + .LowSideOutputs = (LowSideOutputsFunction_t)LOW_SIDE_SIGNALS_ENABLING, + .pwm_en_u_port = MC_NULL, + .pwm_en_u_pin = (uint16_t)0, + .pwm_en_v_port = MC_NULL, + .pwm_en_v_pin = (uint16_t)0, + .pwm_en_w_port = MC_NULL, + .pwm_en_w_pin = (uint16_t)0, + .hT_Sqrt3 = (PWM_PERIOD_CYCLES * SQRT3FACTOR) / 16384u, + .Sector = 0, + .CntPhA = 0, + .CntPhB = 0, + .CntPhC = 0, + .SWerror = 0, + .TurnOnLowSidesAction = false, + .OffCalibrWaitTimeCounter = 0, + .Motor = 0, + .RLDetectionMode = false, + .SingleShuntTopology = true, + .Ia = 0, + .Ib = 0, + .Ic = 0, + .LPFIqd_const = LPF_FILT_CONST, + .DTCompCnt = DTCOMPCNT, + .PWMperiod = PWM_PERIOD_CYCLES, + .Ton = TON, + .Toff = TOFF, + .OverCurrentFlag = false, + .OverVoltageFlag = false, + .BrakeActionLock = false, + .driverProtectionFlag = false, + }, + + .DmaBuffCCR = {0, 0, 0, 0, 0, 0}, + .PhaseOffset = 0, + .Half_PWMPeriod = PWM_PERIOD_CYCLES / 2u, + .CntSmp1 = 0, + .CntSmp2 = 0, + .sampCur1 = 0, + .sampCur2 = 0, + .CurrAOld = 0, + .CurrBOld = 0, + .Index = 0, + .iflag = 0, + .TCCnt = 0U, + .UpdateFlagBuffer = 0, + .TCDoneFlag = true, + .pParams_str = &R1_ParamsM1, +}; + +OpenLoop_Handle_t OpenLoop_ParamsM1 = {.hDefaultVoltage = OPEN_LOOP_VOLTAGE_d, + .VFMode = OPEN_LOOP_VF, + .hVFOffset = OPEN_LOOP_OFF, + .hVFSlope = OPEN_LOOP_K}; + +/** + * @brief SpeedNPosition sensor parameters Motor 1 - HALL. + */ +HALL_Handle_t HALL_M1 = { + ._Super = + { + .bElToMecRatio = POLE_PAIR_NUM, + .hMaxReliableMecSpeedUnit = (uint16_t)(1.15 * MAX_APPLICATION_SPEED_UNIT), + .hMinReliableMecSpeedUnit = (uint16_t)(MIN_APPLICATION_SPEED_UNIT), + .bMaximumSpeedErrorsNumber = M1_SS_MEAS_ERRORS_BEFORE_FAULTS, + .hMaxReliableMecAccelUnitP = 65535, + .hMeasurementFrequency = TF_REGULATION_RATE_SCALED, + .DPPConvFactor = DPP_CONV_FACTOR, + }, + + .SensorPlacement = HALL_SENSORS_PLACEMENT, + .PhaseShift = (int16_t)(HALL_PHASE_SHIFT * 65536 / 360), + .SpeedSamplingFreqHz = MEDIUM_FREQUENCY_TASK_RATE, + .SpeedBufferSize = HALL_AVERAGING_FIFO_DEPTH, + .TIMClockFreq = HALL_TIM_CLK, + .TIMx = TIM2, + .ICx_Filter = M1_HALL_IC_FILTER_LL, + .PWMFreqScaling = PWM_FREQ_SCALING, + .HallMtpa = HALL_MTPA, + .H1Port = M1_HALL_H1_GPIO_Port, + .H1Pin = M1_HALL_H1_Pin, + .H2Port = M1_HALL_H2_GPIO_Port, + .H2Pin = M1_HALL_H2_Pin, + .H3Port = M1_HALL_H3_GPIO_Port, + .H3Pin = M1_HALL_H3_Pin, +}; + +/** RAMP for Motor1 + * + */ +RampExtMngr_Handle_t RampExtMngrHFParamsM1 = {.FrequencyHz = TF_REGULATION_RATE}; + +/** + * @brief CircleLimitation Component parameters Motor 1 - Base Component. + */ +CircleLimitation_Handle_t CircleLimitationM1 = { + .MaxModule = MAX_MODULE, + .MaxVd = (uint16_t)((MAX_MODULE * 950) / 1000), +}; + +FOCVars_t FOCVars[NBR_OF_MOTORS]; +RampExtMngr_Handle_t *pREMNG[NBR_OF_MOTORS]; +SpeednTorqCtrl_Handle_t *pSTC[NBR_OF_MOTORS] = {&SpeednTorqCtrlM1}; +NTC_Handle_t *pTemperatureSensor[NBR_OF_MOTORS] = {&TempSensor_M1}; +PID_Handle_t *pPIDIq[NBR_OF_MOTORS] = {&PIDIqHandle_M1}; +PID_Handle_t *pPIDId[NBR_OF_MOTORS] = {&PIDIdHandle_M1}; +PQD_MotorPowMeas_Handle_t *pMPM[NBR_OF_MOTORS] = {&PQD_MotorPowMeasM1}; + +MCI_Handle_t Mci[NBR_OF_MOTORS] = { + { + .pSTC = &SpeednTorqCtrlM1, + .pFOCVars = &FOCVars[0], + .pVSS = &VirtualSpeedSensorM1, + .pPWM = &PWM_Handle_M1._Super, + .lastCommand = MCI_NOCOMMANDSYET, + .hFinalSpeed = 0, + .hFinalTorque = 0, + .pScale = &scaleParams_M1, + .hDurationms = 0, + .DirectCommand = MCI_NO_COMMAND, + .State = IDLE, + .CurrentFaults = MC_NO_FAULTS, + .PastFaults = MC_NO_FAULTS, + .CommandState = MCI_BUFFER_EMPTY, + }, + +}; + +/* USER CODE BEGIN Additional configuration */ + +/* USER CODE END Additional configuration */ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_config.h b/src/firmware/motor/mc_config.h new file mode 100644 index 0000000000..8b2d870f7b --- /dev/null +++ b/src/firmware/motor/mc_config.h @@ -0,0 +1,67 @@ + +/** + ****************************************************************************** + * @file mc_config.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief Motor Control Subsystem components configuration and handler + * structures declarations. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#ifndef MC_CONFIG_H +#define MC_CONFIG_H + +#include "firmware/motor/mc_config_common.h" +#include "firmware/motor/mcsdk/circle_limitation.h" +#include "firmware/motor/mcsdk/hall_speed_pos_fdbk.h" +#include "firmware/motor/mcsdk/open_loop.h" +#include "firmware/motor/mcsdk/pid_regulator.h" +#include "firmware/motor/mcsdk/pqd_motor_power_measurement.h" +#include "firmware/motor/mcsdk/pwm_curr_fdbk.h" +#include "firmware/motor/mcsdk/ramp_ext_mngr.h" +#include "firmware/motor/mcsdk/revup_ctrl.h" +#include "firmware/motor/mcsdk/speed_torq_ctrl.h" +#include "firmware/motor/r1_ps_pwm_curr_fdbk.h" + +/* USER CODE BEGIN Additional include */ + +/* USER CODE END Additional include */ + +extern PID_Handle_t PIDIqHandle_M1; +extern PID_Handle_t PIDIdHandle_M1; +extern PWMC_R1_Handle_t PWM_Handle_M1; +extern PQD_MotorPowMeas_Handle_t PQD_MotorPowMeasM1; +extern PQD_MotorPowMeas_Handle_t *pPQD_MotorPowMeasM1; + +extern CircleLimitation_Handle_t CircleLimitationM1; +extern RampExtMngr_Handle_t RampExtMngrHFParamsM1; +extern OpenLoop_Handle_t OpenLoop_ParamsM1; +extern RampExtMngr_Handle_t *pREMNG[NBR_OF_MOTORS]; +extern FOCVars_t FOCVars[NBR_OF_MOTORS]; +extern PID_Handle_t *pPIDIq[NBR_OF_MOTORS]; +extern PID_Handle_t *pPIDId[NBR_OF_MOTORS]; +extern PQD_MotorPowMeas_Handle_t *pMPM[NBR_OF_MOTORS]; +extern MCI_Handle_t *pMCI[NBR_OF_MOTORS]; +extern SpeednTorqCtrl_Handle_t *pSTC[NBR_OF_MOTORS]; +extern MCI_Handle_t Mci[NBR_OF_MOTORS]; +extern SpeednTorqCtrl_Handle_t SpeednTorqCtrlM1; +extern PID_Handle_t PIDSpeedHandle_M1; +extern HALL_Handle_t HALL_M1; + +/* USER CODE BEGIN Additional extern */ + +/* USER CODE END Additional extern */ + +#endif /* MC_CONFIG_H */ +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_config_common.c b/src/firmware/motor/mc_config_common.c new file mode 100644 index 0000000000..64968dd502 --- /dev/null +++ b/src/firmware/motor/mc_config_common.c @@ -0,0 +1,86 @@ + +/** + ****************************************************************************** + * @file mc_config_common.c + * @author Motor Control SDK Team,ST Microelectronics + * @brief Motor Control Subsystem components configuration and handler structures. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044,the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#include "firmware/motor/mc_config_common.h" + +// cstat -MISRAC2012-Rule-21.1 +#include "firmware/motor/main.h" //cstat !MISRAC2012-Rule-21.1 +// cstat +MISRAC2012-Rule-21.1 +#include "firmware/motor/mc_parameters.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/parameters_conversion.h" + +/* USER CODE BEGIN Additional include */ + +/* USER CODE END Additional include */ + +/* USER CODE BEGIN Additional define */ + +/* USER CODE END Additional define */ + +/** + * @brief SpeedNPosition sensor parameters Motor 1 - Base Class. + */ +VirtualSpeedSensor_Handle_t VirtualSpeedSensorM1 = { + + ._Super = + { + .bElToMecRatio = POLE_PAIR_NUM, + .hMaxReliableMecSpeedUnit = (uint16_t)(1.15 * MAX_APPLICATION_SPEED_UNIT), + .hMinReliableMecSpeedUnit = (uint16_t)(MIN_APPLICATION_SPEED_UNIT), + .bMaximumSpeedErrorsNumber = M1_SS_MEAS_ERRORS_BEFORE_FAULTS, + .hMaxReliableMecAccelUnitP = 65535, + .hMeasurementFrequency = TF_REGULATION_RATE_SCALED, + .DPPConvFactor = DPP_CONV_FACTOR, + }, + + .hSpeedSamplingFreqHz = MEDIUM_FREQUENCY_TASK_RATE, + .hTransitionSteps = (int16_t)((TF_REGULATION_RATE * TRANSITION_DURATION) / 1000.0), +}; + +/** + * Virtual temperature sensor parameters Motor 1. + */ +NTC_Handle_t TempSensor_M1 = { + .bSensorType = VIRTUAL_SENSOR, + .hExpectedTemp_d = 555, + .hExpectedTemp_C = M1_VIRTUAL_HEAT_SINK_TEMPERATURE_VALUE, +}; + +/** + * Virtual bus voltage sensor parameters Motor 1. + */ +VirtualBusVoltageSensor_Handle_t BusVoltageSensor_M1 = { + ._Super = + { + .SensorType = VIRTUAL_SENSOR, + .ConversionFactor = 500, + }, + + .ExpectedVbus_d = 1 + ((NOMINAL_BUS_VOLTAGE_V * 65536) / 500), +}; + +PWMC_Handle_t *pwmcHandle[NBR_OF_MOTORS]; + +/* USER CODE BEGIN Additional configuration */ + +/* USER CODE END Additional configuration */ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_config_common.h b/src/firmware/motor/mc_config_common.h new file mode 100644 index 0000000000..e3d2753cf1 --- /dev/null +++ b/src/firmware/motor/mc_config_common.h @@ -0,0 +1,43 @@ + +/** + ****************************************************************************** + * @file mc_config_common.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief Motor Control Subsystem components configuration and handler + * structures declarations. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#ifndef MC_CONFIG_COMMON_H +#define MC_CONFIG_COMMON_H + +#include "firmware/motor/mc_configuration_registers.h" +#include "firmware/motor/mc_interface.h" +#include "firmware/motor/mcsdk/ntc_temperature_sensor.h" +#include "firmware/motor/mcsdk/pid_regulator.h" +#include "firmware/motor/mcsdk/virtual_bus_voltage_sensor.h" +#include "firmware/motor/mcsdk/virtual_speed_sensor.h" + +extern NTC_Handle_t TempSensor_M1; +extern VirtualSpeedSensor_Handle_t VirtualSpeedSensorM1; +extern VirtualBusVoltageSensor_Handle_t BusVoltageSensor_M1; +extern PWMC_Handle_t *pwmcHandle[NBR_OF_MOTORS]; +extern NTC_Handle_t *pTemperatureSensor[NBR_OF_MOTORS]; + +/* USER CODE BEGIN Additional extern */ + +/* USER CODE END Additional extern */ + +#endif /* MC_CONFIG_COMMON_H */ +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_configuration_registers.c b/src/firmware/motor/mc_configuration_registers.c new file mode 100644 index 0000000000..e841ecfeb1 --- /dev/null +++ b/src/firmware/motor/mc_configuration_registers.c @@ -0,0 +1,78 @@ + +/******************************************************************************* + * @file mc_configuration_registers.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides project configuration information registers. + * + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#include "firmware/motor/mc_configuration_registers.h" + +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/parameters_conversion.h" + +#define FIRMWARE_NAME_STR "ST MC SDK\tVer.6.3.2" + +const char_t CTL_BOARD[] = "EVSPIN32F0251S1"; +static const char_t M1_PWR_BOARD[] = "EVSPIN32F0251S1"; +const char_t FIRMWARE_NAME[] = FIRMWARE_NAME_STR; + +const GlobalConfig_reg_t globalConfig_reg = { + .SDKVersion = SDK_VERSION, + .MotorNumber = 1, + .MCP_Flag = FLAG_MCP_OVER_STLINK + FLAG_MCP_OVER_UARTA + FLAG_MCP_OVER_UARTB, + .MCPA_UARTA_LOG = 0, + .MCPA_UARTB_LOG = 0, + .MCPA_STLNK_LOG = 0, +}; + +static const ApplicationConfig_reg_t M1_ApplicationConfig_reg = { + .maxMechanicalSpeed = 4840, + .maxReadableCurrent = M1_MAX_READABLE_CURRENT, + .nominalCurrent = 9.5, + .nominalVoltage = 24, + .driveType = DRIVE_TYPE_M1, +}; + +// cstat !MISRAC2012-Rule-9.2 +static const MotorConfig_reg_t M1_MotorConfig_reg = {.polePairs = 8, + .ratedFlux = 3.8, + .rs = 0.64, + .ls = 0.00027 * 1.000, + .ld = 0.00027, + .maxCurrent = 9.5, + .name = "DF45L024048-82"}; + +static const FOCFwConfig_reg_t M1_FOCConfig_reg = { + .primarySensor = (uint8_t)PRIM_SENSOR_M1, + .auxiliarySensor = (uint8_t)AUX_SENSOR_M1, + .topology = (uint8_t)TOPOLOGY_M1, + .FOCRate = (uint8_t)FOC_RATE_M1, + .PWMFrequency = (uint32_t)PWM_FREQ_M1, + .MediumFrequency = (uint16_t)MEDIUM_FREQUENCY_TASK_RATE, + .configurationFlag1 = + (uint16_t)configurationFlag1_M1, // cstat !MISRAC2012-Rule-10.1_R6 + .configurationFlag2 = + (uint16_t)configurationFlag2_M1, // cstat !MISRAC2012-Rule-10.1_R6 +}; + +const char_t* PWR_BOARD_NAME[NBR_OF_MOTORS] = {M1_PWR_BOARD}; +const FOCFwConfig_reg_t* FOCConfig_reg[NBR_OF_MOTORS] = {&M1_FOCConfig_reg}; +const MotorConfig_reg_t* MotorConfig_reg[NBR_OF_MOTORS] = {&M1_MotorConfig_reg}; +const ApplicationConfig_reg_t* ApplicationConfig_reg[NBR_OF_MOTORS] = { + &M1_ApplicationConfig_reg}; + +/************************ (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_configuration_registers.h b/src/firmware/motor/mc_configuration_registers.h new file mode 100644 index 0000000000..a340ff678e --- /dev/null +++ b/src/firmware/motor/mc_configuration_registers.h @@ -0,0 +1,140 @@ + +/** + ****************************************************************************** + * @file mc_configuration_registers.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides the definitions needed to build the project + * configuration information registers. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#ifndef MC_CONFIGURATION_REGISTERS_H +#define MC_CONFIGURATION_REGISTERS_H + +#include "firmware/motor/mcsdk/mc_type.h" + +typedef struct +{ + uint32_t SDKVersion; + uint8_t MotorNumber; + uint8_t MCP_Flag; + uint8_t MCPA_UARTA_LOG; + uint8_t MCPA_UARTB_LOG; + uint8_t MCPA_STLNK_LOG; + uint8_t Padding; +} __attribute__((packed)) GlobalConfig_reg_t; + +typedef struct +{ + float_t polePairs; + float_t ratedFlux; + float_t rs; + float_t rsSkinFactor; + float_t ls; + float_t ld; + float_t maxCurrent; + float_t mass_copper_kg; + float_t cooling_tau_s; + char_t name[24]; +} __attribute__((packed)) MotorConfig_reg_t; + +typedef struct +{ + uint32_t maxMechanicalSpeed; + float_t maxReadableCurrent; + float_t nominalCurrent; + uint16_t nominalVoltage; + uint8_t driveType; + uint8_t padding; +} __attribute__((packed)) ApplicationConfig_reg_t; + +typedef struct +{ + uint8_t primarySensor; + uint8_t auxiliarySensor; + uint8_t topology; + uint8_t FOCRate; + uint32_t PWMFrequency; + uint16_t MediumFrequency; + uint16_t configurationFlag1; + uint16_t configurationFlag2; +} __attribute__((packed)) FOCFwConfig_reg_t; + +#define ENO_SENSOR 0 +#define EPLL 1 +#define ECORDIC 2 +#define EENCODER 3 +#define EHALL 4 +#define EHSO 5 +#define EZEST 6 + +#define SDK_VERSION_MAIN (0x6) /*!< [31:24] main version */ +#define SDK_VERSION_SUB1 (0x3) /*!< [23:16] sub1 version */ +#define SDK_VERSION_SUB2 (0x2) /*!< [15:8] sub2 version */ +#define SDK_VERSION_RC (0x0) /*!< [7:0] release candidate */ +#define SDK_VERSION \ + ((SDK_VERSION_MAIN << 24U) | (SDK_VERSION_SUB1 << 16U) | (SDK_VERSION_SUB2 << 8U) | \ + (SDK_VERSION_RC)) +/* configurationFlag1 definition */ +#define FLUX_WEAKENING_FLAG (1U) +#define FEED_FORWARD_FLAG (1U << 1U) +#define MTPA_FLAG (1U << 2U) +#define PFC_FLAG (1U << 3U) +#define ICL_FLAG (1U << 4U) +#define RESISTIVE_BREAK_FLAG (1U << 5U) +#define OCP_DISABLE_FLAG (1U << 6U) +#define STGAP_FLAG (1U << 7U) +#define POSITION_CTRL_FLAG (1U << 8U) +#define VBUS_SENSING_FLAG (1U << 9U) +#define TEMP_SENSING_FLAG (1U << 10U) +#define VOLTAGE_SENSING_FLAG (1U << 11U) +#define FLASH_CONFIG_FLAG (1U << 12U) +#define DAC_CH1_FLAG (1U << 13U) +#define DAC_CH2_FLAG (1U << 14U) +#define OTF_STARTUP_FLAG (1U << 15U) + +/* configurationFlag2 definition */ +#define OVERMODULATION_FLAG (1U) +#define DISCONTINUOUS_PWM_FLAG (1U << 1U) +#define PROFILER_FLAG (1U << 13U) +#define DBG_MCU_LOAD_MEASURE_FLAG (1U << 14U) +#define DBG_OPEN_LOOP_FLAG (1U << 15U) + +/* MCP_Flag definition */ +#define FLAG_MCP_OVER_STLINK 0U +#define FLAG_MCP_OVER_UARTA (1U << 1U) +#define FLAG_MCP_OVER_UARTB 0U + +#define configurationFlag1_M1 (0U) +#define configurationFlag2_M1 (DBG_OPEN_LOOP_FLAG) + +#define DRIVE_TYPE_M1 0 +#define PRIM_SENSOR_M1 EHALL +#define AUX_SENSOR_M1 ENO_SENSOR +#define TOPOLOGY_M1 2 +#define FOC_RATE_M1 1 +#define PWM_FREQ_M1 13000 + +extern const char_t FIRMWARE_NAME[]; // cstat !MISRAC2012-Rule-18.8 !MISRAC2012-Rule-8.11 +extern const char_t CTL_BOARD[]; // cstat !MISRAC2012-Rule-18.8 !MISRAC2012-Rule-8.11 +extern const char_t *PWR_BOARD_NAME[NBR_OF_MOTORS]; +extern const char_t *MOTOR_NAME[NBR_OF_MOTORS]; +extern const GlobalConfig_reg_t globalConfig_reg; +extern const FOCFwConfig_reg_t *FOCConfig_reg[NBR_OF_MOTORS]; +extern const MotorConfig_reg_t *MotorConfig_reg[NBR_OF_MOTORS]; +extern const ApplicationConfig_reg_t *ApplicationConfig_reg[NBR_OF_MOTORS]; + +#endif /* MC_CONFIGURATION_REGISTERS_H */ +/************************ (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_interface.c b/src/firmware/motor/mc_interface.c new file mode 100644 index 0000000000..10f3ac86e5 --- /dev/null +++ b/src/firmware/motor/mc_interface.c @@ -0,0 +1,1789 @@ + +/** + ****************************************************************************** + * @file mc_interface.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the MC Interface component of the Motor Control SDK: + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCInterface + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mc_interface.h" + +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/speed_torq_ctrl.h" +#include "firmware/motor/motorcontrol.h" + +#define ROUNDING_OFF + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup CAI + * @{ + */ + +/** @defgroup MCInterface Motor Control Interface + * @brief MC Interface component of the Motor Control SDK + * + * This interface allows for performing basic operations on the motor driven by a + * Motor Control SDK based application. With it, motors can be started and stopped, speed + * or torque ramps can be programmed and executed and information on the state of the + * motor can be retrieved, among others. + * + * These functions aims at being the main interface used by an application to control the + * motor. + * + * @{ + */ +/* Private macros ------------------------------------------------------------*/ + +#define round(x) ((x) >= 0 ? (int32_t)((x) + 0.5) : (int32_t)((x)-0.5)) + +/* Functions -----------------------------------------------*/ + +/** + * @brief Programs a motor speed ramp + * + * @param pHandle Pointer on the component instance to operate on. + * @param hFinalSpeed The value of mechanical rotor speed reference at the + * end of the ramp expressed in the unit defined by #SPEED_UNIT. + * @param hDurationms The duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the + * value. + * + * This command is executed immediately if the target motor's state machine is in + * the #RUN state. Otherwise, it is buffered and its execution is delayed until This + * state is reached. + * + * Users can check the status of the command by calling the MCI_IsCommandAcknowledged() + * function. + * + * @sa MCI_ExecSpeedRamp + */ +__weak void MCI_ExecSpeedRamp(MCI_Handle_t *pHandle, int16_t hFinalSpeed, + uint16_t hDurationms) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->lastCommand = MCI_CMD_EXECSPEEDRAMP; + pHandle->hFinalSpeed = hFinalSpeed; + pHandle->hDurationms = hDurationms; + pHandle->CommandState = MCI_COMMAND_NOT_ALREADY_EXECUTED; + +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief Programs a motor speed ramp + * + * @param pHandle Pointer on the component instance to operate on. + * @param FinalSpeed is the value of mechanical rotor speed reference at the + * end of the ramp expressed in RPM. + * @param hDurationms the duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the + * value. + * + * This command is executed immediately if the target motor's state machine is in + * the #RUN state. Otherwise, it is buffered and its execution is delayed until This + * state is reached. + * + * Users can check the status of the command by calling the MCI_IsCommandAcknowledged() + * function. + * + * @sa MCI_ExecSpeedRamp_F + */ +__weak void MCI_ExecSpeedRamp_F(MCI_Handle_t *pHandle, const float_t FinalSpeed, + uint16_t hDurationms) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + float_t hFinalSpeed = ((FinalSpeed * (float_t)SPEED_UNIT) / (float_t)U_RPM); + MCI_ExecSpeedRamp(pHandle, (int16_t)hFinalSpeed, hDurationms); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief Programs a motor torque ramp + * + * @param pHandle Pointer on the component instance to work on. + * @param hFinalTorque is the value of motor torque reference at the end of + * the ramp. This value represents actually the $I_q$ current expressed in + * digit. + * To convert current expressed in Amps to current expressed in digit + * is possible to use the formula: + * Current (digit) = [Current(Amp) * 65536 * Rshunt * Aop] / Vdd micro. + * @param hDurationms the duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the + * value. + * + * This command is executed immediately if the target motor's state machine is in + * the #RUN state. Otherwise, it is buffered and its execution is delayed until This + * state is reached. + * + * Users can check the status of the command by calling the MCI_IsCommandAcknowledged() + * function. + * + * @sa MCI_ExecTorqueRamp + */ +__weak void MCI_ExecTorqueRamp(MCI_Handle_t *pHandle, int16_t hFinalTorque, + uint16_t hDurationms) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->lastCommand = MCI_CMD_EXECTORQUERAMP; + pHandle->hFinalTorque = hFinalTorque; + pHandle->hDurationms = hDurationms; + pHandle->CommandState = MCI_COMMAND_NOT_ALREADY_EXECUTED; + pHandle->LastModalitySetByUser = MCM_TORQUE_MODE; +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief Programs a motor torque ramp + * + * @param pHandle Pointer on the component instance to work on. + * @param FinalTorque is the value of motor torque reference at the end of + * the ramp. This value represents actually the $I_q$ current expressed in + * Ampere. + * Here the formula for conversion from current in Ampere to digit: + * I(s16) = [i(Amp) * 65536 * Rshunt * Aop] / Vdd_micro. + * @param hDurationms the duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the + * value. + * + * This command is executed immediately if the target motor's state machine is in + * the #RUN state. Otherwise, it is buffered and its execution is delayed until This + * state is reached. + * + * Users can check the status of the command by calling the MCI_IsCommandAcknowledged() + * function. + * + * @sa MCI_ExecTorqueRamp_F + */ +__weak void MCI_ExecTorqueRamp_F(MCI_Handle_t *pHandle, const float_t FinalTorque, + uint16_t hDurationms) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + float_t hFinalTorque = (FinalTorque * (float_t)CURRENT_CONV_FACTOR); + MCI_ExecTorqueRamp(pHandle, (int16_t)hFinalTorque, hDurationms); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief Sets the motor current references $I_q$ and $I_d$ directly. + * + * @param pHandle Pointer on the component instance to work on. + * @param Iqdref current references on qd reference frame in qd_t format. + * + * This command is executed immediately if the target motor's state machine is in + * the #RUN state. Otherwise, it is buffered and its execution is delayed until This + * state is reached. + * + * Users can check the status of the command by calling the MCI_IsCommandAcknowledged() + * function. + + @sa MCI_SetCurrentReferences_F + */ +__weak void MCI_SetCurrentReferences(MCI_Handle_t *pHandle, qd_t Iqdref) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + + MC_ControlMode_t mode; + mode = MCI_GetControlMode(pHandle); + if (mode == MCM_OPEN_LOOP_CURRENT_MODE) + { + pHandle->Iqdref.q = Iqdref.q; + pHandle->Iqdref.d = Iqdref.d; + pHandle->pFOCVars->Iqdref.q = Iqdref.q; + pHandle->pFOCVars->Iqdref.d = Iqdref.d; + pHandle->LastModalitySetByUser = mode; + } + else + { + pHandle->lastCommand = MCI_CMD_SETCURRENTREFERENCES; + pHandle->Iqdref.q = Iqdref.q; + pHandle->Iqdref.d = Iqdref.d; + pHandle->CommandState = MCI_COMMAND_NOT_ALREADY_EXECUTED; + pHandle->LastModalitySetByUser = MCM_TORQUE_MODE; + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief Sets the motor current references $I_q$ and $I_d$ directly. + * + * @param pHandle Pointer on the component instance to work on. + * @param IqdRef current (A) references on qd reference frame in qd_f_t format. + * + * This command is executed immediately if the target motor's state machine is in + * the #RUN state. Otherwise, it is buffered and its execution is delayed until This + * state is reached. + * + * Users can check the status of the command by calling the MCI_IsCommandAcknowledged() + * function. + + @sa MCI_SetCurrentReferences + */ +__weak void MCI_SetCurrentReferences_F(MCI_Handle_t *pHandle, qd_f_t IqdRef) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + qd_t iqDrefTemp; + qd_f_t iqDrefTempf; + iqDrefTempf.d = (IqdRef.d * (float_t)CURRENT_CONV_FACTOR); + iqDrefTempf.q = (IqdRef.q * (float_t)CURRENT_CONV_FACTOR); + iqDrefTemp.d = (int16_t)(iqDrefTempf.d); + iqDrefTemp.q = (int16_t)(iqDrefTempf.q); + MCI_SetCurrentReferences(pHandle, iqDrefTemp); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} +/** + * @brief Sets the target motor's control mode to Speed mode. + * @param pHandle Pointer on the component instance to work on. + * + * @note This function is only available when the Open loop Debug feature is + * enabled at firmware generation time. + */ +__weak void MCI_SetSpeedMode(MCI_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFOCVars->bDriveInput = INTERNAL; + STC_SetControlMode(pHandle->pSTC, MCM_SPEED_MODE); + pHandle->LastModalitySetByUser = MCM_SPEED_MODE; +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief Sets the target motor's control mode to Open loop Current mode. + * @param pHandle Pointer on the component instance to work on. + * + * @note This function is only available when the Open loop Debug feature is + * enabled at firmware generation time. + */ +__weak void MCI_SetOpenLoopCurrentMode(MCI_Handle_t *pHandle) +{ + pHandle->pFOCVars->bDriveInput = EXTERNAL; + STC_SetControlMode(pHandle->pSTC, MCM_OPEN_LOOP_CURRENT_MODE); + pHandle->LastModalitySetByUser = MCM_OPEN_LOOP_CURRENT_MODE; +} +/** + * @brief Sets the target motor's control mode to Open loop Current mode. + * @param pHandle Pointer on the component instance to work on. + * + * @note This function is only available when the Open loop Debug feature is + * enabled at firmware generation time. + * + * @deprecated This function is deprecated and should not be used anymore. + * It will be removed in a future version of the MCSDK. Use MCI_SetOpenLoopCurrentMode() + * instead. + */ +__weak void MCI_SetOpenLoopCurrent(MCI_Handle_t *pHandle) +{ + MCI_SetOpenLoopCurrentMode(pHandle); +} + +/** + * @brief Sets the target motor's control mode to Open loop Voltage mode. + * @param pHandle Pointer on the component instance to work on. + * + * @note This function is only available when the Open loop Debug feature is + * enabled at firmware generation time. + */ +__weak void MCI_SetOpenLoopVoltageMode(MCI_Handle_t *pHandle) +{ + pHandle->pFOCVars->bDriveInput = EXTERNAL; + STC_SetControlMode(pHandle->pSTC, MCM_OPEN_LOOP_VOLTAGE_MODE); + pHandle->LastModalitySetByUser = MCM_OPEN_LOOP_VOLTAGE_MODE; +} + +/** + * @brief Sets the target motor's control mode to Open loop Voltage mode. + * @param pHandle Pointer on the component instance to work on. + * + * @note This function is only available when the Open loop Debug feature is + * enabled at firmware generation time. + * + * @deprecated This function is deprecated and should not be used anymore. + * It will be removed in a future version of the MCSDK. Use MCI_SetOpenLoopVoltageMode() + * instead. + */ +__weak void MCI_SetOpenLoopVoltage(MCI_Handle_t *pHandle) +{ + MCI_SetOpenLoopVoltageMode(pHandle); +} + +/** + * @brief Initiates a motor startup procedure + * + * @param pHandle Handle on the target motor interface structure + * @retval Returns true if the command is successfully executed; + * returns false otherwise + * + * If the state machine of target the motor is in #IDLE state the command is + * executed instantaneously otherwise it is discarded. Users can check + * the return value of the function to get its status. The state of the motor + * can be queried with the MCI_GetSTMState() function. + * + * Before calling MCI_StartMotor() it is mandatory to execute one of the + * following commands, in order to set a torque or a speed reference + * otherwise the behavior of the motor when it reaches the #RUN state will + * be unpredictable: + * - MCI_ExecSpeedRamp + * - MCI_ExecTorqueRamp + * - MCI_SetCurrentReferences + * + * If the offsets of the current measurement circuitry offsets are not known yet, + * an offset calibration procedure is executed to measure them prior to acutally + * starting up the motor. + * + * @note The MCI_StartMotor command only triggers the execution of the start-up + * procedure (or eventually the offset calibration procedure) and returns + * immediately after. It is not blocking the execution of the application until + * the motor is indeed running in steady state. If the application needs to wait + * for the motor to be running in steady state, the application has to check the + * state machine of the motor and verify that the #RUN state has been reached. + * Note also that if the startup sequence fails the #RUN state may never be reached. + */ +__weak bool MCI_StartMotor(MCI_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if ((IDLE == MCI_GetSTMState(pHandle)) && + (MC_NO_FAULTS == MCI_GetOccurredFaults(pHandle)) && + (MC_NO_FAULTS == MCI_GetCurrentFaults(pHandle))) + { + pHandle->DirectCommand = MCI_START; + pHandle->CommandState = MCI_COMMAND_NOT_ALREADY_EXECUTED; + retVal = true; + } + else + { + /* Reject the command as the condition are not met */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (retVal); +} + +/** + * @brief Initiates a motor startup procedure preceded by an offset + * calibration procedure + * + * @param pHandle Handle on the target motor interface structure + * @retval Returns true if the command is successfully executed; + * returns false otherwise + * + * If the state machine of target the motor is in #IDLE state the command is + * executed instantaneously otherwise it is discarded. Users can check + * the return value of the function to get its status. The state of the motor + * can be queried with the MCI_GetSTMState() function. + * + * Before calling MCI_StartMotor() it is mandatory to execute one of the + * following commands, in order to set a torque or a speed reference + * otherwise the behavior of the motor when it reaches the #RUN state will + * be unpredictable: + * - MCI_ExecSpeedRamp + * - MCI_ExecTorqueRamp + * - MCI_SetCurrentReferences + * + * Whether the current measurement circuitry offsets are known or not, an + * offset calibration procedure is executed to (re)measure them. Once it has + * completed, the start up procedure of the motor is executed. + * + * @note The MCI_StartMotor command only triggers the execution of the start-up + * procedure (or eventually the offset calibration procedure) and returns + * immediately after. It is not blocking the execution of the application until + * the motor is indeed running in steady state. If the application needs to wait + * for the motor to be running in steady state, the application has to check the + * state machine of the motor and verify that the #RUN state has been reached. + * Note also that if the startup sequence fails the #RUN state may never be reached. + */ +__weak bool MCI_StartWithPolarizationMotor(MCI_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if ((IDLE == MCI_GetSTMState(pHandle)) && + (MC_NO_FAULTS == MCI_GetOccurredFaults(pHandle)) && + (MC_NO_FAULTS == MCI_GetCurrentFaults(pHandle))) + { + pHandle->DirectCommand = MCI_START; + pHandle->CommandState = MCI_COMMAND_NOT_ALREADY_EXECUTED; + pHandle->pPWM->offsetCalibStatus = false; + retVal = true; + } + else + { + /* Reject the command as the condition are not met */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (retVal); +} + +/** + * @brief This is a user command used to begin the phase offset calibration + * procedure. If the state machine is in IDLE state the command is executed + * instantaneously otherwise the command is discarded. User must take + * care of this possibility by checking the return value.\n + * Note: The MCI_StartOffsetMeasurments command is used to begin phase + * offset calibration procedure moving the state machine from IDLE state to + * OFFSET_CALIB. The command MCI_StartOffsetMeasurments is not blocking + * the execution of project until the measurments are done; to do this, the user + * have to check the state machine and verify that the IDLE state (or + * any other state) has been reached. + * @param pHandle Pointer on the component instance to work on. + * @retval bool It returns true if the command is successfully executed + * otherwise it return false. + */ +__weak bool MCI_StartOffsetMeasurments(MCI_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if ((IDLE == MCI_GetSTMState(pHandle)) && + (MC_NO_FAULTS == MCI_GetOccurredFaults(pHandle)) && + (MC_NO_FAULTS == MCI_GetCurrentFaults(pHandle))) + { + pHandle->DirectCommand = MCI_MEASURE_OFFSETS; + pHandle->pPWM->offsetCalibStatus = false; + retVal = true; + } + else + { + /* Reject the command as the condition are not met */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (retVal); +} + +/** + * @brief Gets the phase current measurement offset values + * + * The offset values are written in the PolarizationOffsets structure provided that they + * have been previously provided for the Motor Control subsystem or measured by it. + * + * If the offset have not previously been provided to the Motor Control subsystem or + * if it has not measured them the function returns false and nothing is written in the + * PolarizationOffsets structure. + * + * @param pHandle Pointer on the component instance to work on. + * @param PolarizationOffsets Pointer on ploarization offset structure in which offsets + * will be written + * @retval returns true if the command is successfully executed; returns false otherwise. + */ +__weak bool MCI_GetCalibratedOffsetsMotor(MCI_Handle_t *pHandle, + PolarizationOffsets_t *PolarizationOffsets) +{ + bool retVal = false; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (pHandle->pPWM->offsetCalibStatus == true) + { + PWMC_GetOffsetCalib(pHandle->pPWM, PolarizationOffsets); + retVal = true; + } + else + { + /* Reject the command as the condition are not met */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + + return (retVal); +} + +/** + * @brief Sets the phase current measurement offset values + * + * If the state machine is in IDLE state the command is executed + * instantaneously otherwise the command is discarded. User must take + * care of this possibility by checking the return value. + * + * @note The MCI_SetCalibratedOffsetsMotor command is used to set the phase + * offset values . The command MCI_SetCalibratedOffsetsMotor is not blocking + * the execution of project until the measurments are done; to do this, the user + * have to check the state machine and verify that the IDLE state (or + * any other state) has been reached. + * + * @param pHandle Pointer on the component instance to work on. + * @param PolarizationOffsets Pointer on ploarization offset structure that contains + * phase A, and C values. + * @retval Returns true if the command is successfully executed + * otherwise it return false. + */ +__weak bool MCI_SetCalibratedOffsetsMotor(MCI_Handle_t *pHandle, + PolarizationOffsets_t *PolarizationOffsets) +{ + bool retVal = false; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if ((IDLE == MCI_GetSTMState(pHandle)) && + (MC_NO_FAULTS == MCI_GetOccurredFaults(pHandle)) && + (MC_NO_FAULTS == MCI_GetCurrentFaults(pHandle))) + { + PWMC_SetOffsetCalib(pHandle->pPWM, PolarizationOffsets); + pHandle->pPWM->offsetCalibStatus = true; + retVal = true; + } + else + { + /* Reject the command as the condition are not met */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (retVal); +} + +/** + * @brief Initiates the stop procedure for a motor + * + * If the state machine is in any state but the #ICLWAIT, #IDLE, #FAULT_NOW and + * #FAULT_OVER states, the command is immediately executed. Otherwise, it is + * discarded. The Application can check the return value to know whether the + * command was executed or discarded. + * + * @note The MCI_StopMotor() command only triggers the stop motor procedure + * and then returns. It is not blocking the application until the motor is indeed + * stopped. To know if it has stopped, the application can query the motor's state + * machine and check if the #IDLE state has been reached. + * + * @param pHandle Pointer on the component instance to work on. + * @retval returns true if the command is successfully executed, false otherwise. + */ +__weak bool MCI_StopMotor(MCI_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + bool status; + MCI_State_t State; + + State = MCI_GetSTMState(pHandle); + if ((IDLE == State) || (ICLWAIT == State)) + { + status = false; + } + else + { + status = true; + } + + if ((MC_NO_FAULTS == MCI_GetOccurredFaults(pHandle)) && + (MC_NO_FAULTS == MCI_GetCurrentFaults(pHandle)) && (status == true)) + { + pHandle->DirectCommand = MCI_STOP; + retVal = true; + } + else + { + /* Reject the command as the condition are not met */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (retVal); +} + +/** + * @brief Acknowledges Motor Control faults that occurred on the target motor 1. + * + * This function must be called before the motor can be started again when a fault + * condition has occured. It clears the faults status and resets the state machine + * of the target motor to the #IDLE state provided that there is no active fault + * condition anymore. + * + * If the state machine of the target motor is in the #FAULT_OVER state, the function + * clears the list of past faults, transitions to the #IDLE state and returns true. + * Otherwise, it oes nothing and returns false. + * + * @param pHandle Pointer on the target motor drive structure. + */ +__weak bool MCI_FaultAcknowledged(MCI_Handle_t *pHandle) +{ + bool reVal = false; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if ((FAULT_OVER == MCI_GetSTMState(pHandle)) && + (MC_NO_FAULTS == MCI_GetCurrentFaults(pHandle))) + { + pHandle->PastFaults = MC_NO_FAULTS; + pHandle->DirectCommand = MCI_ACK_FAULTS; + reVal = true; + } + else + { + /* Reject the command as the conditions are not met */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (reVal); +} + +/** + * @brief It clocks both HW and SW faults processing and update the state + * machine accordingly with hSetErrors, hResetErrors and present state. + * Refer to State_t description for more information about fault states. + * @param pHandle pointer of type STM_Handle_t + * @param hSetErrors Bit field reporting faults currently present + * @param hResetErrors Bit field reporting faults to be cleared + */ +__weak void MCI_FaultProcessing(MCI_Handle_t *pHandle, uint16_t hSetErrors, + uint16_t hResetErrors) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + /* Set current errors */ + pHandle->CurrentFaults = (pHandle->CurrentFaults | hSetErrors) & (~hResetErrors); + pHandle->PastFaults |= hSetErrors; +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief This is usually a method managed by task. It must be called + * periodically in order to check the status of the related pSTM object + * and eventually to execute the buffered command if the condition + * occurs. + * @param pHandle Pointer on the component instance to work on. + */ +__weak void MCI_ExecBufferedCommands(MCI_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (pHandle->CommandState == MCI_COMMAND_NOT_ALREADY_EXECUTED) + { + bool commandHasBeenExecuted = false; + switch (pHandle->lastCommand) + { + case MCI_CMD_EXECSPEEDRAMP: + { + pHandle->pFOCVars->bDriveInput = INTERNAL; + STC_SetControlMode(pHandle->pSTC, MCM_SPEED_MODE); + VSS_SetMecAcceleration(pHandle->pVSS, pHandle->hFinalSpeed, + pHandle->hDurationms); + commandHasBeenExecuted = STC_ExecRamp( + pHandle->pSTC, pHandle->hFinalSpeed, pHandle->hDurationms); + break; + } + + case MCI_CMD_EXECTORQUERAMP: + { + pHandle->pFOCVars->bDriveInput = INTERNAL; + STC_SetControlMode(pHandle->pSTC, MCM_TORQUE_MODE); + commandHasBeenExecuted = STC_ExecRamp( + pHandle->pSTC, pHandle->hFinalTorque, pHandle->hDurationms); + break; + } + + case MCI_CMD_SETCURRENTREFERENCES: + { + pHandle->pFOCVars->bDriveInput = EXTERNAL; + pHandle->pFOCVars->Iqdref = pHandle->Iqdref; + commandHasBeenExecuted = true; + break; + } + + case MCI_CMD_SETOPENLOOPCURRENT: + { + pHandle->pFOCVars->bDriveInput = EXTERNAL; + VSS_SetMecAcceleration(pHandle->pVSS, pHandle->hFinalSpeed, + pHandle->hDurationms); + commandHasBeenExecuted = true; + break; + } + + case MCI_CMD_SETOPENLOOPVOLTAGE: + { + pHandle->pFOCVars->bDriveInput = EXTERNAL; + VSS_SetMecAcceleration(pHandle->pVSS, pHandle->hFinalSpeed, + pHandle->hDurationms); + commandHasBeenExecuted = true; + break; + } + + default: + break; + } + + if (commandHasBeenExecuted) + { + pHandle->CommandState = MCI_COMMAND_EXECUTED_SUCCESSFULLY; + } + else + { + pHandle->CommandState = MCI_COMMAND_EXECUTED_UNSUCCESSFULLY; + } + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief Returns information about the state of the last buffered command. + * @param pHandle Pointer on the component instance to work on. + * @retval The state of the last buffered command + * + * The state returned by this function can be one of the following codes: + * - #MCI_BUFFER_EMPTY if no buffered command has been called. + * - #MCI_COMMAND_NOT_ALREADY_EXECUTED if the buffered command + * condition has not already occurred. + * - #MCI_COMMAND_EXECUTED_SUCCESSFULLY if the buffered command has + * been executed successfully. In this case calling this function resets + * the command state to #MCI_BUFFER_EMPTY. + * - #MCI_COMMAND_EXECUTED_UNSUCCESSFULLY if the buffered command has + * been executed unsuccessfully. In this case calling this function + * resets the command state to #MCI_BUFFER_EMPTY. + */ +__weak MCI_CommandState_t MCI_IsCommandAcknowledged(MCI_Handle_t *pHandle) +{ + MCI_CommandState_t retVal; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + retVal = MCI_COMMAND_EXECUTED_UNSUCCESSFULLY; + } + else + { +#endif + retVal = pHandle->CommandState; + + if ((MCI_COMMAND_EXECUTED_SUCCESSFULLY == retVal) || + (MCI_COMMAND_EXECUTED_UNSUCCESSFULLY == retVal)) + { + pHandle->CommandState = MCI_BUFFER_EMPTY; + } + else + { + /* Nothing to do */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (retVal); +} + +/** + * @brief It returns information about the state of the related pSTM object. + * @param pHandle Pointer on the component instance to work on. + * @retval State_t It returns the current state of the related pSTM object. + */ +__weak MCI_State_t MCI_GetSTMState(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? FAULT_NOW : pHandle->State); +#else + return (pHandle->State); +#endif +} + +/** + * @brief Returns the list of non-acknowledged faults that occured on the target motor + * + * This function returns a bitfield indicating the faults that occured since the state + * machine of the target motor has been moved into the #FAULT_NOW state. + * + * Possible error codes are listed in the @ref fault_codes "Fault codes" section. + * + * @param pHandle Pointer on the target motor drive structure. + * @retval uint16_t 16 bit fields with information about the faults + * historically occurred since the state machine has been moved into + */ +__weak uint16_t +MCI_GetOccurredFaults(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? MC_SW_ERROR : (uint16_t)pHandle->PastFaults); +#else + return ((uint16_t)pHandle->PastFaults); +#endif +} + +/** + * @brief Returns the list of faults that are currently active on the target motor + * + * This function returns a bitfield that indicates faults that occured on the Motor + * Control subsystem for the target motor and that are still active (the conditions + * that triggered the faults returned are still true). + * + * Possible error codes are listed in the @ref fault_codes "Fault codes" section. + * + * @param pHandle Pointer on the target motor drive structure. + */ +__weak uint16_t MCI_GetCurrentFaults(MCI_Handle_t *pHandle) // cstat + // !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? MC_SW_ERROR : (uint16_t)pHandle->CurrentFaults); +#else + return ((uint16_t)pHandle->CurrentFaults); +#endif +} + +/** + * @brief Returns the lists of current and past faults that occurred on the target motor + * + * This function returns two bitfields containing information about the faults currently + * present and the faults occurred since the state machine has been moved into the + * #FAULT_NOW state. + * + * These two bitfields are 16 bits wide each and are concatenated into the 32-bit data. + * The 16 most significant bits contains the status of the current faults while that of + * the past faults is in the 16 least significant bits. + * + * @sa MCI_GetOccurredFaults, MCI_GetCurrentFaults + * + * @param pHandle Pointer on the target motor drive structure. + */ +__weak uint32_t MCI_GetFaultState(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ + uint32_t LocalFaultState; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + LocalFaultState = MC_SW_ERROR | (MC_SW_ERROR << 16); + } + else + { +#endif + LocalFaultState = (uint32_t)(pHandle->PastFaults); + LocalFaultState |= (uint32_t)(pHandle->CurrentFaults) << 16; +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (LocalFaultState); +} + +/** + * @brief It returns the modality of the speed and torque controller. + * @param pHandle Pointer on the component instance to work on. + * @retval MC_ControlMode_t It returns the modality of STC. It can be one of + * these two values: MCM_TORQUE_MODE or MCM_SPEED_MODE. + */ +__weak MC_ControlMode_t +MCI_GetControlMode(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? MCM_TORQUE_MODE : pHandle->LastModalitySetByUser); +#else + return (pHandle->LastModalitySetByUser); +#endif +} + +/** + * @brief It returns the motor direction imposed by the last command + * (MCI_ExecSpeedRamp, MCI_ExecTorqueRamp or MCI_SetCurrentReferences). + * @param pHandle Pointer on the component instance to work on. + * @retval int16_t It returns 1 or -1 according the sign of hFinalSpeed, + * hFinalTorque or Iqdref.q of the last command. + */ +__weak int16_t +MCI_GetImposedMotorDirection(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ + int16_t retVal = 1; + +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + switch (pHandle->lastCommand) + { + case MCI_CMD_EXECSPEEDRAMP: + { + if (pHandle->hFinalSpeed < 0) + { + retVal = -1; + } + else + { + /* Nothing to do */ + } + break; + } + + case MCI_CMD_EXECTORQUERAMP: + { + if (pHandle->hFinalTorque < 0) + { + retVal = -1; + } + else + { + /* Nothing to do */ + } + break; + } + + case MCI_CMD_SETCURRENTREFERENCES: + { + if (pHandle->Iqdref.q < 0) + { + retVal = -1; + } + else + { + /* Nothing to do */ + } + break; + } + default: + break; + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (retVal); +} + +/** + * @brief It returns information about the last ramp final speed sent by the + * user expressed in the unit defined by #SPEED_UNIT. + * @param pHandle Pointer on the component instance to work on. + * @retval int16_t last ramp final speed sent by the user expressed in + * the unit defined by #SPEED_UNIT. + */ +__weak int16_t +MCI_GetLastRampFinalSpeed(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + int16_t retVal = 0; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + retVal = pHandle->hFinalSpeed; + } + return (retVal); +#else + return (pHandle->hFinalSpeed); +#endif +} + +/** + * @brief It returns information about the last ramp final torque sent by the + * user .This value represents actually the Iq current expressed in + * digit. + * @param pHandle Pointer on the component instance to work on. + * @retval int16_t last ramp final torque sent by the user expressed in digit + */ +__weak int16_t +MCI_GetLastRampFinalTorque(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + int16_t retVal = 0; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + retVal = pHandle->hFinalTorque; + } + return (retVal); +#else + return (pHandle->hFinalTorque); +#endif +} + +/** + * @brief It returns information about the last ramp final torque sent by the + * user .This value represents actually the Iq current expressed in + * Ampere. + * @param pHandle Pointer on the component instance to work on. + * @retval float_t last ramp final torque sent by the user expressed in digit + */ +__weak float_t +MCI_GetLastRampFinalTorque_F(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + float_t retVal = 0; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + retVal = ((float_t)pHandle->hFinalTorque * (float_t)pHandle->pScale->current); + } + return (retVal); +#else + return ((float_t)pHandle->hFinalTorque * (float_t)pHandle->pScale->current); +#endif +} + +/** + * @brief It returns information about the last ramp Duration sent by the + * user . + * @param pHandle Pointer on the component instance to work on. + * @retval uint16_t last ramp final torque sent by the user expressed in digit + */ +__weak uint16_t +MCI_GetLastRampFinalDuration(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + uint16_t retVal = 0; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + retVal = pHandle->hDurationms; + } + return (retVal); +#else + return (pHandle->hDurationms); +#endif +} + +/** + * @brief It returns last ramp final speed expressed in rpm. + * @param pHandle Pointer on the component instance to work on. + * @retval float_t last ramp final speed sent by the user expressed in rpm. + */ +__weak float_t +MCI_GetLastRampFinalSpeed_F(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ + float_t reVal = 0.0f; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + reVal = (((float_t)pHandle->hFinalSpeed * (float_t)U_RPM) / (float_t)SPEED_UNIT); + } + return (reVal); +} + +/** + * @brief Check if the settled speed or torque ramp has been completed. + * @param pHandle Pointer on the component instance to work on. + * @retval bool It returns true if the ramp is completed, false otherwise. + */ +__weak bool MCI_RampCompleted(MCI_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (RUN == MCI_GetSTMState(pHandle)) + { + retVal = STC_RampCompleted(pHandle->pSTC); + } + else + { + /* Nothing to do */ + } +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (retVal); +} + +/** + * @brief Stop the execution of speed ramp. + * @param pHandle Pointer on the component instance to work on. + * @retval bool It returns true if the command is executed, false otherwise. + * + * @deprecated This function is deprecated and should not be used anymore. It will be + * removed in a future version of the MCSDK. Use MCI_StopRamp() instead. + */ +__weak bool MCI_StopSpeedRamp(MCI_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? false : STC_StopSpeedRamp(pHandle->pSTC)); +#else + return (STC_StopSpeedRamp(pHandle->pSTC)); +#endif +} + +/** + * @brief Stop the execution of ongoing ramp. + * @param pHandle Pointer on the component instance to work on. + */ +__weak void MCI_StopRamp(MCI_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + STC_StopRamp(pHandle->pSTC); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @brief It returns speed sensor reliability with reference to the sensor + * actually used for reference frame transformation + * @param pHandle Pointer on the component instance to work on. + * @retval bool It returns true if the speed sensor utilized for reference + * frame transformation and (in speed control mode) for speed + * regulation is reliable, false otherwise + */ +__weak bool MCI_GetSpdSensorReliability(MCI_Handle_t *pHandle) +{ + bool status; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + status = false; + } + else + { +#endif + SpeednPosFdbk_Handle_t *SpeedSensor = STC_GetSpeedSensor(pHandle->pSTC); + status = SPD_Check(SpeedSensor); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + + return (status); +} + +/** + * @brief Returns the last computed average mechanical speed, expressed in + * the unit defined by #SPEED_UNIT and related to the sensor actually + * used by FOC algorithm + * @param pHandle Pointer on the component instance to work on. + */ +__weak int16_t MCI_GetAvrgMecSpeedUnit(MCI_Handle_t *pHandle) +{ + int16_t temp_speed; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + temp_speed = 0; + } + else + { +#endif + SpeednPosFdbk_Handle_t *SpeedSensor = STC_GetSpeedSensor(pHandle->pSTC); + temp_speed = SPD_GetAvrgMecSpeedUnit(SpeedSensor); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (temp_speed); +} + +/** + * @brief Returns the last computed average mechanical speed, expressed in rpm + * and related to the sensor actually used by FOC algorithm. + * @param pHandle Pointer on the component instance to work on. + */ +__weak float_t MCI_GetAvrgMecSpeed_F(MCI_Handle_t *pHandle) +{ + float_t returnAvrgSpeed; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + returnAvrgSpeed = 0.0f; + } + else + { +#endif + SpeednPosFdbk_Handle_t *SpeedSensor = STC_GetSpeedSensor(pHandle->pSTC); + returnAvrgSpeed = + (((float_t)SPD_GetAvrgMecSpeedUnit(SpeedSensor) * (float_t)U_RPM) / + (float_t)SPEED_UNIT); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (returnAvrgSpeed); +} + +/** + * @brief Returns the current mechanical rotor speed reference expressed in the unit + * defined by #SPEED_UNIT + * + * @param pHandle Pointer on the component instance to work on. + * + */ +__weak int16_t MCI_GetMecSpeedRefUnit(MCI_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? 0 : STC_GetMecSpeedRefUnit(pHandle->pSTC)); +#else + return (STC_GetMecSpeedRefUnit(pHandle->pSTC)); +#endif +} + +/** + * @brief Returns the current mechanical rotor speed reference expressed in rpm. + * + * @param pHandle Pointer on the component instance to work on. + * + */ +__weak float_t MCI_GetMecSpeedRef_F(MCI_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) + ? 0.0f + : (((float_t)STC_GetMecSpeedRefUnit(pHandle->pSTC) * (float_t)U_RPM) / + (float_t)SPEED_UNIT)); +#else + return ((((float_t)STC_GetMecSpeedRefUnit(pHandle->pSTC) * (float_t)U_RPM) / + (float_t)SPEED_UNIT)); +#endif +} + +/** + * @brief It returns stator current Iab in ab_t format + * @param pHandle Pointer on the component instance to work on. + * @retval ab_t Stator current Iab + */ +__weak ab_t MCI_GetIab(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + ab_t tempVal; + + if (MC_NULL == pHandle) + { + tempVal.a = 0; + tempVal.b = 0; + } + else + { + tempVal = pHandle->pFOCVars->Iab; + } + return (tempVal); +#else + return (pHandle->pFOCVars->Iab); +#endif +} + +__weak ab_f_t MCI_GetIab_F(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ + ab_f_t iab; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + iab.a = 0.0f; + iab.b = 0.0f; + } + else + { +#endif + iab.a = (float_t)((float_t)pHandle->pFOCVars->Iab.a * pHandle->pScale->current); + iab.b = (float_t)((float_t)pHandle->pFOCVars->Iab.b * pHandle->pScale->current); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (iab); +} + +/** + * @brief It returns stator current Ialphabeta in alphabeta_t format + * @param pHandle Pointer on the component instance to work on. + * @retval alphabeta_t Stator current Ialphabeta + */ +__weak alphabeta_t MCI_GetIalphabeta(MCI_Handle_t *pHandle) // cstat + // !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + alphabeta_t tempVal; + + if (MC_NULL == pHandle) + { + tempVal.alpha = 0; + tempVal.beta = 0; + } + else + { + tempVal = pHandle->pFOCVars->Ialphabeta; + } + return (tempVal); +#else + return (pHandle->pFOCVars->Ialphabeta); +#endif +} + +/** + * @brief It returns stator current Iqd in qd_t format + * @param pHandle Pointer on the component instance to work on. + * @retval qd_t Stator current Iqd + */ +__weak qd_t MCI_GetIqd(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + qd_t tempVal; + + if (MC_NULL == pHandle) + { + tempVal.q = 0; + tempVal.d = 0; + } + else + { + tempVal = pHandle->pFOCVars->Iqd; + } + return (tempVal); +#else + return (pHandle->pFOCVars->Iqd); +#endif +} + +/** + * @brief It returns stator current Iqd in float_t format + * @param pHandle Pointer on the component instance to work on. + * @retval qd_f_t Stator current Iqd (in Ampere) + */ +__weak qd_f_t MCI_GetIqd_F(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ + qd_f_t iqd; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + iqd.d = 0.0f; + iqd.q = 0.0f; + } + else + { +#endif + iqd.d = (float_t)((float_t)pHandle->pFOCVars->Iqd.d * pHandle->pScale->current); + iqd.q = (float_t)((float_t)pHandle->pFOCVars->Iqd.q * pHandle->pScale->current); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (iqd); +} + +/** + * @brief It returns stator current IqdHF in qd_t format + * @param pHandle Pointer on the component instance to work on. + * @retval qd_t Stator current IqdHF if HFI is selected as main + * sensor. Otherwise it returns { 0, 0}. + */ +__weak qd_t MCI_GetIqdHF(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + qd_t tempVal; + + if (MC_NULL == pHandle) + { + tempVal.q = 0; + tempVal.d = 0; + } + else + { + tempVal = pHandle->pFOCVars->IqdHF; + } + return (tempVal); +#else + return (pHandle->pFOCVars->IqdHF); +#endif +} + +/** + * @brief It returns stator current Iqdref in qd_t format + * @param pHandle Pointer on the component instance to work on. + * @retval qd_t Stator current Iqdref + */ +__weak qd_t MCI_GetIqdref(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + qd_t tempVal; + + if (MC_NULL == pHandle) + { + tempVal.q = 0; + tempVal.d = 0; + } + else + { + tempVal = pHandle->pFOCVars->Iqdref; + } + return (tempVal); +#else + return (pHandle->pFOCVars->Iqdref); +#endif +} + +/** + * @brief It returns stator current Iqdref in float_t format + * @param pHandle Pointer on the component instance to work on. + * @retval qd_f_t Stator current Iqdref (in Ampere) + */ +__weak qd_f_t MCI_GetIqdref_F(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ + qd_f_t iqdref; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + iqdref.d = 0.0f; + iqdref.q = 0.0f; + } + else + { +#endif + iqdref.d = + (float_t)((float_t)pHandle->pFOCVars->Iqdref.d * pHandle->pScale->current); + iqdref.q = + (float_t)((float_t)pHandle->pFOCVars->Iqdref.q * pHandle->pScale->current); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (iqdref); +} + +/** + * @brief It returns stator current Vqd in qd_t format + * @param pHandle Pointer on the component instance to work on. + * @retval qd_t Stator current Vqd + */ +__weak qd_t MCI_GetVqd(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + qd_t tempVal; + + if (MC_NULL == pHandle) + { + tempVal.q = 0; + tempVal.d = 0; + } + else + { + tempVal = pHandle->pFOCVars->Vqd; + } + return (tempVal); +#else + return (pHandle->pFOCVars->Vqd); +#endif +} + +/** + * @brief It returns stator current Valphabeta in alphabeta_t format + * @param pHandle Pointer on the component instance to work on. + * @retval alphabeta_t Stator current Valphabeta + */ +__weak alphabeta_t MCI_GetValphabeta(MCI_Handle_t *pHandle) // cstat + // !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + alphabeta_t tempVal; + + if (MC_NULL == pHandle) + { + tempVal.alpha = 0; + tempVal.beta = 0; + } + else + { + tempVal = pHandle->pFOCVars->Valphabeta; + } + return (tempVal); +#else + return (pHandle->pFOCVars->Valphabeta); +#endif +} + +/** + * @brief It returns the rotor electrical angle actually used for reference + * frame transformation + * @param pHandle Pointer on the component instance to work on. + * @retval int16_t Rotor electrical angle in dpp format + */ +__weak int16_t MCI_GetElAngledpp(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? 0 : pHandle->pFOCVars->hElAngle); +#else + return (pHandle->pFOCVars->hElAngle); +#endif +} + +/** + * @brief It returns the reference electrical torque, fed to derived class for + * Iqref and Idref computation + * @param pHandle Pointer on the component instance to work on. + * @retval int16_t Teref + */ +__weak int16_t MCI_GetTeref(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? 0 : pHandle->pFOCVars->hTeref); +#else + return (pHandle->pFOCVars->hTeref); +#endif +} + +/** + * @brief It returns the reference electrical torque. + * @param pHandle Pointer on the component instance to work on. + * @retval float_t Teref + */ +__weak float_t MCI_GetTeref_F(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_MC_INT + return ((MC_NULL == pHandle) ? 0.0f + : ((float_t)pHandle->pFOCVars->hTeref * + (float_t)pHandle->pScale->current)); +#else + return ((float_t)pHandle->pFOCVars->hTeref * (float_t)pHandle->pScale->current); +#endif +} + +/** + * @brief It returns the motor phase current amplitude (0-to-peak) in s16A + * To convert s16A into Ampere following formula must be used: + * Current(Amp) = [Current(s16A) * Vdd micro] / [65536 * Rshunt * Aop] + * @param pHandle Pointer on the component instance to work on. + * @retval int16_t Motor phase current (0-to-peak) in s16A + */ +__weak int16_t +MCI_GetPhaseCurrentAmplitude(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ + alphabeta_t Local_Curr; + int16_t wAux; + +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + wAux = 0; + } + else + { +#endif + Local_Curr = pHandle->pFOCVars->Ialphabeta; + wAux = MCM_Modulus(Local_Curr.alpha, Local_Curr.beta); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + + return (wAux); +} + +/** + * @brief It returns the applied motor phase voltage amplitude (0-to-peak) in + * s16V. To convert s16V into Volts following formula must be used: + * PhaseVoltage(V) = [PhaseVoltage(s16A) * Vbus(V)] /[sqrt(3) *32767] + * @param pHandle Pointer on the component instance to work on. + * @retval int16_t Motor phase voltage (0-to-peak) in s16V + */ +__weak int16_t +MCI_GetPhaseVoltageAmplitude(MCI_Handle_t *pHandle) // cstat !MISRAC2012-Rule-8.13 +{ + int16_t temp_wAux; +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + temp_wAux = 0; + } + else + { +#endif + alphabeta_t Local_Voltage; + int32_t wAux1; + int32_t wAux2; + + Local_Voltage = pHandle->pFOCVars->Valphabeta; + wAux1 = (int32_t)(Local_Voltage.alpha) * Local_Voltage.alpha; + wAux2 = (int32_t)(Local_Voltage.beta) * Local_Voltage.beta; + + wAux1 += wAux2; + wAux1 = MCM_Sqrt(wAux1); + + if (wAux1 > INT16_MAX) + { + wAux1 = (int32_t)INT16_MAX; + } + temp_wAux = (int16_t)wAux1; +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif + return (temp_wAux); +} + +/** + * @brief It re-initializes Iqdref variables with their default values. + * @param pHandle Pointer on the component instance to work on. + */ +__weak void MCI_Clear_Iqdref(MCI_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_MC_INT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFOCVars->Iqdref = STC_GetDefaultIqdref(pHandle->pSTC); +#ifdef NULL_PTR_CHECK_MC_INT + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_interface.h b/src/firmware/motor/mc_interface.h new file mode 100644 index 0000000000..d5a6702b2f --- /dev/null +++ b/src/firmware/motor/mc_interface.h @@ -0,0 +1,253 @@ + +/** + ****************************************************************************** + * @file mc_interface.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * MC Interface component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCInterface + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MC_INTERFACE_H +#define MC_INTERFACE_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/pwm_curr_fdbk.h" +#include "firmware/motor/mcsdk/speed_torq_ctrl.h" +#include "firmware/motor/mcsdk/virtual_speed_sensor.h" + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup CAI + * @{ + */ + + /** @addtogroup MCInterface + * @{ + */ + /* Exported types ------------------------------------------------------------*/ + /** + * @brief Status of a user (buffered) command + */ + typedef enum + { + MCI_BUFFER_EMPTY, /*!< If no buffered command has been called.*/ + MCI_COMMAND_NOT_ALREADY_EXECUTED, /*!< If the buffered command condition hasn't + already occurred.*/ + MCI_COMMAND_EXECUTED_SUCCESSFULLY, /*!< If the buffered command has been executed + successfully.*/ + MCI_COMMAND_EXECUTED_UNSUCCESSFULLY /*!< If the buffered command has been executed + unsuccessfully.*/ + } MCI_CommandState_t; + + /** + * @brief list of user (buffered) commands + */ + typedef enum + { + MCI_NOCOMMANDSYET, /*!< No command has been set by the user.*/ + MCI_CMD_EXECSPEEDRAMP, /*!< ExecSpeedRamp command coming from the user.*/ + MCI_CMD_EXECTORQUERAMP, /*!< ExecTorqueRamp command coming from the user.*/ + MCI_CMD_SETCURRENTREFERENCES, /*!< SetCurrentReferences command coming from the + user.*/ + MCI_CMD_SETOPENLOOPCURRENT, /*!< set open loop current .*/ + MCI_CMD_SETOPENLOOPVOLTAGE, /*!< set open loop voltage .*/ + } MCI_UserCommands_t; + + typedef struct + { + float voltage; + float current; + float frequency; + float padding[1]; + } __attribute__((packed)) ScaleParams_t; + + /** + * @brief State_t enum type definition, it lists all the possible state machine + * states + */ + typedef enum + { + ICLWAIT = 12, /**< The system is waiting for ICL deactivation. Is not possible + * to run the motor if ICL is active. While the ICL is active + * the state is forced to #ICLWAIT; when ICL become inactive the + * state is moved to #IDLE. */ + IDLE = + 0, /**< The state machine remains in this state as long as the + * application is not controlling the motor. This state is exited + * when the application sends a motor command or when a fault occurs. */ + ALIGNMENT = 2, /**< The encoder alignment procedure that will properly align the + * the encoder to a set mechanical angle is being executed. */ + CHARGE_BOOT_CAP = 16, /**< The gate driver boot capacitors are being charged. */ + OFFSET_CALIB = 17, /**< The offset of motor currents and voltages measurement + * cirtcuitry are being calibrated. */ + START = 4, /**< The motor start-up is procedure is being executed. */ + SWITCH_OVER = 19, /**< Transition between the open loop startup procedure and + * closed loop operation */ + RUN = 6, /**< The state machien remains in this state as long as the + * application is running (controlling) the motor. This state + * is exited when the application isues a stop command or when + * a fault occurs. */ + STOP = 8, /**< The stop motor procedure is being executed. */ + FAULT_NOW = 10, /**< The state machine is moved from any state directly to this + * state when a fault occurs. The next state can only be + * #FAULT_OVER. */ + FAULT_OVER = + 11, /*!< The state machine transitions from #FAULT_NOW to this state + * when there is no active fault condition anymore. It remains + * in this state until either a new fault condition occurs (in which + * case it goes back to the #FAULT_NOW state) or the application + * acknowledges the faults (in which case it goes to the #IDLE state). + */ + WAIT_STOP_MOTOR = 20 /**< Temporisation to make sure the motor is stopped. */ + + } MCI_State_t; + + /** + * @brief list of direct (unbffered) commands + */ + typedef enum + { + MCI_NO_COMMAND = 0, /**< No Command --- Set when going to IDLE */ + MCI_START, /**< Start controling the Motor */ + MCI_ACK_FAULTS, /**< Acknowledge Motor Control subsystem faults */ + MCI_MEASURE_OFFSETS, /**< Start the ADCs Offset measurements procedure */ + /* Shouldn't we remove this command ? */ + MCI_ALIGN_ENCODER, /**< Start the Encoder alignment procedure */ + MCI_STOP /**< Stop the Motor and the control */ + } MCI_DirectCommands_t; + + typedef struct + { + SpeednTorqCtrl_Handle_t + *pSTC; /*!< Speed and torque controller object used by MCI.*/ + pFOCVars_t pFOCVars; /*!< Pointer to FOC vars used by MCI.*/ + PWMC_Handle_t *pPWM; /*!< Pointer to PWM handle structure.*/ + VirtualSpeedSensor_Handle_t *pVSS; + MCI_UserCommands_t lastCommand; /*!< Last command coming from the user.*/ + int16_t hFinalSpeed; /*!< Final speed of last ExecSpeedRamp command.*/ + int16_t hFinalTorque; /*!< Final torque of last ExecTorqueRamp command.*/ + qd_t Iqdref; /*!< Current component of last SetCurrentReferences command.*/ + ScaleParams_t *pScale; + uint16_t hDurationms; /*!< Duration in ms of last ExecSpeedRamp or ExecTorqueRamp + command.*/ + MCI_DirectCommands_t DirectCommand; + MCI_State_t State; + uint16_t CurrentFaults; + uint16_t PastFaults; + MCI_CommandState_t CommandState; /*!< The status of the buffered command.*/ + MC_ControlMode_t + LastModalitySetByUser; /*!< The last MC_ControlMode_t set by the user. */ + } MCI_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + void MCI_Init(MCI_Handle_t *pHandle, SpeednTorqCtrl_Handle_t *pSTC, + pFOCVars_t pFOCVars, PWMC_Handle_t *pPWMHandle); + void MCI_ExecBufferedCommands(MCI_Handle_t *pHandle); + void MCI_ExecSpeedRamp(MCI_Handle_t *pHandle, int16_t hFinalSpeed, + uint16_t hDurationms); + void MCI_ExecSpeedRamp_F(MCI_Handle_t *pHandle, const float_t FinalSpeed, + uint16_t hDurationms); + + void MCI_ExecTorqueRamp(MCI_Handle_t *pHandle, int16_t hFinalTorque, + uint16_t hDurationms); + void MCI_ExecTorqueRamp_F(MCI_Handle_t *pHandle, const float_t FinalTorque, + uint16_t hDurationms); + + void MCI_SetCurrentReferences(MCI_Handle_t *pHandle, qd_t Iqdref); + void MCI_SetCurrentReferences_F(MCI_Handle_t *pHandle, qd_f_t IqdRef); + + void MCI_SetIdref(MCI_Handle_t *pHandle, int16_t hNewIdRef); + void MCI_SetIdref_F(MCI_Handle_t *pHandle, float_t NewIdRef); + bool MCI_StartMotor(MCI_Handle_t *pHandle); + bool MCI_StartWithPolarizationMotor(MCI_Handle_t *pHandle); + bool MCI_StartOffsetMeasurments(MCI_Handle_t *pHandle); + bool MCI_GetCalibratedOffsetsMotor(MCI_Handle_t *pHandle, + PolarizationOffsets_t *PolarizationOffsets); + bool MCI_SetCalibratedOffsetsMotor(MCI_Handle_t *pHandle, + PolarizationOffsets_t *PolarizationOffsets); + bool MCI_StopMotor(MCI_Handle_t *pHandle); + bool MCI_FaultAcknowledged(MCI_Handle_t *pHandle); + void MCI_FaultProcessing(MCI_Handle_t *pHandle, uint16_t hSetErrors, + uint16_t hResetErrors); + uint32_t MCI_GetFaultState(MCI_Handle_t *pHandle); + MCI_CommandState_t MCI_IsCommandAcknowledged(MCI_Handle_t *pHandle); + MCI_State_t MCI_GetSTMState(MCI_Handle_t *pHandle); + uint16_t MCI_GetOccurredFaults(MCI_Handle_t *pHandle); + uint16_t MCI_GetCurrentFaults(MCI_Handle_t *pHandle); + float_t MCI_GetMecSpeedRef_F(MCI_Handle_t *pHandle); + float_t MCI_GetAvrgMecSpeed_F(MCI_Handle_t *pHandle); + MC_ControlMode_t MCI_GetControlMode(MCI_Handle_t *pHandle); + int16_t MCI_GetImposedMotorDirection(MCI_Handle_t *pHandle); + int16_t MCI_GetLastRampFinalSpeed(MCI_Handle_t *pHandle); + int16_t MCI_GetLastRampFinalTorque(MCI_Handle_t *pHandle); + float_t MCI_GetLastRampFinalTorque_F(MCI_Handle_t *pHandle); + uint16_t MCI_GetLastRampFinalDuration(MCI_Handle_t *pHandle); + bool MCI_RampCompleted(MCI_Handle_t *pHandle); + float_t MCI_GetLastRampFinalSpeed_F(MCI_Handle_t *pHandle); + bool MCI_StopSpeedRamp(MCI_Handle_t *pHandle); + void MCI_StopRamp(MCI_Handle_t *pHandle); + bool MCI_GetSpdSensorReliability(MCI_Handle_t *pHandle); + int16_t MCI_GetAvrgMecSpeedUnit(MCI_Handle_t *pHandle); + int16_t MCI_GetMecSpeedRefUnit(MCI_Handle_t *pHandle); + ab_t MCI_GetIab(MCI_Handle_t *pHandle); + ab_f_t MCI_GetIab_F(MCI_Handle_t *pHandle); + alphabeta_t MCI_GetIalphabeta(MCI_Handle_t *pHandle); + qd_t MCI_GetIqd(MCI_Handle_t *pHandle); + qd_f_t MCI_GetIqd_F(MCI_Handle_t *pHandle); + qd_t MCI_GetIqdHF(MCI_Handle_t *pHandle); + qd_t MCI_GetIqdref(MCI_Handle_t *pHandle); + qd_f_t MCI_GetIqdref_F(MCI_Handle_t *pHandle); + qd_t MCI_GetVqd(MCI_Handle_t *pHandle); + alphabeta_t MCI_GetValphabeta(MCI_Handle_t *pHandle); + int16_t MCI_GetElAngledpp(MCI_Handle_t *pHandle); + int16_t MCI_GetTeref(MCI_Handle_t *pHandle); + float_t MCI_GetTeref_F(MCI_Handle_t *pHandle); + int16_t MCI_GetPhaseCurrentAmplitude(MCI_Handle_t *pHandle); + int16_t MCI_GetPhaseVoltageAmplitude(MCI_Handle_t *pHandle); + void MCI_Clear_Iqdref(MCI_Handle_t *pHandle); + + void MCI_SetSpeedMode(MCI_Handle_t *pHandle); + void MCI_SetOpenLoopCurrent(MCI_Handle_t *pHandle); + void MCI_SetOpenLoopVoltage(MCI_Handle_t *pHandle); + void MCI_SetOpenLoopCurrentMode(MCI_Handle_t *pHandle); + void MCI_SetOpenLoopVoltageMode(MCI_Handle_t *pHandle); + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* MC_INTERFACE_H */ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_math.c b/src/firmware/motor/mc_math.c new file mode 100644 index 0000000000..088a3eb9a7 --- /dev/null +++ b/src/firmware/motor/mc_math.c @@ -0,0 +1,457 @@ +/** + ****************************************************************************** + * @file mc_math.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides mathematics functions useful for and specific to + * Motor Control. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mc_math.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup MC_Math Motor Control Math functions + * @brief Motor Control Mathematic functions of the Motor Control SDK + * + * @todo Document the Motor Control Math "module". + * + * @{ + */ + +/* Private macro -------------------------------------------------------------*/ + +#define SIN_COS_TABLE \ + { \ + 0x0000, 0x00C9, 0x0192, 0x025B, 0x0324, 0x03ED, 0x04B6, 0x057F, 0x0648, 0x0711, \ + 0x07D9, 0x08A2, 0x096A, 0x0A33, 0x0AFB, 0x0BC4, 0x0C8C, 0x0D54, 0x0E1C, \ + 0x0EE3, 0x0FAB, 0x1072, 0x113A, 0x1201, 0x12C8, 0x138F, 0x1455, 0x151C, \ + 0x15E2, 0x16A8, 0x176E, 0x1833, 0x18F9, 0x19BE, 0x1A82, 0x1B47, 0x1C0B, \ + 0x1CCF, 0x1D93, 0x1E57, 0x1F1A, 0x1FDD, 0x209F, 0x2161, 0x2223, 0x22E5, \ + 0x23A6, 0x2467, 0x2528, 0x25E8, 0x26A8, 0x2767, 0x2826, 0x28E5, 0x29A3, \ + 0x2A61, 0x2B1F, 0x2BDC, 0x2C99, 0x2D55, 0x2E11, 0x2ECC, 0x2F87, 0x3041, \ + 0x30FB, 0x31B5, 0x326E, 0x3326, 0x33DF, 0x3496, 0x354D, 0x3604, 0x36BA, \ + 0x376F, 0x3824, 0x38D9, 0x398C, 0x3A40, 0x3AF2, 0x3BA5, 0x3C56, 0x3D07, \ + 0x3DB8, 0x3E68, 0x3F17, 0x3FC5, 0x4073, 0x4121, 0x41CE, 0x427A, 0x4325, \ + 0x43D0, 0x447A, 0x4524, 0x45CD, 0x4675, 0x471C, 0x47C3, 0x4869, 0x490F, \ + 0x49B4, 0x4A58, 0x4AFB, 0x4B9D, 0x4C3F, 0x4CE0, 0x4D81, 0x4E20, 0x4EBF, \ + 0x4F5D, 0x4FFB, 0x5097, 0x5133, 0x51CE, 0x5268, 0x5302, 0x539B, 0x5432, \ + 0x54C9, 0x5560, 0x55F5, 0x568A, 0x571D, 0x57B0, 0x5842, 0x58D3, 0x5964, \ + 0x59F3, 0x5A82, 0x5B0F, 0x5B9C, 0x5C28, 0x5CB3, 0x5D3E, 0x5DC7, 0x5E4F, \ + 0x5ED7, 0x5F5D, 0x5FE3, 0x6068, 0x60EB, 0x616E, 0x61F0, 0x6271, 0x62F1, \ + 0x6370, 0x63EE, 0x646C, 0x64E8, 0x6563, 0x65DD, 0x6656, 0x66CF, 0x6746, \ + 0x67BC, 0x6832, 0x68A6, 0x6919, 0x698B, 0x69FD, 0x6A6D, 0x6ADC, 0x6B4A, \ + 0x6BB7, 0x6C23, 0x6C8E, 0x6CF8, 0x6D61, 0x6DC9, 0x6E30, 0x6E96, 0x6EFB, \ + 0x6F5E, 0x6FC1, 0x7022, 0x7083, 0x70E2, 0x7140, 0x719D, 0x71F9, 0x7254, \ + 0x72AE, 0x7307, 0x735E, 0x73B5, 0x740A, 0x745F, 0x74B2, 0x7504, 0x7555, \ + 0x75A5, 0x75F3, 0x7641, 0x768D, 0x76D8, 0x7722, 0x776B, 0x77B3, 0x77FA, \ + 0x783F, 0x7884, 0x78C7, 0x7909, 0x794A, 0x7989, 0x79C8, 0x7A05, 0x7A41, \ + 0x7A7C, 0x7AB6, 0x7AEE, 0x7B26, 0x7B5C, 0x7B91, 0x7BC5, 0x7BF8, 0x7C29, \ + 0x7C59, 0x7C88, 0x7CB6, 0x7CE3, 0x7D0E, 0x7D39, 0x7D62, 0x7D89, 0x7DB0, \ + 0x7DD5, 0x7DFA, 0x7E1D, 0x7E3E, 0x7E5F, 0x7E7E, 0x7E9C, 0x7EB9, 0x7ED5, \ + 0x7EEF, 0x7F09, 0x7F21, 0x7F37, 0x7F4D, 0x7F61, 0x7F74, 0x7F86, 0x7F97, \ + 0x7FA6, 0x7FB4, 0x7FC1, 0x7FCD, 0x7FD8, 0x7FE1, 0x7FE9, 0x7FF0, 0x7FF5, \ + 0x7FF9, 0x7FFD, 0x7FFE \ + } + +#define SIN_MASK 0x0300u +#define U0_90 0x0200u +#define U90_180 0x0300u +#define U180_270 0x0000u +#define U270_360 0x0100u + +/* Private variables ---------------------------------------------------------*/ +const int16_t hSin_Cos_Table[256] = SIN_COS_TABLE; + +#define divSQRT_3 (int32_t)0x49E6 /* 1/sqrt(3) in q1.15 format=0.5773315*/ + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief This function transforms stator values a and b (which are + * directed along axes each displaced by 120 degrees) into values + * alpha and beta in a stationary qd reference frame. + * alpha = a + * beta = -(2*b+a)/sqrt(3) + * @param Input: stator values a and b in ab_t format + * @retval Stator values alpha and beta in alphabeta_t format + */ +__weak alphabeta_t MCM_Clarke(ab_t Input) +{ + alphabeta_t Output; + + int32_t a_divSQRT3_tmp; + int32_t b_divSQRT3_tmp; + int32_t wbeta_tmp; + int16_t hbeta_tmp; + + /* qIalpha = qIas*/ + Output.alpha = Input.a; + + a_divSQRT3_tmp = divSQRT_3 * ((int32_t)Input.a); + + b_divSQRT3_tmp = divSQRT_3 * ((int32_t)Input.b); + + /*qIbeta = -(2*qIbs+qIas)/sqrt(3)*/ +#ifndef FULL_MISRA_C_COMPLIANCY_MC_MATH + /* WARNING: the below instruction is not MISRA compliant, user should verify + that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by + the compiler to perform the shift (instead of LSR logical shift right) */ + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wbeta_tmp = (-(a_divSQRT3_tmp) - (b_divSQRT3_tmp) - (b_divSQRT3_tmp)) >> 15; +#else + wbeta_tmp = (-(a_divSQRT3_tmp) - (b_divSQRT3_tmp) - (b_divSQRT3_tmp)) / 32768; +#endif + + /* Check saturation of Ibeta */ + if (wbeta_tmp > INT16_MAX) + { + hbeta_tmp = INT16_MAX; + } + else if (wbeta_tmp < (-32768)) + { + hbeta_tmp = ((int16_t)-32768); + } + else + { + hbeta_tmp = ((int16_t)wbeta_tmp); + } + + Output.beta = hbeta_tmp; + + if (((int16_t)-32768) == Output.beta) + { + Output.beta = -32767; + } + + return (Output); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief This function transforms stator values alpha and beta, which + * belong to a stationary qd reference frame, to a rotor flux + * synchronous reference frame (properly oriented), so as q and d. + * d= alpha *sin(theta)+ beta *cos(Theta) + * q= alpha *cos(Theta)- beta *sin(Theta) + * @param Input: stator values alpha and beta in alphabeta_t format + * @param Theta: rotating frame angular position in q1.15 format + * @retval Stator values q and d in qd_t format + */ +__weak qd_t MCM_Park(alphabeta_t Input, int16_t Theta) +{ + qd_t Output; + int32_t d_tmp_1; + int32_t d_tmp_2; + int32_t q_tmp_1; + int32_t q_tmp_2; + int32_t wqd_tmp; + int16_t hqd_tmp; + Trig_Components Local_Vector_Components; + + Local_Vector_Components = MCM_Trig_Functions(Theta); + + /*No overflow guaranteed*/ + q_tmp_1 = Input.alpha * ((int32_t)Local_Vector_Components.hCos); + + /*No overflow guaranteed*/ + q_tmp_2 = Input.beta * ((int32_t)Local_Vector_Components.hSin); + + /*Iq component in Q1.15 Format */ +#ifndef FULL_MISRA_C_COMPLIANCY_MC_MATH + /* WARNING: the below instruction is not MISRA compliant, user should verify + that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by + the compiler to perform the shift (instead of LSR logical shift right) */ + wqd_tmp = (q_tmp_1 - q_tmp_2) >> + 15; // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 +#else + wqd_tmp = (q_tmp_1 - q_tmp_2) / 32768; +#endif + + /* Check saturation of Iq */ + if (wqd_tmp > INT16_MAX) + { + hqd_tmp = INT16_MAX; + } + else if (wqd_tmp < (-32768)) + { + hqd_tmp = ((int16_t)-32768); + } + else + { + hqd_tmp = ((int16_t)wqd_tmp); + } + + Output.q = hqd_tmp; + + if (((int16_t)-32768) == Output.q) + { + Output.q = -32767; + } + + /*No overflow guaranteed*/ + d_tmp_1 = Input.alpha * ((int32_t)Local_Vector_Components.hSin); + + /*No overflow guaranteed*/ + d_tmp_2 = Input.beta * ((int32_t)Local_Vector_Components.hCos); + + /*Id component in Q1.15 Format */ +#ifndef FULL_MISRA_C_COMPLIANCY_MC_MATH + /* WARNING: the below instruction is not MISRA compliant, user should verify + that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by + the compiler to perform the shift (instead of LSR logical shift right) */ + wqd_tmp = (d_tmp_1 + d_tmp_2) >> + 15; // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 +#else + wqd_tmp = (d_tmp_1 + d_tmp_2) / 32768; +#endif + + /* Check saturation of Id */ + if (wqd_tmp > INT16_MAX) + { + hqd_tmp = INT16_MAX; + } + else if (wqd_tmp < (-32768)) + { + hqd_tmp = ((int16_t)-32768); + } + else + { + hqd_tmp = ((int16_t)wqd_tmp); + } + + Output.d = hqd_tmp; + + if (((int16_t)-32768) == Output.d) + { + Output.d = -32767; + } + + return (Output); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief This function transforms stator voltage qVq and qVd, that belong to + * a rotor flux synchronous rotating frame, to a stationary reference + * frame, so as to obtain qValpha and qVbeta: + * Valfa= Vq*Cos(theta)+ Vd*Sin(theta) + * Vbeta=-Vq*Sin(theta)+ Vd*Cos(theta) + * @param Input: stator voltage Vq and Vd in qd_t format + * @param Theta: rotating frame angular position in q1.15 format + * @retval Stator voltage Valpha and Vbeta in qd_t format + */ +__weak alphabeta_t MCM_Rev_Park(qd_t Input, int16_t Theta) +{ + int32_t alpha_tmp1; + int32_t alpha_tmp2; + int32_t beta_tmp1; + int32_t beta_tmp2; + Trig_Components Local_Vector_Components; + alphabeta_t Output; + + Local_Vector_Components = MCM_Trig_Functions(Theta); + + /*No overflow guaranteed*/ + alpha_tmp1 = Input.q * ((int32_t)Local_Vector_Components.hCos); + alpha_tmp2 = Input.d * ((int32_t)Local_Vector_Components.hSin); + +#ifndef FULL_MISRA_C_COMPLIANCY_MC_MATH + /* WARNING: the below instruction is not MISRA compliant, user should verify + that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by + the compiler to perform the shift (instead of LSR logical shift right) */ + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + Output.alpha = (int16_t)(((alpha_tmp1) + (alpha_tmp2)) >> 15); +#else + Output.alpha = (int16_t)(((alpha_tmp1) + (alpha_tmp2)) / 32768); +#endif + + beta_tmp1 = Input.q * ((int32_t)Local_Vector_Components.hSin); + beta_tmp2 = Input.d * ((int32_t)Local_Vector_Components.hCos); + +#ifndef FULL_MISRA_C_COMPLIANCY_MC_MATH + /* WARNING: the below instruction is not MISRA compliant, user should verify + that Cortex-M3 assembly instruction ASR (arithmetic shift right) is used by + the compiler to perform the shift (instead of LSR logical shift right) */ + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + Output.beta = (int16_t)((beta_tmp2 - beta_tmp1) >> 15); +#else + Output.beta = (int16_t)((beta_tmp2 - beta_tmp1) / 32768); +#endif + + return (Output); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief This function returns cosine and sine functions of the angle fed in + * input + * @param hAngle: angle in q1.15 format + * @retval Sin(angle) and Cos(angle) in Trig_Components format + */ + +__weak Trig_Components MCM_Trig_Functions(int16_t hAngle) +{ + int32_t shindex; + uint16_t uhindex; + + Trig_Components Local_Components; + + /* 10 bit index computation */ + shindex = (((int32_t)32768) + ((int32_t)hAngle)); + uhindex = (uint16_t)shindex; + uhindex /= ((uint16_t)64); + + switch (((uint16_t)uhindex) & SIN_MASK) + { + case U0_90: + { + Local_Components.hSin = hSin_Cos_Table[(uint8_t)(uhindex)]; + Local_Components.hCos = hSin_Cos_Table[(uint8_t)(0xFFu - (uint8_t)(uhindex))]; + break; + } + + case U90_180: + { + Local_Components.hSin = hSin_Cos_Table[(uint8_t)(0xFFu - (uint8_t)(uhindex))]; + Local_Components.hCos = -hSin_Cos_Table[(uint8_t)(uhindex)]; + break; + } + + case U180_270: + { + Local_Components.hSin = -hSin_Cos_Table[(uint8_t)(uhindex)]; + Local_Components.hCos = + -hSin_Cos_Table[(uint8_t)(0xFFu - (uint8_t)(uhindex))]; + break; + } + + case U270_360: + { + Local_Components.hSin = + -hSin_Cos_Table[(uint8_t)(0xFFu - (uint8_t)(uhindex))]; + Local_Components.hCos = hSin_Cos_Table[(uint8_t)(uhindex)]; + break; + } + + default: + break; + } + return (Local_Components); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief It calculates the square root of a non-negative int32_t. It returns 0 + * for negative int32_t. + * @param Input int32_t number + * @retval int32_t Square root of Input (0 if Input<0) + */ +__weak int32_t MCM_Sqrt(int32_t wInput) +{ + int32_t wtemprootnew; + + if (wInput > 0) + { + uint8_t biter = 0u; + int32_t wtemproot; + + if (wInput <= ((int32_t)2097152)) + { + wtemproot = ((int32_t)128); + } + else + { + wtemproot = ((int32_t)8192); + } + + do + { + wtemprootnew = (wtemproot + (wInput / wtemproot)) / (int32_t)2; + if ((wtemprootnew == wtemproot) || ((int32_t)0 == wtemproot)) + { + biter = 6U; + } + else + { + biter++; + wtemproot = wtemprootnew; + } + } while (biter < 6U); + } + else + { + wtemprootnew = (int32_t)0; + } + + return (wtemprootnew); +} + +/** + * @brief This function codify a floating point number into the relative + * 32bit integer. + * @param float Floating point number to be coded. + * @retval uint32_t Coded 32bit integer. + */ +__weak uint32_t MCM_floatToIntBit(float_t x) // cstat !MISRAC2012-Dir-4.6_a +{ + uint32_t *pInt; + pInt = (uint32_t *)(&x); // cstat !MISRAC2012-Rule-11.3 + return (*pInt); +} + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_math.h b/src/firmware/motor/mc_math.h new file mode 100644 index 0000000000..63d0668837 --- /dev/null +++ b/src/firmware/motor/mc_math.h @@ -0,0 +1,500 @@ + +/** + ****************************************************************************** + * @file mc_math.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides mathematics functions useful for and specific to + * Motor Control. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MC_Math + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MC_MATH_H +#define MC_MATH_H + +/* Includes ------------------------------------------------------------------*/ +#include "mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup MC_Math + * @{ + */ +#define SQRT_2 1.4142 +#define SQRT_3 1.732 + +/** + * @brief Macro to compute logarithm of two + */ +#define LOG2(x) \ + (((x) == 65535) \ + ? 16 \ + : (((x) == (2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2)) \ + ? 15 \ + : (((x) == (2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2)) \ + ? 14 \ + : (((x) == (2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2)) \ + ? 13 \ + : (((x) == \ + (2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2)) \ + ? 12 \ + : (((x) == \ + (2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2)) \ + ? 11 \ + : (((x) == \ + (2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2)) \ + ? 10 \ + : (((x) == (2 * 2 * 2 * 2 * 2 * 2 * \ + 2 * 2 * 2)) \ + ? 9 \ + : (((x) == (2 * 2 * 2 * 2 * \ + 2 * 2 * 2 * 2)) \ + ? 8 \ + : (((x) == \ + (2 * 2 * 2 * 2 * \ + 2 * 2 * 2)) \ + ? 7 \ + : (((x) == \ + (2 * 2 * 2 * \ + 2 * 2 * 2)) \ + ? 6 \ + : (((x) == \ + (2 * \ + 2 * \ + 2 * \ + 2 * \ + 2)) \ + ? 5 \ + : (((x) == \ + (2 * \ + 2 * \ + 2 * \ + 2)) \ + ? 4 \ + : (((x) == \ + (2 * \ + 2 * \ + 2)) \ + ? 3 \ + : (((x) == \ + (2 * \ + 2)) \ + ? 2 \ + : (((x) == \ + 2) \ + ? 1 \ + : (((x) == \ + 1) \ + ? 0 \ + : -1))))))))))))))))) + +/** + * @brief Trigonometrical functions type definition + */ +typedef struct +{ + int16_t hCos; + int16_t hSin; +} Trig_Components; + +/** + * @brief This function transforms stator currents Ia and qIb (which are + * directed along axes each displaced by 120 degrees) into currents + * Ialpha and Ibeta in a stationary qd reference frame. + * Ialpha = Ia + * Ibeta = -(2*Ib+Ia)/sqrt(3) + * @param Curr_Input: stator current Ia and Ib in ab_t format + * @retval Stator current Ialpha and Ibeta in alphabeta_t format + */ +alphabeta_t MCM_Clarke(ab_t Input); + +/** + * @brief This function transforms stator values alpha and beta, which + * belong to a stationary qd reference frame, to a rotor flux + * synchronous reference frame (properly oriented), so as Iq and Id. + * Id= Ialpha *sin(theta)+qIbeta *cos(Theta) + * Iq=qIalpha *cos(Theta)-qIbeta *sin(Theta) + * @param Curr_Input: stator values alpha and beta in alphabeta_t format + * @param Theta: rotating frame angular position in q1.15 format + * @retval Stator current q and d in qd_t format + */ +qd_t MCM_Park(alphabeta_t Input, int16_t Theta); + +/** + * @brief This function transforms stator voltage qVq and qVd, that belong to + * a rotor flux synchronous rotating frame, to a stationary reference + * frame, so as to obtain qValpha and qVbeta: + * Valfa= Vq*Cos(theta)+ Vd*Sin(theta) + * Vbeta=-Vq*Sin(theta)+ Vd*Cos(theta) + * @param Curr_Input: stator voltage Vq and Vd in qd_t format + * @param Theta: rotating frame angular position in q1.15 format + * @retval Stator values alpha and beta in alphabeta_t format + */ +alphabeta_t MCM_Rev_Park(qd_t Input, int16_t Theta); + +/** + * @brief This function returns cosine and sine functions of the angle fed in + * input + * @param hAngle: angle in q1.15 format + * @retval Trig_Components Cos(angle) and Sin(angle) in Trig_Components format + */ +Trig_Components MCM_Trig_Functions(int16_t hAngle); + +/** + * @brief It calculates the square root of a non-negative s32. It returns 0 + * for negative s32. + * @param Input int32_t number + * @retval int32_t Square root of Input (0 if Input<0) + */ +int32_t MCM_Sqrt(int32_t wInput); + +/** + * @brief Sqrt table used by Circle Limitation function + * used for STM32F0/STM32G0 series only + */ +#define SQRT_CIRCLE_LIMITATION \ + { \ + 0, 1023, 1448, 1773, 2047, 2289, 2508, 2709, 2896, 3071, 3238, 3396, 3547, 3691, \ + 3831, 3965, 4095, 4221, 4344, 4463, 4579, 4692, 4802, 4910, 5016, 5119, \ + 5221, 5320, 5418, 5514, 5608, 5701, 5792, 5882, 5970, 6057, 6143, 6228, \ + 6312, 6394, 6476, 6556, 6636, 6714, 6792, 6868, 6944, 7019, 7094, 7167, \ + 7240, 7312, 7383, 7454, 7524, 7593, 7662, 7730, 7798, 7865, 7931, 7997, \ + 8062, 8127, 8191, 8255, 8318, 8381, 8443, 8505, 8567, 8628, 8688, 8748, \ + 8808, 8867, 8926, 8985, 9043, 9101, 9158, 9215, 9272, 9328, 9384, 9440, \ + 9495, 9550, 9605, 9660, 9714, 9768, 9821, 9874, 9927, 9980, 10032, 10084, \ + 10136, 10188, 10239, 10290, 10341, 10392, 10442, 10492, 10542, 10592, 10641, \ + 10690, 10739, 10788, 10836, 10884, 10932, 10980, 11028, 11075, 11123, 11170, \ + 11217, 11263, 11310, 11356, 11402, 11448, 11494, 11539, 11584, 11630, 11675, \ + 11719, 11764, 11808, 11853, 11897, 11941, 11985, 12028, 12072, 12115, 12158, \ + 12201, 12244, 12287, 12330, 12372, 12414, 12457, 12499, 12541, 12582, 12624, \ + 12665, 12707, 12748, 12789, 12830, 12871, 12911, 12952, 12992, 13032, 13073, \ + 13113, 13153, 13192, 13232, 13272, 13311, 13350, 13390, 13429, 13468, 13507, \ + 13545, 13584, 13623, 13661, 13699, 13737, 13776, 13814, 13851, 13889, 13927, \ + 13965, 14002, 14039, 14077, 14114, 14151, 14188, 14225, 14262, 14298, 14335, \ + 14372, 14408, 14444, 14481, 14517, 14553, 14589, 14625, 14661, 14696, 14732, \ + 14767, 14803, 14838, 14874, 14909, 14944, 14979, 15014, 15049, 15084, 15118, \ + 15153, 15187, 15222, 15256, 15291, 15325, 15359, 15393, 15427, 15461, 15495, \ + 15529, 15562, 15596, 15630, 15663, 15697, 15730, 15763, 15797, 15830, 15863, \ + 15896, 15929, 15962, 15994, 16027, 16060, 16092, 16125, 16157, 16190, 16222, \ + 16254, 16287, 16319, 16351, 16383, 16415, 16447, 16479, 16510, 16542, 16574, \ + 16605, 16637, 16669, 16700, 16731, 16763, 16794, 16825, 16856, 16887, 16918, \ + 16949, 16980, 17011, 17042, 17072, 17103, 17134, 17164, 17195, 17225, 17256, \ + 17286, 17316, 17347, 17377, 17407, 17437, 17467, 17497, 17527, 17557, 17587, \ + 17617, 17646, 17676, 17706, 17735, 17765, 17794, 17824, 17853, 17882, 17912, \ + 17941, 17970, 17999, 18028, 18057, 18086, 18115, 18144, 18173, 18202, 18231, \ + 18259, 18288, 18317, 18345, 18374, 18402, 18431, 18459, 18488, 18516, 18544, \ + 18573, 18601, 18629, 18657, 18685, 18713, 18741, 18769, 18797, 18825, 18853, \ + 18881, 18908, 18936, 18964, 18991, 19019, 19046, 19074, 19101, 19129, 19156, \ + 19184, 19211, 19238, 19265, 19293, 19320, 19347, 19374, 19401, 19428, 19455, \ + 19482, 19509, 19536, 19562, 19589, 19616, 19643, 19669, 19696, 19723, 19749, \ + 19776, 19802, 19829, 19855, 19881, 19908, 19934, 19960, 19987, 20013, 20039, \ + 20065, 20091, 20117, 20143, 20169, 20195, 20221, 20247, 20273, 20299, 20325, \ + 20350, 20376, 20402, 20428, 20453, 20479, 20504, 20530, 20556, 20581, 20606, \ + 20632, 20657, 20683, 20708, 20733, 20759, 20784, 20809, 20834, 20859, 20884, \ + 20910, 20935, 20960, 20985, 21010, 21035, 21059, 21084, 21109, 21134, 21159, \ + 21184, 21208, 21233, 21258, 21282, 21307, 21331, 21356, 21381, 21405, 21430, \ + 21454, 21478, 21503, 21527, 21552, 21576, 21600, 21624, 21649, 21673, 21697, \ + 21721, 21745, 21769, 21793, 21817, 21841, 21865, 21889, 21913, 21937, 21961, \ + 21985, 22009, 22033, 22056, 22080, 22104, 22128, 22151, 22175, 22199, 22222, \ + 22246, 22269, 22293, 22316, 22340, 22363, 22387, 22410, 22434, 22457, 22480, \ + 22504, 22527, 22550, 22573, 22597, 22620, 22643, 22666, 22689, 22712, 22735, \ + 22758, 22781, 22804, 22827, 22850, 22873, 22896, 22919, 22942, 22965, 22988, \ + 23010, 23033, 23056, 23079, 23101, 23124, 23147, 23169, 23192, 23214, 23237, \ + 23260, 23282, 23305, 23327, 23350, 23372, 23394, 23417, 23439, 23462, 23484, \ + 23506, 23529, 23551, 23573, 23595, 23617, 23640, 23662, 23684, 23706, 23728, \ + 23750, 23772, 23794, 23816, 23838, 23860, 23882, 23904, 23926, 23948, 23970, \ + 23992, 24014, 24036, 24057, 24079, 24101, 24123, 24144, 24166, 24188, 24209, \ + 24231, 24253, 24274, 24296, 24317, 24339, 24360, 24382, 24403, 24425, 24446, \ + 24468, 24489, 24511, 24532, 24553, 24575, 24596, 24617, 24639, 24660, 24681, \ + 24702, 24724, 24745, 24766, 24787, 24808, 24829, 24851, 24872, 24893, 24914, \ + 24935, 24956, 24977, 24998, 25019, 25040, 25061, 25082, 25102, 25123, 25144, \ + 25165, 25186, 25207, 25227, 25248, 25269, 25290, 25310, 25331, 25352, 25372, \ + 25393, 25414, 25434, 25455, 25476, 25496, 25517, 25537, 25558, 25578, 25599, \ + 25619, 25640, 25660, 25681, 25701, 25721, 25742, 25762, 25782, 25803, 25823, \ + 25843, 25864, 25884, 25904, 25924, 25945, 25965, 25985, 26005, 26025, 26045, \ + 26065, 26086, 26106, 26126, 26146, 26166, 26186, 26206, 26226, 26246, 26266, \ + 26286, 26306, 26326, 26346, 26365, 26385, 26405, 26425, 26445, 26465, 26484, \ + 26504, 26524, 26544, 26564, 26583, 26603, 26623, 26642, 26662, 26682, 26701, \ + 26721, 26741, 26760, 26780, 26799, 26819, 26838, 26858, 26877, 26897, 26916, \ + 26936, 26955, 26975, 26994, 27014, 27033, 27052, 27072, 27091, 27111, 27130, \ + 27149, 27168, 27188, 27207, 27226, 27246, 27265, 27284, 27303, 27322, 27342, \ + 27361, 27380, 27399, 27418, 27437, 27456, 27475, 27495, 27514, 27533, 27552, \ + 27571, 27590, 27609, 27628, 27647, 27666, 27685, 27703, 27722, 27741, 27760, \ + 27779, 27798, 27817, 27836, 27854, 27873, 27892, 27911, 27930, 27948, 27967, \ + 27986, 28005, 28023, 28042, 28061, 28079, 28098, 28117, 28135, 28154, 28173, \ + 28191, 28210, 28228, 28247, 28265, 28284, 28303, 28321, 28340, 28358, 28377, \ + 28395, 28413, 28432, 28450, 28469, 28487, 28506, 28524, 28542, 28561, 28579, \ + 28597, 28616, 28634, 28652, 28671, 28689, 28707, 28725, 28744, 28762, 28780, \ + 28798, 28817, 28835, 28853, 28871, 28889, 28907, 28925, 28944, 28962, 28980, \ + 28998, 29016, 29034, 29052, 29070, 29088, 29106, 29124, 29142, 29160, 29178, \ + 29196, 29214, 29232, 29250, 29268, 29286, 29304, 29322, 29339, 29357, 29375, \ + 29393, 29411, 29429, 29446, 29464, 29482, 29500, 29518, 29535, 29553, 29571, \ + 29588, 29606, 29624, 29642, 29659, 29677, 29695, 29712, 29730, 29748, 29765, \ + 29783, 29800, 29818, 29835, 29853, 29871, 29888, 29906, 29923, 29941, 29958, \ + 29976, 29993, 30011, 30028, 30046, 30063, 30080, 30098, 30115, 30133, 30150, \ + 30168, 30185, 30202, 30220, 30237, 30254, 30272, 30289, 30306, 30324, 30341, \ + 30358, 30375, 30393, 30410, 30427, 30444, 30461, 30479, 30496, 30513, 30530, \ + 30547, 30565, 30582, 30599, 30616, 30633, 30650, 30667, 30684, 30701, 30719, \ + 30736, 30753, 30770, 30787, 30804, 30821, 30838, 30855, 30872, 30889, 30906, \ + 30923, 30940, 30957, 30973, 30990, 31007, 31024, 31041, 31058, 31075, 31092, \ + 31109, 31125, 31142, 31159, 31176, 31193, 31210, 31226, 31243, 31260, 31277, \ + 31293, 31310, 31327, 31344, 31360, 31377, 31394, 31410, 31427, 31444, 31461, \ + 31477, 31494, 31510, 31527, 31544, 31560, 31577, 31594, 31610, 31627, 31643, \ + 31660, 31676, 31693, 31709, 31726, 31743, 31759, 31776, 31792, 31809, 31825, \ + 31841, 31858, 31874, 31891, 31907, 31924, 31940, 31957, 31973, 31989, 32006, \ + 32022, 32038, 32055, 32071, 32087, 32104, 32120, 32136, 32153, 32169, 32185, \ + 32202, 32218, 32234, 32250, 32267, 32283, 32299, 32315, 32332, 32348, 32364, \ + 32380, 32396, 32413, 32429, 32445, 32461, 32477, 32493, 32509, 32526, 32542, \ + 32558, 32574, 32590, 32606, 32622, 32638, 32654, 32670, 32686, 32702, 32718, \ + 32734, 32750, 32767 \ + } + +#define ATAN1DIV1 (int16_t)8192 +#define ATAN1DIV2 (int16_t)4836 +#define ATAN1DIV4 (int16_t)2555 +#define ATAN1DIV8 (int16_t)1297 +#define ATAN1DIV16 (int16_t)651 +#define ATAN1DIV32 (int16_t)326 +#define ATAN1DIV64 (int16_t)163 +#define ATAN1DIV128 (int16_t)81 +#define ATAN1DIV256 (int16_t)41 +#define ATAN1DIV512 (int16_t)20 +#define ATAN1DIV1024 (int16_t)10 +#define ATAN1DIV2048 (int16_t)5 +#define ATAN1DIV4096 (int16_t)3 +#define ATAN1DIV8192 (int16_t)1 + +/** + * @brief It executes Modulus algorithm + * @param alpha component + * beta component + * @retval int16_t Modulus + */ +static inline int16_t MCM_Modulus(int16_t alpha, int16_t beta) +{ + int32_t wAux1; + int32_t wAux2; + + wAux1 = (int32_t)(alpha * alpha); + wAux2 = (int32_t)(beta * beta); + + wAux1 += wAux2; + wAux1 = MCM_Sqrt(wAux1); + + if (wAux1 > INT16_MAX) + { + wAux1 = (int32_t)INT16_MAX; + } + + return ((int16_t)wAux1); +} + +/** + * @brief It executes CORDIC algorithm for rotor position extraction from B-emf + * alpha and beta + * @param wBemf_alfa_est estimated Bemf alpha on the stator reference frame + * wBemf_beta_est estimated Bemf beta on the stator reference frame + * @retval int16_t rotor electrical angle (s16degrees) + */ +static inline int16_t MCM_PhaseComputation(int32_t wBemf_alfa_est, int32_t wBemf_beta_est) +{ + int16_t hAngle; + int32_t wXi, wYi, wXold; + + /*Determining quadrant*/ + if (wBemf_alfa_est < 0) + { + if (wBemf_beta_est < 0) + { + /*Quadrant III, add 90 degrees so as to move to quadrant IV*/ + hAngle = 16384; + wXi = -(wBemf_beta_est / 2); + wYi = wBemf_alfa_est / 2; + } + else + { + /*Quadrant II, subtract 90 degrees so as to move to quadrant I*/ + hAngle = -16384; + wXi = wBemf_beta_est / 2; + wYi = -(wBemf_alfa_est / 2); + } + } + else + { + /* Quadrant I or IV*/ + hAngle = 0; + wXi = wBemf_alfa_est / 2; + wYi = wBemf_beta_est / 2; + } + wXold = wXi; + + /*begin the successive approximation process*/ + /*iteration0*/ + if (wYi < 0) + { + /*vector is in Quadrant IV*/ + hAngle += ATAN1DIV1; + wXi = wXi - wYi; + wYi = wXold + wYi; + } + else + { + /*vector is in Quadrant I*/ + hAngle -= ATAN1DIV1; + wXi = wXi + wYi; + wYi = -wXold + wYi; + } + wXold = wXi; + + /*iteration1*/ + if (wYi < 0) + { + /*vector is in Quadrant IV*/ + hAngle += ATAN1DIV2; + wXi = wXi - (wYi / 2); + wYi = (wXold / 2) + wYi; + } + else + { + /*vector is in Quadrant I*/ + hAngle -= ATAN1DIV2; + wXi = wXi + (wYi / 2); + wYi = (-wXold / 2) + wYi; + } + wXold = wXi; + + /*iteration2*/ + if (wYi < 0) + { + /*vector is in Quadrant IV*/ + hAngle += ATAN1DIV4; + wXi = wXi - (wYi / 4); + wYi = (wXold / 4) + wYi; + } + else + { + /*vector is in Quadrant I*/ + hAngle -= ATAN1DIV4; + wXi = wXi + (wYi / 4); + wYi = (-wXold / 4) + wYi; + } + wXold = wXi; + + /*iteration3*/ + if (wYi < 0) + { + /*vector is in Quadrant IV*/ + hAngle += ATAN1DIV8; + wXi = wXi - (wYi / 8); + wYi = (wXold / 8) + wYi; + } + else + { + /*vector is in Quadrant I*/ + hAngle -= ATAN1DIV8; + wXi = wXi + (wYi / 8); + wYi = (-wXold / 8) + wYi; + } + wXold = wXi; + + /*iteration4*/ + if (wYi < 0) + { + /*vector is in Quadrant IV*/ + hAngle += ATAN1DIV16; + wXi = wXi - (wYi / 16); + wYi = (wXold / 16) + wYi; + } + else + { + /*vector is in Quadrant I*/ + hAngle -= ATAN1DIV16; + wXi = wXi + (wYi / 16); + wYi = (-wXold / 16) + wYi; + } + wXold = wXi; + + /*iteration5*/ + if (wYi < 0) + { + /*vector is in Quadrant IV*/ + hAngle += ATAN1DIV32; + wXi = wXi - (wYi / 32); + wYi = (wXold / 32) + wYi; + } + else + { + /*vector is in Quadrant I*/ + hAngle -= ATAN1DIV32; + wXi = wXi + (wYi / 32); + wYi = (-wXold / 32) + wYi; + } + wXold = wXi; + + /*iteration6*/ + if (wYi < 0) + { + /*vector is in Quadrant IV*/ + hAngle += ATAN1DIV64; + wXi = wXi - (wYi / 64); + wYi = (wXold / 64) + wYi; + } + else + { + /*vector is in Quadrant I*/ + hAngle -= ATAN1DIV64; + wXi = wXi + (wYi / 64); + wYi = (-wXold / 64) + wYi; + } + wXold = wXi; + + /*iteration7*/ + if (wYi < 0) + { + /*vector is in Quadrant IV*/ + hAngle += ATAN1DIV128; + wXi = wXi - (wYi / 128); + wYi = (wXold / 128) + wYi; + } + else + { + /*vector is in Quadrant I*/ + hAngle -= ATAN1DIV128; + wXi = wXi + (wYi / 128); + wYi = (-wXold / 128) + wYi; + } + + return (-hAngle); +} + +/** + * @brief This function codify a floting point number into the relative + * 32bit integer. + * @param float Floting point number to be coded. + * @retval uint32_t Coded 32bit integer. + */ +uint32_t MCM_floatToIntBit(float x); + +/** + * @} + */ + +/** + * @} + */ +#endif /* MC_MATH_H*/ +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_parameters.c b/src/firmware/motor/mc_parameters.c new file mode 100644 index 0000000000..2300c366cf --- /dev/null +++ b/src/firmware/motor/mc_parameters.c @@ -0,0 +1,76 @@ + +/** + ****************************************************************************** + * @file mc_parameters.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides definitions of HW parameters specific to the + * configuration of the subsystem. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +// cstat -MISRAC2012-Rule-21.1 +#include "main.h" //cstat !MISRAC2012-Rule-21.1 +// cstat +MISRAC2012-Rule-21.1 +#include "parameters_conversion.h" +#include "r1_ps_pwm_curr_fdbk.h" + +/* USER CODE BEGIN Additional include */ + +/* USER CODE END Additional include */ + +#define FREQ_RATIO 1 /* Dummy value for single drive */ +#define FREQ_RELATION HIGHEST_FREQ /* Dummy value for single drive */ + +/** + * @brief Current sensor parameters Motor 1 - single shunt phase shift + */ +// cstat !MISRAC2012-Rule-8.4 +const R1_Params_t R1_ParamsM1 = { + /* Dual MC parameters --------------------------------------------------------*/ + .FreqRatio = FREQ_RATIO, + .IsHigherFreqTim = FREQ_RELATION, + + /* Current reading A/D Conversions initialization -----------------------------*/ + .ADCx = ADC1, + .IChannel = 5, + .ISamplingTime = LL_ADC_SAMPLINGTIME_7CYCLES_5, + + /* PWM generation parameters --------------------------------------------------*/ + .RepetitionCounter = REP_COUNTER, + .TMin = TMIN, + .TSample = (uint16_t)(TBEFORE), + .TIMx = TIM1, + .DMAx = DMA1, + .DMAChannelX = LL_DMA_CHANNEL_5, + .DMASamplingPtChannelX = LL_DMA_CHANNEL_4, + .DMA_ADC_DR_ChannelX = LL_DMA_CHANNEL_1, + .hTADConv = (uint16_t)((ADC_SAR_CYCLES + ADC_TRIG_CONV_LATENCY_CYCLES) * + (ADV_TIM_CLK_MHz / ADC_CLK_MHz)), + + /* Internal OPAMP common settings --------------------------------------------*/ + +}; + +ScaleParams_t scaleParams_M1 = { + .voltage = NOMINAL_BUS_VOLTAGE_V / (1.73205 * 32767), /* sqrt(3) = 1.73205 */ + .current = CURRENT_CONV_FACTOR_INV, + .frequency = (1.15 * MAX_APPLICATION_SPEED_UNIT * U_RPM) / (32768 * SPEED_UNIT)}; + +/* USER CODE BEGIN Additional parameters */ + +/* USER CODE END Additional parameters */ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_parameters.h b/src/firmware/motor/mc_parameters.h new file mode 100644 index 0000000000..b5aa9e088c --- /dev/null +++ b/src/firmware/motor/mc_parameters.h @@ -0,0 +1,41 @@ + +/** + ****************************************************************************** + * @file mc_parameters.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides declarations of HW parameters specific to the + * configuration of the subsystem. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +#ifndef MC_PARAMETERS_H +#define MC_PARAMETERS_H + +#include "mc_interface.h" +#include "r1_ps_pwm_curr_fdbk.h" + +/* USER CODE BEGIN Additional include */ + +/* USER CODE END Additional include */ + +extern const R1_Params_t R1_ParamsM1; + +extern ScaleParams_t scaleParams_M1; + +/* USER CODE BEGIN Additional extern */ + +/* USER CODE END Additional extern */ + +#endif /* MC_PARAMETERS_H */ +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_tasks.c b/src/firmware/motor/mc_tasks.c new file mode 100644 index 0000000000..68464a30e6 --- /dev/null +++ b/src/firmware/motor/mc_tasks.c @@ -0,0 +1,404 @@ + +/** + ****************************************************************************** + * @file mc_tasks.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file implements tasks definition + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mc_tasks.h" + +// cstat -MISRAC2012-Rule-21.1 +#include "firmware/motor/main.h" +// cstat +MISRAC2012-Rule-21.1 +#include "firmware/motor/mc_app_hooks.h" +#include "firmware/motor/mc_interface.h" +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/digital_output.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/pwm_common.h" +#include "firmware/motor/motorcontrol.h" +#include "firmware/motor/parameters_conversion.h" +#include "firmware/motor/regular_conversion_manager.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private define */ +/* Private define ------------------------------------------------------------*/ +/* Un-Comment this macro define in order to activate the smooth + braking action on over voltage */ +/* #define MC.SMOOTH_BRAKING_ACTION_ON_OVERVOLTAGE */ + +/* USER CODE END Private define */ + +#define VBUS_TEMP_ERR_MASK ~(MC_OVER_VOLT | MC_UNDER_VOLT | MC_OVER_TEMP) +/* Private variables----------------------------------------------------------*/ + +static uint16_t hMFTaskCounterM1 = 0; // cstat !MISRAC2012-Rule-8.9_a +static volatile uint16_t hBootCapDelayCounterM1 = ((uint16_t)0); +static volatile uint16_t hStopPermanencyCounterM1 = ((uint16_t)0); +static volatile uint8_t bMCBootCompleted = ((uint8_t)0); + +#define M1_CHARGE_BOOT_CAP_TICKS (((uint16_t)SYS_TICK_FREQUENCY * (uint16_t)10) / 1000U) +#define M1_CHARGE_BOOT_CAP_DUTY_CYCLES \ + ((uint32_t)0.000 * ((uint32_t)PWM_PERIOD_CYCLES / 2U)) +#define M2_CHARGE_BOOT_CAP_TICKS (((uint16_t)SYS_TICK_FREQUENCY * (uint16_t)10) / 1000U) +#define M2_CHARGE_BOOT_CAP_DUTY_CYCLES ((uint32_t)0 * ((uint32_t)PWM_PERIOD_CYCLES2 / 2U)) + +/* USER CODE BEGIN Private Variables */ + +/* USER CODE END Private Variables */ + +/* Private functions ---------------------------------------------------------*/ +void TSK_MediumFrequencyTaskM1(void); +void TSK_MF_StopProcessing(uint8_t motor); +MCI_Handle_t* GetMCI(uint8_t bMotor); +void TSK_SetChargeBootCapDelayM1(uint16_t hTickCount); +bool TSK_ChargeBootCapDelayHasElapsedM1(void); +void TSK_SetStopPermanencyTimeM1(uint16_t hTickCount); +bool TSK_StopPermanencyTimeHasElapsedM1(void); +void TSK_SafetyTask_PWMOFF(uint8_t motor); + +/* USER CODE BEGIN Private Functions */ + +/* USER CODE END Private Functions */ +/** + * @brief It initializes the whole MC core according to user defined + * parameters. + * @param pMCIList pointer to the vector of MCInterface objects that will be + * created and initialized. The vector must have length equal to the + * number of motor drives. + */ +__weak void MCboot(MCI_Handle_t* pMCIList[NBR_OF_MOTORS]) +{ + /* USER CODE BEGIN MCboot 0 */ + + /* USER CODE END MCboot 0 */ + + if (MC_NULL == pMCIList) + { + /* Nothing to do */ + } + else + { + bMCBootCompleted = (uint8_t)0; + + /*************************************************/ + /* FOC initialization */ + /*************************************************/ + pMCIList[M1] = &Mci[M1]; + FOC_Init(); + + /* USER CODE BEGIN MCboot 1 */ + + /* USER CODE END MCboot 1 */ + + /******************************************************/ + /* PID component initialization: speed regulation */ + /******************************************************/ + PID_HandleInit(&PIDSpeedHandle_M1); + + /**********************************************************/ + /* Virtual bus voltage sensor component initialization */ + /**********************************************************/ + VVBS_Init(&BusVoltageSensor_M1); + + /*******************************************************/ + /* Temperature measurement component initialization */ + /*******************************************************/ + NTC_Init(&TempSensor_M1); + + /* Applicative hook in MCBoot() */ + MC_APP_BootHook(); + + /* USER CODE BEGIN MCboot 2 */ + + /* USER CODE END MCboot 2 */ + + bMCBootCompleted = 1U; + } +} + +/** + * @brief Runs all the Tasks of the Motor Control cockpit + * + * This function is to be called periodically at least at the Medium Frequency task + * rate (It is typically called on the Systick interrupt). Exact invokation rate is + * the Speed regulator execution rate set in the Motor Contorl Workbench. + * + * The following tasks are executed in this order: + * + * - Medium Frequency Tasks of each motors. + * - Safety Task. + * - Power Factor Correction Task (if enabled). + * - User Interface task. + */ +__weak void MC_RunMotorControlTasks(void) +{ + if (0U == bMCBootCompleted) + { + /* Nothing to do */ + } + else + { + /* ** Medium Frequency Tasks ** */ + /* USER CODE BEGIN MC_Scheduler 0 */ + + /* USER CODE END MC_Scheduler 0 */ + + if (hMFTaskCounterM1 > 0u) + { + hMFTaskCounterM1--; + } + else + { + TSK_MediumFrequencyTaskM1(); + + /* Applicative hook at end of Medium Frequency for Motor 1 */ + MC_APP_PostMediumFrequencyHook_M1(); + + /* USER CODE BEGIN MC_Scheduler 1 */ + + /* USER CODE END MC_Scheduler 1 */ + + hMFTaskCounterM1 = (uint16_t)MF_TASK_OCCURENCE_TICKS; + } + if (hBootCapDelayCounterM1 > 0U) + { + hBootCapDelayCounterM1--; + } + else + { + /* Nothing to do */ + } + if (hStopPermanencyCounterM1 > 0U) + { + hStopPermanencyCounterM1--; + } + else + { + /* Nothing to do */ + } + + /* USER CODE BEGIN MC_Scheduler 2 */ + + /* USER CODE END MC_Scheduler 2 */ + + /* Safety task is run after Medium Frequency task so that + * it can overcome actions they initiated if needed */ + TSK_SafetyTask(); + } +} + +/** + * @brief It set a counter intended to be used for counting the delay required + * for drivers boot capacitors charging of motor 1. + * @param hTickCount number of ticks to be counted. + * @retval void + */ +__weak void TSK_SetChargeBootCapDelayM1(uint16_t hTickCount) +{ + hBootCapDelayCounterM1 = hTickCount; +} + +/** + * @brief Use this function to know whether the time required to charge boot + * capacitors of motor 1 has elapsed. + * @param none + * @retval bool true if time has elapsed, false otherwise. + */ +__weak bool TSK_ChargeBootCapDelayHasElapsedM1(void) +{ + bool retVal = false; + if (((uint16_t)0) == hBootCapDelayCounterM1) + { + retVal = true; + } + return (retVal); +} + +/** + * @brief It set a counter intended to be used for counting the permanency + * time in STOP state of motor 1. + * @param hTickCount number of ticks to be counted. + * @retval void + */ +__weak void TSK_SetStopPermanencyTimeM1(uint16_t hTickCount) +{ + hStopPermanencyCounterM1 = hTickCount; +} + +/** + * @brief Use this function to know whether the permanency time in STOP state + * of motor 1 has elapsed. + * @param none + * @retval bool true if time is elapsed, false otherwise. + */ +__weak bool TSK_StopPermanencyTimeHasElapsedM1(void) +{ + bool retVal = false; + if (((uint16_t)0) == hStopPermanencyCounterM1) + { + retVal = true; + } + return (retVal); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section (".ccmram"))) +#endif +#endif + +/** + * @brief Executes the Motor Control duties that require a high frequency rate and a + * precise timing. + * + * This is mainly the FOC current control loop. It is executed depending on the state of + * the Motor Control subsystem (see the state machine(s)). + * + * @retval Number of the motor instance which FOC loop was executed. + */ +__weak uint8_t TSK_HighFrequencyTask(void) +{ + uint8_t bMotorNbr; + bMotorNbr = 0; + + /* USER CODE BEGIN HighFrequencyTask 0 */ + + /* USER CODE END HighFrequencyTask 0 */ + FOC_HighFrequencyTask(bMotorNbr); + + /* USER CODE BEGIN HighFrequencyTask 1 */ + + /* USER CODE END HighFrequencyTask 1 */ + + return (bMotorNbr); +} + +/** + * @brief Executes safety checks (e.g. bus voltage and temperature) for all drive + * instances. + * + * Faults flags are updated here. + */ +__weak void TSK_SafetyTask(void) +{ + /* USER CODE BEGIN TSK_SafetyTask 0 */ + + /* USER CODE END TSK_SafetyTask 0 */ + if (1U == bMCBootCompleted) + { + TSK_SafetyTask_PWMOFF(M1); + /* User conversion execution */ + RCM_ExecUserConv(); + /* USER CODE BEGIN TSK_SafetyTask 1 */ + + /* USER CODE END TSK_SafetyTask 1 */ + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief Safety task implementation if MC.M1_ON_OVER_VOLTAGE == TURN_OFF_PWM. + * @param bMotor Motor reference number defined + * \link Motors_reference_number here \endlink. + */ +__weak void TSK_SafetyTask_PWMOFF(uint8_t bMotor) +{ + /* USER CODE BEGIN TSK_SafetyTask_PWMOFF 0 */ + + /* USER CODE END TSK_SafetyTask_PWMOFF 0 */ + uint16_t CodeReturn = MC_NO_ERROR; + uint8_t lbmotor = M1; + /* Check for fault if FW protection is activated. It returns MC_OVER_TEMP or + * MC_NO_ERROR */ + + /* Due to warning array subscript 1 is above array bounds of PWMC_Handle_t *[1] + * [-Warray-bounds] */ + CodeReturn |= PWMC_IsFaultOccurred( + pwmcHandle[lbmotor]); /* check for fault. It return MC_OVER_CURR or MC_NO_FAULTS + (for STM32F30x can return MC_OVER_VOLT in case of HW Overvoltage) */ + + MCI_FaultProcessing(&Mci[bMotor], CodeReturn, ~CodeReturn); /* Process faults */ + + if (MCI_GetFaultState(&Mci[bMotor]) != (uint32_t)MC_NO_FAULTS) + { + PWMC_SwitchOffPWM(pwmcHandle[bMotor]); + FOC_Clear(bMotor); + /* USER CODE BEGIN TSK_SafetyTask_PWMOFF 1 */ + + /* USER CODE END TSK_SafetyTask_PWMOFF 1 */ + } + else + { + /* No errors */ + } + /* USER CODE BEGIN TSK_SafetyTask_PWMOFF 3 */ + + /* USER CODE END TSK_SafetyTask_PWMOFF 3 */ +} + +/** + * @brief Puts the Motor Control subsystem in in safety conditions on a Hard Fault + * + * This function is to be executed when a general hardware failure has been detected + * by the microcontroller and is used to put the system in safety condition. + */ +__weak void TSK_HardwareFaultTask(void) +{ + /* USER CODE BEGIN TSK_HardwareFaultTask 0 */ + + /* USER CODE END TSK_HardwareFaultTask 0 */ + FOC_Clear(M1); + MCI_FaultProcessing(&Mci[M1], MC_SW_ERROR, 0); + + /* USER CODE BEGIN TSK_HardwareFaultTask 1 */ + + /* USER CODE END TSK_HardwareFaultTask 1 */ +} + +/** + * @brief Locks GPIO pins used for Motor Control to prevent accidental reconfiguration. + */ +__weak void mc_lock_pins(void) +{ + LL_GPIO_LockPin(M1_CURR_AMPL_GPIO_Port, M1_CURR_AMPL_Pin); + LL_GPIO_LockPin(M1_HALL_H2_GPIO_Port, M1_HALL_H2_Pin); + LL_GPIO_LockPin(M1_HALL_H3_GPIO_Port, M1_HALL_H3_Pin); + LL_GPIO_LockPin(M1_HALL_H1_GPIO_Port, M1_HALL_H1_Pin); + LL_GPIO_LockPin(M1_PWM_UH_GPIO_Port, M1_PWM_UH_Pin); + LL_GPIO_LockPin(M1_PWM_VH_GPIO_Port, M1_PWM_VH_Pin); + LL_GPIO_LockPin(M1_OCP_GPIO_Port, M1_OCP_Pin); + LL_GPIO_LockPin(M1_PWM_VL_GPIO_Port, M1_PWM_VL_Pin); + LL_GPIO_LockPin(M1_PWM_WH_GPIO_Port, M1_PWM_WH_Pin); + LL_GPIO_LockPin(M1_PWM_WL_GPIO_Port, M1_PWM_WL_Pin); + LL_GPIO_LockPin(M1_PWM_UL_GPIO_Port, M1_PWM_UL_Pin); + LL_GPIO_LockPin(M1_EN_DRIVER_GPIO_Port, M1_EN_DRIVER_Pin); +} +/* USER CODE BEGIN mc_task 0 */ + +/* USER CODE END mc_task 0 */ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_tasks.h b/src/firmware/motor/mc_tasks.h new file mode 100644 index 0000000000..535d8dde72 --- /dev/null +++ b/src/firmware/motor/mc_tasks.h @@ -0,0 +1,127 @@ + +/** + ****************************************************************************** + * @file mc_tasks.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file implementes tasks definition. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCTasks + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MCTASKS_H +#define MCTASKS_H + +/* Includes ------------------------------------------------------------------*/ +#include "mc_parameters.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + /** @addtogroup MCSDK + * @{ + */ + + /** @defgroup MCTasks Motor Control Tasks + * + * @brief Motor Control subsystem configuration and operation routines. + * + * @{ + */ + +#define STOPPERMANENCY_MS ((uint16_t)400) +#define STOPPERMANENCY_MS2 ((uint16_t)400) +#define STOPPERMANENCY_TICKS \ + (uint16_t)((SYS_TICK_FREQUENCY * STOPPERMANENCY_MS) / ((uint16_t)1000)) +#define STOPPERMANENCY_TICKS2 \ + (uint16_t)((SYS_TICK_FREQUENCY * STOPPERMANENCY_MS2) / ((uint16_t)1000)) + + /* Initializes the Motor subsystem core according to user defined parameters */ + void MCboot(MCI_Handle_t *pMCIList[NBR_OF_MOTORS]); + + /* Runs all the Tasks of the Motor Control cockpit */ + void MC_RunMotorControlTasks(void); + + /* Executes the Medium Frequency Task functions for each drive instance */ + void MC_Scheduler(void); + + /* Executes safety checks (e.g. bus voltage and temperature) for all drive instances + */ + void TSK_SafetyTask(void); + + /* */ + void FOC_Init(void); + + /* */ + uint8_t FOC_HighFrequencyTask(uint8_t bMotorNbr); + + /* */ + void FOC_Clear(uint8_t bMotor); + + /* Executes the Motor Control duties that require a high frequency rate and a precise + * timing */ + uint8_t TSK_HighFrequencyTask(void); + + /* */ + void TSK_SetChargeBootCapDelayM1(uint16_t hTickCount); + + /* */ + bool TSK_ChargeBootCapDelayHasElapsedM1(void); + + /* */ + void TSK_SetStopPermanencyTimeM1(uint16_t hTickCount); + + /* */ + bool TSK_StopPermanencyTimeHasElapsedM1(void); + + /* */ + void TSK_SetStopPermanencyTimeM2(uint16_t SysTickCount); + + /* */ + void TSK_SetChargeBootCapDelayM2(uint16_t hTickCount); + + /* */ + void TSK_SetChargeBootCapDelayM2(uint16_t hTickCount); + + /* */ + bool TSK_StopPermanencyTimeHasElapsedM2(void); + + /* */ + bool TSK_ChargeBootCapDelayHasElapsedM2(void); + + /* Reserves FOC execution on ADC ISR half a PWM period in advance */ + void TSK_DualDriveFIFOUpdate(uint8_t Motor); + + /* Puts the Motor Control subsystem in in safety conditions on a Hard Fault */ + void TSK_HardwareFaultTask(void); + + /* Locks GPIO pins used for Motor Control to prevent accidental reconfiguration */ + void mc_lock_pins(void); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* MCTASKS_H */ +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mc_tasks_foc.c b/src/firmware/motor/mc_tasks_foc.c new file mode 100644 index 0000000000..e679308649 --- /dev/null +++ b/src/firmware/motor/mc_tasks_foc.c @@ -0,0 +1,625 @@ + +/** + ****************************************************************************** + * @file mc_tasks_foc.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file implements tasks definition + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +#include "firmware/motor/mc_tasks.h" + +/* Includes ------------------------------------------------------------------*/ +// cstat -MISRAC2012-Rule-21.1 +#include "firmware/motor/main.h" +// cstat +MISRAC2012-Rule-21.1 +#include "firmware/motor/mc_app_hooks.h" +#include "firmware/motor/mc_interface.h" +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/digital_output.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/pwm_common.h" +#include "firmware/motor/motorcontrol.h" +#include "firmware/motor/parameters_conversion.h" +#include "firmware/motor/regular_conversion_manager.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private define */ +/* Private define ------------------------------------------------------------*/ + +/* USER CODE END Private define */ + +/* Private variables----------------------------------------------------------*/ +OpenLoop_Handle_t *pOpenLoop[1] = {MC_NULL}; /* Only if M1 has OPEN LOOP */ + +static volatile uint16_t hBootCapDelayCounterM1 = ((uint16_t)0); +static volatile uint16_t hStopPermanencyCounterM1 = ((uint16_t)0); + +#define M1_CHARGE_BOOT_CAP_TICKS (((uint16_t)SYS_TICK_FREQUENCY * (uint16_t)10) / 1000U) +#define M1_CHARGE_BOOT_CAP_DUTY_CYCLES \ + ((uint32_t)0.000 * ((uint32_t)PWM_PERIOD_CYCLES / 2U)) +#define M2_CHARGE_BOOT_CAP_TICKS (((uint16_t)SYS_TICK_FREQUENCY * (uint16_t)10) / 1000U) +#define M2_CHARGE_BOOT_CAP_DUTY_CYCLES ((uint32_t)0 * ((uint32_t)PWM_PERIOD_CYCLES2 / 2U)) + +/* USER CODE BEGIN Private Variables */ + +/* USER CODE END Private Variables */ + +/* Private functions ---------------------------------------------------------*/ +void TSK_MediumFrequencyTaskM1(void); +void FOC_InitAdditionalMethods(uint8_t bMotor); +void FOC_CalcCurrRef(uint8_t bMotor); +void TSK_MF_StopProcessing(uint8_t motor); + +MCI_Handle_t *GetMCI(uint8_t bMotor); +static uint16_t FOC_CurrControllerM1(void); + +void TSK_SafetyTask_PWMOFF(uint8_t motor); + +/* USER CODE BEGIN Private Functions */ + +/* USER CODE END Private Functions */ +/** + * @brief It initializes the whole MC core according to user defined + * parameters. + */ +__weak void FOC_Init(void) +{ + /* USER CODE BEGIN MCboot 0 */ + + /* USER CODE END MCboot 0 */ + + /**********************************************************/ + /* PWM and current sensing component initialization */ + /**********************************************************/ + pwmcHandle[M1] = &PWM_Handle_M1._Super; + R1_Init(&PWM_Handle_M1); + + /* USER CODE BEGIN MCboot 1 */ + + /* USER CODE END MCboot 1 */ + + /******************************************************/ + /* PID component initialization: speed regulation */ + /******************************************************/ + PID_HandleInit(&PIDSpeedHandle_M1); + + /******************************************************/ + /* Main speed sensor component initialization */ + /******************************************************/ + HALL_Init(&HALL_M1); + + /******************************************************/ + /* Speed & torque component initialization */ + /******************************************************/ + STC_Init(pSTC[M1], &PIDSpeedHandle_M1, &HALL_M1._Super); + + /********************************************************/ + /* PID component initialization: current regulation */ + /********************************************************/ + PID_HandleInit(&PIDIqHandle_M1); + PID_HandleInit(&PIDIdHandle_M1); + + /*************************************************/ + /* Power measurement component initialization */ + /*************************************************/ + pMPM[M1]->pVBS = &(BusVoltageSensor_M1._Super); + pMPM[M1]->pFOCVars = &FOCVars[M1]; + + OL_Init(&OpenLoop_ParamsM1, &VirtualSpeedSensorM1); /* Only if M1 has open loop */ + pOpenLoop[M1] = &OpenLoop_ParamsM1; + + pREMNG[M1] = &RampExtMngrHFParamsM1; + REMNG_Init(pREMNG[M1]); + + FOC_Clear(M1); + FOCVars[M1].bDriveInput = EXTERNAL; + FOCVars[M1].Iqdref = STC_GetDefaultIqdref(pSTC[M1]); + FOCVars[M1].UserIdref = STC_GetDefaultIqdref(pSTC[M1]).d; + MCI_SetSpeedMode(&Mci[M1]); + + MCI_ExecSpeedRamp(&Mci[M1], STC_GetMecSpeedRefUnitDefault(pSTC[M1]), + 0); /* First command to STC */ + + /* USER CODE BEGIN MCboot 2 */ + + /* USER CODE END MCboot 2 */ +} + +/** + * @brief Performs stop process and update the state machine.This function + * shall be called only during medium frequency task. + */ +void TSK_MF_StopProcessing(uint8_t motor) +{ + R1_SwitchOffPWM(pwmcHandle[motor]); + + FOC_Clear(motor); + + TSK_SetStopPermanencyTimeM1(STOPPERMANENCY_TICKS); + Mci[motor].State = STOP; +} + +/** + * @brief Executes medium frequency periodic Motor Control tasks + * + * This function performs some of the control duties on Motor 1 according to the + * present state of its state machine. In particular, duties requiring a periodic + * execution at a medium frequency rate (such as the speed controller for instance) + * are executed here. + */ +__weak void TSK_MediumFrequencyTaskM1(void) +{ + /* USER CODE BEGIN MediumFrequencyTask M1 0 */ + + /* USER CODE END MediumFrequencyTask M1 0 */ + + int16_t wAux = 0; + MC_ControlMode_t mode; + + mode = MCI_GetControlMode(&Mci[M1]); + bool IsSpeedReliable = HALL_CalcAvrgMecSpeedUnit(&HALL_M1, &wAux); + PQD_CalcElMotorPower(pMPM[M1]); + + if (MCI_GetCurrentFaults(&Mci[M1]) == MC_NO_FAULTS) + { + if (MCI_GetOccurredFaults(&Mci[M1]) == MC_NO_FAULTS) + { + switch (Mci[M1].State) + { + case IDLE: + { + if ((MCI_START == Mci[M1].DirectCommand) || + (MCI_MEASURE_OFFSETS == Mci[M1].DirectCommand)) + { + if (pwmcHandle[M1]->offsetCalibStatus == false) + { + (void)PWMC_CurrentReadingCalibr(pwmcHandle[M1], CRC_START); + Mci[M1].State = OFFSET_CALIB; + } + else + { + /* Calibration already done. Enables only TIM channels */ + pwmcHandle[M1]->OffCalibrWaitTimeCounter = 1u; + (void)PWMC_CurrentReadingCalibr(pwmcHandle[M1], CRC_EXEC); + R1_TurnOnLowSides(pwmcHandle[M1], + M1_CHARGE_BOOT_CAP_DUTY_CYCLES); + TSK_SetChargeBootCapDelayM1(M1_CHARGE_BOOT_CAP_TICKS); + Mci[M1].State = CHARGE_BOOT_CAP; + } + } + else + { + /* Nothing to be done, FW stays in IDLE state */ + } + break; + } + + case OFFSET_CALIB: + { + if (MCI_STOP == Mci[M1].DirectCommand) + { + TSK_MF_StopProcessing(M1); + } + else + { + if (PWMC_CurrentReadingCalibr(pwmcHandle[M1], CRC_EXEC)) + { + if (MCI_MEASURE_OFFSETS == Mci[M1].DirectCommand) + { + FOC_Clear(M1); + Mci[M1].DirectCommand = MCI_NO_COMMAND; + Mci[M1].State = IDLE; + } + else + { + R1_TurnOnLowSides(pwmcHandle[M1], + M1_CHARGE_BOOT_CAP_DUTY_CYCLES); + TSK_SetChargeBootCapDelayM1(M1_CHARGE_BOOT_CAP_TICKS); + Mci[M1].State = CHARGE_BOOT_CAP; + } + } + else + { + /* Nothing to be done, FW waits for offset calibration to + * finish */ + } + } + break; + } + + case CHARGE_BOOT_CAP: + { + if (MCI_STOP == Mci[M1].DirectCommand) + { + TSK_MF_StopProcessing(M1); + } + else + { + if (TSK_ChargeBootCapDelayHasElapsedM1()) + { + R1_SwitchOffPWM(pwmcHandle[M1]); + + HALL_Clear(&HALL_M1); + + FOC_Clear(M1); + + if (mode == MCM_OPEN_LOOP_VOLTAGE_MODE || + mode == MCM_OPEN_LOOP_CURRENT_MODE) + { /* In open loop mode, angle comes from virtual sensor */ + STC_SetSpeedSensor(pSTC[M1], + &VirtualSpeedSensorM1._Super); + } + else + { + STC_SetSpeedSensor(pSTC[M1], &HALL_M1._Super); + + FOC_InitAdditionalMethods(M1); + FOC_CalcCurrRef(M1); + STC_ForceSpeedReferenceToCurrentSpeed( + pSTC[M1]); /* Init the reference speed to current + speed */ + } + MCI_ExecBufferedCommands( + &Mci[M1]); /* Exec the speed ramp after changing of the + speed sensor */ + Mci[M1].State = RUN; + PWMC_SwitchOnPWM(pwmcHandle[M1]); + } + else + { + /* Nothing to be done, FW waits for bootstrap capacitor to + * charge */ + } + } + break; + } + + case RUN: + { + if (MCI_STOP == Mci[M1].DirectCommand) + { + TSK_MF_StopProcessing(M1); + } + else + { + /* USER CODE BEGIN MediumFrequencyTask M1 2 */ + + /* USER CODE END MediumFrequencyTask M1 2 */ + + MCI_ExecBufferedCommands(&Mci[M1]); + if (mode != MCM_OPEN_LOOP_VOLTAGE_MODE && + mode != MCM_OPEN_LOOP_CURRENT_MODE) + { + FOC_CalcCurrRef(M1); + if (!IsSpeedReliable) + { + MCI_FaultProcessing(&Mci[M1], MC_SPEED_FDBK, 0); + } + else + { + /* Nothing to do */ + } + } + else + { + int16_t hForcedMecSpeedUnit; + /* Open Loop */ + VSS_CalcAvrgMecSpeedUnit(&VirtualSpeedSensorM1, + &hForcedMecSpeedUnit); + OL_Calc(pOpenLoop[M1]); + } + } + break; + } + + case STOP: + { + if (TSK_StopPermanencyTimeHasElapsedM1()) + { + /* USER CODE BEGIN MediumFrequencyTask M1 5 */ + + /* USER CODE END MediumFrequencyTask M1 5 */ + Mci[M1].DirectCommand = MCI_NO_COMMAND; + Mci[M1].State = IDLE; + } + else + { + /* Nothing to do, FW waits for to stop */ + } + break; + } + + case FAULT_OVER: + { + if (MCI_ACK_FAULTS == Mci[M1].DirectCommand) + { + Mci[M1].DirectCommand = MCI_NO_COMMAND; + Mci[M1].State = IDLE; + } + else + { + /* Nothing to do, FW stays in FAULT_OVER state until + * acknowledgement */ + } + break; + } + + case FAULT_NOW: + { + Mci[M1].State = FAULT_OVER; + break; + } + + default: + break; + } + } + else + { + Mci[M1].State = FAULT_OVER; + } + } + else + { + Mci[M1].State = FAULT_NOW; + } + /* USER CODE BEGIN MediumFrequencyTask M1 6 */ + + /* USER CODE END MediumFrequencyTask M1 6 */ +} + +/** + * @brief It re-initializes the current and voltage variables. Moreover + * it clears qd currents PI controllers, voltage sensor and SpeednTorque + * controller. It must be called before each motor restart. + * It does not clear speed sensor. + * @param bMotor related motor it can be M1 or M2. + */ +__weak void FOC_Clear(uint8_t bMotor) +{ + /* USER CODE BEGIN FOC_Clear 0 */ + + /* USER CODE END FOC_Clear 0 */ + MC_ControlMode_t mode; + + mode = MCI_GetControlMode(&Mci[bMotor]); + + ab_t NULL_ab = {((int16_t)0), ((int16_t)0)}; + qd_t NULL_qd = {((int16_t)0), ((int16_t)0)}; + alphabeta_t NULL_alphabeta = {((int16_t)0), ((int16_t)0)}; + + FOCVars[bMotor].Iab = NULL_ab; + FOCVars[bMotor].Ialphabeta = NULL_alphabeta; + FOCVars[bMotor].Iqd = NULL_qd; + if (mode != MCM_OPEN_LOOP_VOLTAGE_MODE && mode != MCM_OPEN_LOOP_CURRENT_MODE) + { + FOCVars[bMotor].Iqdref = NULL_qd; + } + else + { + /* Nothing to do */ + } + FOCVars[bMotor].hTeref = (int16_t)0; + FOCVars[bMotor].Vqd = NULL_qd; + FOCVars[bMotor].Valphabeta = NULL_alphabeta; + FOCVars[bMotor].hElAngle = (int16_t)0; + + PID_SetIntegralTerm(pPIDIq[bMotor], ((int32_t)0)); + PID_SetIntegralTerm(pPIDId[bMotor], ((int32_t)0)); + + STC_Clear(pSTC[bMotor]); + + PWMC_SwitchOffPWM(pwmcHandle[bMotor]); + + /* USER CODE BEGIN FOC_Clear 1 */ + + /* USER CODE END FOC_Clear 1 */ +} + +/** + * @brief Use this method to initialize additional methods (if any) in + * START_TO_RUN state. + * @param bMotor related motor it can be M1 or M2. + */ +__weak void FOC_InitAdditionalMethods(uint8_t bMotor) // cstat !RED-func-no-effect +{ + if (M_NONE == bMotor) + { + /* Nothing to do */ + } + else + { + /* USER CODE BEGIN FOC_InitAdditionalMethods 0 */ + + /* USER CODE END FOC_InitAdditionalMethods 0 */ + } +} + +/** + * @brief It computes the new values of Iqdref (current references on qd + * reference frame) based on the required electrical torque information + * provided by oTSC object (internally clocked). + * If implemented in the derived class it executes flux weakening and/or + * MTPA algorithm(s). It must be called with the periodicity specified + * in oTSC parameters. + * @param bMotor related motor it can be M1 or M2. + */ +__weak void FOC_CalcCurrRef(uint8_t bMotor) +{ + qd_t IqdTmp; + + /* Enter critical section */ + /* Disable interrupts to avoid any interruption during Iqd reference latching */ + /* to avoid MF task writing them while HF task reading them */ + __disable_irq(); + IqdTmp = FOCVars[bMotor].Iqdref; + + /* Exit critical section */ + __enable_irq(); + + /* USER CODE BEGIN FOC_CalcCurrRef 0 */ + + /* USER CODE END FOC_CalcCurrRef 0 */ + MC_ControlMode_t mode; + + mode = MCI_GetControlMode(&Mci[bMotor]); + if (INTERNAL == FOCVars[bMotor].bDriveInput && + (mode != MCM_OPEN_LOOP_VOLTAGE_MODE && mode != MCM_OPEN_LOOP_CURRENT_MODE)) + { + FOCVars[bMotor].hTeref = STC_CalcTorqueReference(pSTC[bMotor]); + IqdTmp.q = FOCVars[bMotor].hTeref; + } + else + { + /* Nothing to do */ + } + + /* Enter critical section */ + /* Disable interrupts to avoid any interruption during Iqd reference restoring */ + __disable_irq(); + FOCVars[bMotor].Iqdref = IqdTmp; + + /* Exit critical section */ + __enable_irq(); + /* USER CODE BEGIN FOC_CalcCurrRef 1 */ + + /* USER CODE END FOC_CalcCurrRef 1 */ +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section (".ccmram"))) +#endif +#endif + +/** + * @brief Executes the Motor Control duties that require a high frequency rate and a + * precise timing. + * + * This is mainly the FOC current control loop. It is executed depending on the state of + * the Motor Control subsystem (see the state machine(s)). + * + * @retval Number of the motor instance which FOC loop was executed. + */ +__weak uint8_t FOC_HighFrequencyTask(uint8_t bMotorNbr) +{ + uint16_t hFOCreturn; + /* USER CODE BEGIN HighFrequencyTask 0 */ + + /* USER CODE END HighFrequencyTask 0 */ + + (void)HALL_CalcElAngle(&HALL_M1); + + /* USER CODE BEGIN HighFrequencyTask SINGLEDRIVE_1 */ + + /* USER CODE END HighFrequencyTask SINGLEDRIVE_1 */ + hFOCreturn = FOC_CurrControllerM1(); + /* USER CODE BEGIN HighFrequencyTask SINGLEDRIVE_2 */ + + /* USER CODE END HighFrequencyTask SINGLEDRIVE_2 */ + if (hFOCreturn == MC_DURATION) + { + MCI_FaultProcessing(&Mci[M1], MC_DURATION, 0); + } + else + { + if (RUN == Mci[M1].State) + { + int16_t hObsAngle = SPD_GetElAngle(&HALL_M1._Super); + (void)VSS_CalcElAngle(&VirtualSpeedSensorM1, &hObsAngle); + } + else + { + /* Nothing to do */ + } + /* USER CODE BEGIN HighFrequencyTask SINGLEDRIVE_3 */ + + /* USER CODE END HighFrequencyTask SINGLEDRIVE_3 */ + } + + return (bMotorNbr); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section (".ccmram"))) +#endif +#endif +/** + * @brief It executes the core of FOC drive that is the controllers for Iqd + * currents regulation. Reference frame transformations are carried out + * accordingly to the active speed sensor. It must be called periodically + * when new motor currents have been converted + * @param this related object of class CFOC. + * @retval int16_t It returns MC_NO_FAULTS if the FOC has been ended before + * next PWM Update event, MC_DURATION otherwise + */ +inline uint16_t FOC_CurrControllerM1(void) +{ + qd_t Iqd, Vqd; + ab_t Iab; + alphabeta_t Ialphabeta, Valphabeta; + int16_t hElAngle; + uint16_t hCodeError; + SpeednPosFdbk_Handle_t *speedHandle; + MC_ControlMode_t mode; + + mode = MCI_GetControlMode(&Mci[M1]); + speedHandle = STC_GetSpeedSensor(pSTC[M1]); + hElAngle = SPD_GetElAngle(speedHandle); + PWMC_GetPhaseCurrents(pwmcHandle[M1], &Iab); + RCM_ExecNextConv(); + Ialphabeta = MCM_Clarke(Iab); + Iqd = MCM_Park(Ialphabeta, hElAngle); + Vqd.q = PI_Controller(pPIDIq[M1], (int32_t)(FOCVars[M1].Iqdref.q) - Iqd.q); + Vqd.d = PI_Controller(pPIDId[M1], (int32_t)(FOCVars[M1].Iqdref.d) - Iqd.d); + if (mode == MCM_OPEN_LOOP_VOLTAGE_MODE) + { + Vqd = OL_VqdConditioning(pOpenLoop[M1]); + } + else + { + /* Nothing to do */ + } + Vqd = Circle_Limitation(&CircleLimitationM1, Vqd); + hElAngle += SPD_GetInstElSpeedDpp(speedHandle) * REV_PARK_ANGLE_COMPENSATION_FACTOR; + Valphabeta = MCM_Rev_Park(Vqd, hElAngle); + RCM_ReadOngoingConv(); + hCodeError = PWMC_SetPhaseVoltage(pwmcHandle[M1], Valphabeta); + PWMC_CalcPhaseCurrentsEst(pwmcHandle[M1], Iqd, hElAngle); + + FOCVars[M1].Vqd = Vqd; + FOCVars[M1].Iab = Iab; + FOCVars[M1].Ialphabeta = Ialphabeta; + FOCVars[M1].Iqd = Iqd; + FOCVars[M1].Valphabeta = Valphabeta; + FOCVars[M1].hElAngle = hElAngle; + + return (hCodeError); +} + +/* USER CODE BEGIN mc_task 0 */ + +/* USER CODE END mc_task 0 */ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/bemf_speed_pos_fdbk.h b/src/firmware/motor/mcsdk/bemf_speed_pos_fdbk.h new file mode 100644 index 0000000000..e662d1f5dd --- /dev/null +++ b/src/firmware/motor/mcsdk/bemf_speed_pos_fdbk.h @@ -0,0 +1,109 @@ +/** + ****************************************************************************** + * @file bemf_speed_pos_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains definitions and functions prototypes common to all + * six-step sensorless based Speed & Position Feedback components of the Motor + * Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeednPosFdbk_Bemf + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BEMF_SPEEDNPOSFDBK_H +#define __BEMF_SPEEDNPOSFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "speed_pos_fdbk.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednPosFdbk + * @{ + */ + + /** @defgroup SpeednPosFdbk_Bemf Six-Step Back-EMF sensing + * + * @brief Back-EMF sensing components of the Motor Control SDK + * + * These components fulfill two functions in a Motor Control subsystem: + * + * - The sensing of the Back-EMF + * - The detection of the zero-crossing point and the estimation of the rotor position + * + * The ADC should be triggered by the timers used to generate the duty cycles for the + * PWM. + * + * Several implementation of Six-Step Back-EMF sensing components are provided by the + * Motor Control SDK to account for the specificities of the application: + * + * - The selected MCU: the number of ADCs available on a given MCU, the presence of + * injected channels, for instance, lead to different implementation of this feature + * - The presence of comparators for or a resistor networks that allows the sampling + * during the PWM ON period + * + * All these implementations are built on a base Six-Step Back-EMF sensing component + * that they extend and that provides the functions and data that are common to all of + * them. This base component is never used directly as it does not provide a complete + * implementation of the features. + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** @brief Sensorless Bemf Sensing component handle type */ + typedef struct Bemf_Handle Bemf_Handle_t; + + typedef void (*Bemf_ForceConvergency1_Cb_t)(Bemf_Handle_t* pHandle); + typedef void (*Bemf_ForceConvergency2_Cb_t)(Bemf_Handle_t* pHandle); + typedef void (*Bemf_OtfResetPLL_Cb_t)(Bemf_Handle_t* pHandle); + typedef bool (*Bemf_SpeedReliabilityCheck_Cb_t)(const Bemf_Handle_t* pHandle); + + /** + * @brief SpeednPosFdbk handle definition + */ + struct Bemf_Handle + { + SpeednPosFdbk_Handle_t* _Super; + Bemf_ForceConvergency1_Cb_t pFctForceConvergency1; + Bemf_ForceConvergency2_Cb_t pFctForceConvergency2; + Bemf_OtfResetPLL_Cb_t pFctBemfOtfResetPLL; + Bemf_SpeedReliabilityCheck_Cb_t pFctBemf_SpeedReliabilityCheck; + }; + + /** + * @} + */ + + /** + * @} + */ + + /** @} */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /*__BEMF_SPEEDNPOSFDBK_H*/ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/bus_voltage_sensor.c b/src/firmware/motor/mcsdk/bus_voltage_sensor.c new file mode 100644 index 0000000000..5e2190fb18 --- /dev/null +++ b/src/firmware/motor/mcsdk/bus_voltage_sensor.c @@ -0,0 +1,170 @@ +/** + ****************************************************************************** + * @file bus_voltage_sensor.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the BusVoltageSensor component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup BusVoltageSensor + */ + +/* Includes ------------------------------------------------------------------*/ + +#include "firmware/motor/mcsdk/bus_voltage_sensor.h" + +#include "firmware/motor/common_defs.h" + + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup BusVoltageSensor Bus Voltage Sensing + * @brief Bus Voltage Sensor components of the Motor Control SDK + * + * Two Bus Voltage Sensor implementations are provided (selection done according to + * BUS_VOLTAGE_READING definition): + * + * - The @ref RDividerBusVoltageSensor "Resistor Divider Bus Voltage Sensor" operates as + * the name suggests + * - The @ref VirtualBusVoltageSensor "Virtual Bus Voltage Sensor" does not make + * measurement but rather returns an application fixed defined value (expected VBus + * value). + * + * Two formats are used to return VBus measurement: + * - Volt + * - u16Volt that represents the ADC converted signal measuring the voltage at sensing + * network attenuation output + * @f[ + * u16Volt = (ADC\_REFERENCE\_VOLTAGE / VBUS\_PARTITIONING\_FACTOR) / 65536 + * @f] + * + * @{ + */ + +/** + * @brief It return latest Vbus conversion result expressed in u16Volt format + * @param pHandle related Handle of BusVoltageSensor_Handle_t + * @retval uint16_t Latest Vbus conversion result in u16Volt format + */ +__weak uint16_t VBS_GetBusVoltage_d(const BusVoltageSensor_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_BUS_VOLT + uint16_t temp_latestConv; + if (MC_NULL == pHandle) + { + temp_latestConv = 0; + } + else + { + temp_latestConv = pHandle->LatestConv; + } + return (temp_latestConv); +#else + return (pHandle->LatestConv); +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief It return latest averaged Vbus measurement expressed in u16Volt format + * @param pHandle related Handle of BusVoltageSensor_Handle_t + * @retval uint16_t Latest averaged Vbus measurement in u16Volt format + */ +__weak uint16_t VBS_GetAvBusVoltage_d(const BusVoltageSensor_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_BUS_VOLT + uint16_t temp_avBusVoltage_d; + + if (MC_NULL == pHandle) + { + temp_avBusVoltage_d = 0U; + } + else + { + temp_avBusVoltage_d = pHandle->AvBusVoltage_d; + } + return (temp_avBusVoltage_d); +#else + return (pHandle->AvBusVoltage_d); +#endif +} + + +/** + * @brief It return latest averaged Vbus measurement expressed in Volt format + * @param pHandle related Handle of BusVoltageSensor_Handle_t + * @retval uint16_t Latest averaged Vbus measurement in Volt format + */ +__weak uint16_t VBS_GetAvBusVoltage_V(const BusVoltageSensor_Handle_t *pHandle) +{ + uint32_t temp; +#ifdef NULL_PTR_CHECK_BUS_VOLT + if (MC_NULL == pHandle) + { + temp = 0U; + } + else + { +#endif + temp = (uint32_t)(pHandle->AvBusVoltage_d); + temp *= pHandle->ConversionFactor; + temp /= 65536U; +#ifdef NULL_PTR_CHECK_BUS_VOLT + } +#endif + return ((uint16_t)temp); +} + +/** + * @brief It returns MC_OVER_VOLT, MC_UNDER_VOLT or MC_NO_ERROR depending on + * bus voltage and protection threshold values + * @param pHandle related Handle of BusVoltageSensor_Handle_t + * @retval uint16_t Fault code error + */ +__weak uint16_t VBS_CheckVbus(const BusVoltageSensor_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_BUS_VOLT + uint16_t temp_faultState; + + if (MC_NULL == pHandle) + { + temp_faultState = 0U; + } + else + { + temp_faultState = pHandle->FaultState; + } + return (temp_faultState); +#else + return (pHandle->FaultState); +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/bus_voltage_sensor.h b/src/firmware/motor/mcsdk/bus_voltage_sensor.h new file mode 100644 index 0000000000..432f9bc28f --- /dev/null +++ b/src/firmware/motor/mcsdk/bus_voltage_sensor.h @@ -0,0 +1,89 @@ +/** + ****************************************************************************** + * @file bus_voltage_sensor.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * BusVoltageSensor component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup BusVoltageSensor + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BUSVOLTAGESENSOR_H +#define BUSVOLTAGESENSOR_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup BusVoltageSensor + * @{ + */ + + /** + * @brief BusVoltageSensor handle definition + */ + typedef struct + { + SensorType_t SensorType; /*!< It contains the information about the type + of instanced bus voltage sensor object. + It can be equal to REAL_SENSOR or + VIRTUAL_SENSOR */ + uint16_t ConversionFactor; /*!< It is used to convert bus voltage from + u16Volts into real Volts (V). + 1 u16Volt = 65536/ConversionFactor Volts + For real sensors ConversionFactor it is + equal to the product between the expected MCU + voltage and the voltage sensing network + attenuation. For virtual sensors it must + be equal to 500 */ + + uint16_t LatestConv; /*!< It contains latest Vbus converted value + expressed in u16Volt format */ + uint16_t AvBusVoltage_d; /*!< It contains latest available average Vbus + expressed in u16Volt format */ + uint16_t FaultState; /*!< It contains latest Fault code (MC_NO_ERROR, + MC_OVER_VOLT or MC_UNDER_VOLT) */ + } BusVoltageSensor_Handle_t; + + + /* Exported functions ------------------------------------------------------- */ + uint16_t VBS_GetBusVoltage_d(const BusVoltageSensor_Handle_t *pHandle); + uint16_t VBS_GetAvBusVoltage_d(const BusVoltageSensor_Handle_t *pHandle); + uint16_t VBS_GetAvBusVoltage_V(const BusVoltageSensor_Handle_t *pHandle); + uint16_t VBS_CheckVbus(const BusVoltageSensor_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* BUSVOLTAGESENSOR_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/circle_limitation.c b/src/firmware/motor/mcsdk/circle_limitation.c new file mode 100644 index 0000000000..561212426d --- /dev/null +++ b/src/firmware/motor/mcsdk/circle_limitation.c @@ -0,0 +1,149 @@ +/** + ****************************************************************************** + * @file circle_limitation.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides the functions that implement the circle + * limitation feature of the STM32 Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup CircleLimitation + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/circle_limitation.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup CircleLimitation Circle Limitation + * @brief Circle Limitation component of the Motor Control SDK + * + * @{ + */ + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif + +#if defined CIRCLE_LIMITATION_SQRT_M0 +const uint16_t SqrtTable[1025] = SQRT_CIRCLE_LIMITATION; +#endif +/** + * @brief Returns the saturated @f$v_q, v_d@f$ component values + * @param pHandle Handler of the CircleLimitation component + * @param Vqd @f$v_q, v_d@f$ values + * @retval Saturated @f$v_q, v_d@f$ values + * + * This function implements the CircleLimitation feature described CircleLimitation + component. + * + * @f$v_d = \min(v_d^*, v_d MAX) @f$ + * + * @f$v_q = \sqrt(MaxModule^2-v_d^2\ ) @f$ + + * + */ +__weak qd_t Circle_Limitation(const CircleLimitation_Handle_t *pHandle, qd_t Vqd) +{ + qd_t Local_Vqd = Vqd; +#ifdef NULL_PTR_CHECK_CRC_LIM + if (MC_NULL == pHandle) + { + Local_Vqd.q = 0; + Local_Vqd.d = 0; + } + else + { +#endif + int32_t maxModule; + int32_t square_q; + int32_t square_temp; + int32_t square_d; + int32_t square_sum; + int32_t square_limit; + int32_t vd_square_limit; + int32_t new_q; + int32_t new_d; + + maxModule = (int32_t)pHandle->MaxModule; + + square_q = ((int32_t)(Vqd.q)) * Vqd.q; + square_d = ((int32_t)(Vqd.d)) * Vqd.d; + square_limit = maxModule * maxModule; + vd_square_limit = ((int32_t)pHandle->MaxVd) * ((int32_t)pHandle->MaxVd); + square_sum = square_q + square_d; + + if (square_sum > square_limit) + { + if (square_d <= vd_square_limit) + { +#if defined CIRCLE_LIMITATION_SQRT_M0 + square_temp = (square_limit - square_d) / 1048576; + new_q = SqrtTable[square_temp]; +#else + square_temp = square_limit - square_d; + new_q = MCM_Sqrt(square_temp); +#endif + if (Vqd.q < 0) + { + new_q = -new_q; + } + new_d = Vqd.d; + } + else + { + new_d = (int32_t)pHandle->MaxVd; + if (Vqd.d < 0) + { + new_d = -new_d; + } +#if defined CIRCLE_LIMITATION_SQRT_M0 + square_temp = (square_limit - vd_square_limit) / 1048576; + new_q = SqrtTable[square_temp]; +#else + square_temp = square_limit - vd_square_limit; + new_q = MCM_Sqrt(square_temp); +#endif + if (Vqd.q < 0) + { + new_q = -new_q; + } + } + Local_Vqd.q = (int16_t)new_q; + Local_Vqd.d = (int16_t)new_d; + } +#ifdef NULL_PTR_CHECK_CRC_LIM + } +#endif + return (Local_Vqd); +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/circle_limitation.h b/src/firmware/motor/mcsdk/circle_limitation.h new file mode 100644 index 0000000000..06edc74d8d --- /dev/null +++ b/src/firmware/motor/mcsdk/circle_limitation.h @@ -0,0 +1,75 @@ +/** + ****************************************************************************** + * @file circle_limitation.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Circle Limitation component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup CircleLimitation + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef CIRCLELIMITATION_H +#define CIRCLELIMITATION_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup CircleLimitation + * @{ + */ + + /** + * @brief CircleLimitation component parameters definition + */ + typedef struct + { + uint16_t MaxModule; /**< Circle limitation maximum allowed + module */ + uint16_t MaxVd; /**< Circle limitation maximum allowed + module */ + uint16_t Circle_limit_table[87]; /**< Circle limitation table */ + uint8_t Start_index; /**< Circle limitation table indexing + start */ + } CircleLimitation_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /* Returns the saturated @f$v_q, v_d@f$ component values */ + qd_t Circle_Limitation(const CircleLimitation_Handle_t *pHandle, qd_t Vqd); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* CIRCLELIMITATION_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/current_ref_ctrl.c b/src/firmware/motor/mcsdk/current_ref_ctrl.c new file mode 100644 index 0000000000..53d1ac28b1 --- /dev/null +++ b/src/firmware/motor/mcsdk/current_ref_ctrl.c @@ -0,0 +1,160 @@ +/** + ****************************************************************************** + * @file current_ref_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the + * six-step current mode current reference PWM generation component of + * the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/current_ref_ctrl.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** + * @defgroup current_ref_ctrl Six-Step, current mode, PWM generation for current reference + * + * @brief PWM generation of the current reference for Six-Step drive with current mode + * + * This implementation exploits a timer to generate a PWM as reference to limit the + * current peak by means an external comparator + * + * @{ + */ + +/** + * @brief It initializes TIMx + * @param pHandle: handler of instance of the CRM component + * @retval none + */ +__weak void CRM_Init(CurrentRef_Handle_t* pHandle) +{ + switch (pHandle->pParams_str->RefTimerChannel) + { + case LL_TIM_CHANNEL_CH1: + { + LL_TIM_OC_SetCompareCH1(pHandle->pParams_str->TIMx, pHandle->StartCntPh); + } + break; + case LL_TIM_CHANNEL_CH2: + { + LL_TIM_OC_SetCompareCH2(pHandle->pParams_str->TIMx, pHandle->StartCntPh); + } + break; + case LL_TIM_CHANNEL_CH3: + { + LL_TIM_OC_SetCompareCH3(pHandle->pParams_str->TIMx, pHandle->StartCntPh); + } + break; + case LL_TIM_CHANNEL_CH4: + { + LL_TIM_OC_SetCompareCH4(pHandle->pParams_str->TIMx, pHandle->StartCntPh); + } + break; + default: + LL_TIM_OC_SetCompareCH1(pHandle->pParams_str->TIMx, pHandle->StartCntPh); + } + LL_TIM_EnableCounter(pHandle->pParams_str->TIMx); + LL_TIM_CC_EnableChannel(pHandle->pParams_str->TIMx, + pHandle->pParams_str->RefTimerChannel); +} + +/** + * @brief It clears TIMx counter and resets start-up duty cycle + * @param pHandle: handler of instance of the CRM component + * @retval none + */ +__weak void CRM_Clear(CurrentRef_Handle_t* pHandle) +{ + LL_TIM_SetCounter(pHandle->pParams_str->TIMx, 0u); + pHandle->Cnt = pHandle->StartCntPh; + switch (pHandle->pParams_str->RefTimerChannel) + { + case LL_TIM_CHANNEL_CH1: + { + LL_TIM_OC_SetCompareCH1(pHandle->pParams_str->TIMx, pHandle->Cnt); + } + break; + case LL_TIM_CHANNEL_CH2: + { + LL_TIM_OC_SetCompareCH2(pHandle->pParams_str->TIMx, pHandle->Cnt); + } + break; + case LL_TIM_CHANNEL_CH3: + { + LL_TIM_OC_SetCompareCH3(pHandle->pParams_str->TIMx, pHandle->Cnt); + } + break; + case LL_TIM_CHANNEL_CH4: + { + LL_TIM_OC_SetCompareCH4(pHandle->pParams_str->TIMx, pHandle->Cnt); + } + break; + default: + LL_TIM_OC_SetCompareCH1(pHandle->pParams_str->TIMx, pHandle->Cnt); + } +} + +/** + * @brief It updates current reference value + * @param pHandle: handler of instance of the CRM component + * @param hCnt: new reference value + * @retval none + */ +__weak void CRM_SetReference(CurrentRef_Handle_t* pHandle, uint16_t hCnt) +{ + pHandle->Cnt = hCnt; + switch (pHandle->pParams_str->RefTimerChannel) + { + case LL_TIM_CHANNEL_CH1: + { + LL_TIM_OC_SetCompareCH1(pHandle->pParams_str->TIMx, pHandle->Cnt); + } + break; + case LL_TIM_CHANNEL_CH2: + { + LL_TIM_OC_SetCompareCH2(pHandle->pParams_str->TIMx, pHandle->Cnt); + } + break; + case LL_TIM_CHANNEL_CH3: + { + LL_TIM_OC_SetCompareCH3(pHandle->pParams_str->TIMx, pHandle->Cnt); + } + break; + case LL_TIM_CHANNEL_CH4: + { + LL_TIM_OC_SetCompareCH4(pHandle->pParams_str->TIMx, pHandle->Cnt); + } + break; + default: + LL_TIM_OC_SetCompareCH1(pHandle->pParams_str->TIMx, pHandle->Cnt); + } +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/current_ref_ctrl.h b/src/firmware/motor/mcsdk/current_ref_ctrl.h new file mode 100644 index 0000000000..4a05d33763 --- /dev/null +++ b/src/firmware/motor/mcsdk/current_ref_ctrl.h @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file current_ref_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * six-step current mode current reference PWM generation component of + * the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup current_ref_ctrl + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef CURRENTREF_H +#define CURRENTREF_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup current_ref_ctrl + * @{ + */ + /* Exported defines ------------------------------------------------------------*/ + + /* Exported defines ----------------------------------------------------------*/ + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief CurrentRef pulse polarity definition + */ + typedef enum + { + UP = 0, + DOWN = 1, + } CurrentRef_PulsePolarity; + + /** + * @brief CurrentRef parameters definition + */ + typedef struct + { + TIM_TypeDef* TIMx; /*!< It contains the pointer to the timer + used for current reference PWM generation. */ + uint32_t RefTimerChannel; /*!< Channel of the timer used the generation */ + } CurrentRef_Params_t; + + /** + * @brief This structure is used to handle the data of an instance of the Current + * Reference component + * + */ + typedef struct + { + CurrentRef_Params_t const* pParams_str; + + uint16_t Cnt; /**< PWM Duty cycle */ + uint16_t StartCntPh; + uint16_t PWMperiod; /**< PWM period expressed in timer clock cycles unit: + * @f$hPWMPeriod = TimerFreq_{CLK} / F_{PWM}@f$ */ + CurrentRef_PulsePolarity pPolarity; + } CurrentRef_Handle_t; + + /* Exported functions --------------------------------------------------------*/ + + void CRM_Init(CurrentRef_Handle_t* pHandle); + + void CRM_Clear(CurrentRef_Handle_t* pHandle); + + void CRM_SetReference(CurrentRef_Handle_t* pHandle, uint16_t hCnt); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* CURRENTREF_H */ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/digital_output.c b/src/firmware/motor/mcsdk/digital_output.c new file mode 100644 index 0000000000..2bfedf5116 --- /dev/null +++ b/src/firmware/motor/mcsdk/digital_output.c @@ -0,0 +1,113 @@ +/** + ****************************************************************************** + * @file digital_output.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the Digital + * Output component of the Motor Control SDK: + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup DigitalOutput + */ + +/* Includes ------------------------------------------------------------------*/ +#include "digital_output.h" + +#include "mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup DigitalOutput Digital Output + * @brief Digital output component of the Motor Control SDK + * + * @{ + */ + + +/** + * @brief Accordingly with selected polarity, it sets to active or inactive the + * digital output + * @param pHandle handler address of the digital output component. + * @param State New requested state + * + */ +__weak void DOUT_SetOutputState(DOUT_handle_t *pHandle, DOutputState_t State) +{ +#ifdef NULL_PTR_CHECK_DIG_OUT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (ACTIVE == State) + { + if (pHandle->bDOutputPolarity == DOutputActiveHigh) + { + LL_GPIO_SetOutputPin(pHandle->hDOutputPort, pHandle->hDOutputPin); + } + else + { + LL_GPIO_ResetOutputPin(pHandle->hDOutputPort, pHandle->hDOutputPin); + } + } + else if (pHandle->bDOutputPolarity == DOutputActiveHigh) + { + LL_GPIO_ResetOutputPin(pHandle->hDOutputPort, pHandle->hDOutputPin); + } + else + { + LL_GPIO_SetOutputPin(pHandle->hDOutputPort, pHandle->hDOutputPin); + } + pHandle->OutputState = State; +#ifdef NULL_PTR_CHECK_DIG_OUT + } +#endif +} + +/** + * @brief It returns the state of the digital output + * @param pHandle pointer on related component instance + * @retval Digital output state (ACTIVE or INACTIVE) + */ +__weak DOutputState_t DOUT_GetOutputState(DOUT_handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_DIG_OUT + DOutputState_t temp_outputState; + + if (MC_NULL == pHandle) + { + temp_outputState = INACTIVE; + } + else + { + temp_outputState = pHandle->OutputState; + } + return (temp_outputState); +#else + return (pHandle->OutputState); +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/digital_output.h b/src/firmware/motor/mcsdk/digital_output.h new file mode 100644 index 0000000000..8265f399f0 --- /dev/null +++ b/src/firmware/motor/mcsdk/digital_output.h @@ -0,0 +1,88 @@ +/** + ****************************************************************************** + * @file digital_output.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * digital output component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup DigitalOutput + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef DIGITALOUTPUT_H +#define DIGITALOUTPUT_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup DigitalOutput + * @{ + */ + + +/* Exported constants --------------------------------------------------------*/ +#define DOutputActiveHigh 1U /*!< Digital output active high flag */ +#define DOutputActiveLow 0U /*!< Digital output active low flag */ + + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief Digital output handler definition + */ + typedef struct + { + DOutputState_t OutputState; /*!< indicates the state of the digital output */ + GPIO_TypeDef *hDOutputPort; /*!< GPIO output port. It must be equal + to GPIOx x= A, B, ...*/ + uint16_t hDOutputPin; /*!< GPIO output pin. It must be equal to + GPIO_Pin_x x= 0, 1, ...*/ + uint8_t bDOutputPolarity; /*!< GPIO output polarity. It must be equal + to DOutputActiveHigh or DOutputActiveLow */ + } DOUT_handle_t; + + + /* Accordingly with selected polarity, it sets to active or inactive the + * digital output + */ + void DOUT_SetOutputState(DOUT_handle_t *pHandle, DOutputState_t State); + + /* It returns the state of the digital output */ + __weak DOutputState_t DOUT_GetOutputState(DOUT_handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* DIGITALOUTPUT_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/enc_align_ctrl.c b/src/firmware/motor/mcsdk/enc_align_ctrl.c new file mode 100644 index 0000000000..729befef59 --- /dev/null +++ b/src/firmware/motor/mcsdk/enc_align_ctrl.c @@ -0,0 +1,216 @@ +/** + ****************************************************************************** + * @file enc_align_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Encoder Alignment Control component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup EncAlignCtrl + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/enc_align_ctrl.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup EncAlignCtrl Encoder Alignment Controller + * @brief Encoder Alignment Controller component of the Motor Control SDK + * + * Initial encoder calibration which comprises a rotor alignment in a given position + * necessary to make the information coming from a quadrature encoder absolute. + * @{ + */ + +/** + * @brief It initializes the handle + * @param pHandle: handler of the current instance of the EncAlignCtrl component. + * @param pSTC: Pointer to Speed and Torque Controller structure used by the EAC. + * @param pVSS: Pointer to Virtual Speed Sensor structure used by the EAC. + * @param pENC: Pointer to ENCoder structure used by the EAC. + */ +__weak void EAC_Init(EncAlign_Handle_t *pHandle, SpeednTorqCtrl_Handle_t *pSTC, + VirtualSpeedSensor_Handle_t *pVSS, ENCODER_Handle_t *pENC) +{ +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pSTC = pSTC; + pHandle->pVSS = pVSS; + pHandle->pENC = pENC; + pHandle->EncAligned = false; + pHandle->EncRestart = false; +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + } +#endif +} + +/** + * @brief It starts the encoder alignment procedure. + * It configures the VSS (Virtual Speed Sensor) with the required angle and sets the + * STC (Speed and Torque Controller) to execute the required torque ramp. + * @param pHandle: handler of the current instance of the EncAlignCtrl component. + */ +__weak void EAC_StartAlignment(EncAlign_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + uint32_t wAux; + + /* Set pVSS mechanical speed to zero.*/ + VSS_SetMecAcceleration(pHandle->pVSS, 0, 0U); + + /* Set pVSS mechanical angle.*/ + VSS_SetMecAngle(pHandle->pVSS, pHandle->hElAngle); + + /* Set pSTC in MCM_TORQUE_MODE.*/ + STC_SetControlMode(pHandle->pSTC, MCM_TORQUE_MODE); + + /* Set starting torque to Zero */ + (void)STC_ExecRamp(pHandle->pSTC, 0, 0U); + + /* Execute the torque ramp.*/ + (void)STC_ExecRamp(pHandle->pSTC, pHandle->hFinalTorque, + (uint32_t)pHandle->hDurationms); + /* Compute hRemainingTicks, the number of thick of alignment phase.*/ + wAux = ((uint32_t)pHandle->hDurationms) * ((uint32_t)pHandle->hEACFrequencyHz); + wAux /= 1000U; + pHandle->hRemainingTicks = (uint16_t)wAux; + pHandle->hRemainingTicks++; +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + } +#endif +} + +/** + * @brief It executes the encoder alignment controller and must be called with a + * frequency equal to the one settled in the parameters + * hEACFrequencyHz. Calling this method the EAC is able to verify + * if the alignment duration has been finished. At the end of alignment + * the encoder is set to the defined mechanical angle. + * Note: STC and VSS are not called by EAC_Exec. + * @param pHandle: handler of the current instance of the EncAlignCtrl component. + * @retval bool It returns true when the programmed alignment has been + * completed. + */ +__weak bool EAC_Exec(EncAlign_Handle_t *pHandle) +{ + bool retVal = true; +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + if (NULL == pHandle) + { + retVal = false; + } + else + { +#endif + if (pHandle->hRemainingTicks > 0U) + { + pHandle->hRemainingTicks--; + + if (0U == pHandle->hRemainingTicks) + { + /* At the end of Alignment procedure, we set the encoder mechanical angle + * to the alignement angle.*/ + ENC_SetMecAngle(pHandle->pENC, + pHandle->hElAngle / ((int16_t)pHandle->bElToMecRatio)); + pHandle->EncAligned = true; + retVal = true; + } + else + { + retVal = false; + } +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + } +#endif + } + + return (retVal); +} + +/** + * @brief It returns true if the encoder has been aligned at least + * one time, false if hasn't been never aligned. + * @param pHandle: handler of the current instance of the EncAlignCtrl component. + * @retval bool Encoder Aligned flag + */ +__weak bool EAC_IsAligned(EncAlign_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + return ((NULL == pHandle) ? false : pHandle->EncAligned); +#else + return (pHandle->EncAligned); +#endif +} + +/** + * @brief It sets handler ENCrestart variable according to restart parameter + * @param pHandle: handler of the current instance of the EncAlignCtrl component. + * @param restart: Equal to true if a restart is programmed else false. + */ +__weak void EAC_SetRestartState(EncAlign_Handle_t *pHandle, bool restart) +{ +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->EncRestart = restart; +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + } +#endif +} + +/** + * @brief Returns true if a restart after an encoder alignment has been requested. + * @param pHandle: handler of the current instance of the EncAlignCtrl component. + * @retval bool Encoder Alignment restart order flag + */ +__weak bool EAC_GetRestartState(EncAlign_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_ENC_ALI_CTRL + return ((NULL == pHandle) ? false : pHandle->EncRestart); +#else + return (pHandle->EncRestart); +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/enc_align_ctrl.h b/src/firmware/motor/mcsdk/enc_align_ctrl.h new file mode 100644 index 0000000000..1ba056b4c3 --- /dev/null +++ b/src/firmware/motor/mcsdk/enc_align_ctrl.h @@ -0,0 +1,112 @@ +/** + ****************************************************************************** + * @file enc_align_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Encoder Alignment Control component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup EncAlignCtrl + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef ENCALIGNCTRLCLASS_H +#define ENCALIGNCTRLCLASS_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "encoder_speed_pos_fdbk.h" +#include "mc_type.h" +#include "speed_torq_ctrl.h" +#include "virtual_speed_sensor.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup EncAlignCtrl + * @{ + */ + + /** + * @brief This structure is used to handle an instance of EncAlignCtrl component + */ + + typedef struct + { + SpeednTorqCtrl_Handle_t + *pSTC; /*!< Speed and torque controller object used by EAC.*/ + VirtualSpeedSensor_Handle_t *pVSS; /*!< Virtual speed sensor object used by EAC.*/ + ENCODER_Handle_t *pENC; /*!< Encoder object used by EAC.*/ + uint16_t hRemainingTicks; /*!< Number of tick events remaining to complete + the alignment.*/ + bool EncAligned; /*!< This flag is true if the encoder has been + aligned at least once, false if has not. */ + bool EncRestart; /*!< This flag is used to force a restart of the + motor after the encoder alignment. It is true + if a restart is programmed otherwise, it is false*/ + uint16_t hEACFrequencyHz; /*!< EAC_Exec() function calling frequency, in Hz. */ + int16_t hFinalTorque; /*!< Motor torque reference imposed by STC at the + end of programmed alignment. This value actually + is the Iq current expressed in digit.*/ + int16_t hElAngle; /*!< Electrical angle of programmed alignment + expressed in s16degrees [(rotor angle + unit)](measurement_units.md).*/ + uint16_t hDurationms; /*!< Duration of the programmed alignment expressed + in milliseconds.*/ + uint8_t bElToMecRatio; /*!< Coefficient used to transform electrical to + mechanical quantities and vice-versa. It usually + coincides with motor pole pairs number*/ + } EncAlign_Handle_t; + + + /* Exported functions ------------------------------------------------------- */ + + /* Function used to initialize an instance of the EncAlignCtrl component */ + void EAC_Init(EncAlign_Handle_t *pHandle, SpeednTorqCtrl_Handle_t *pSTC, + VirtualSpeedSensor_Handle_t *pVSS, ENCODER_Handle_t *pENC); + + /* Function used to start the encoder alignment procedure.*/ + void EAC_StartAlignment(EncAlign_Handle_t *pHandle); + + /* Function used to execute the encoder alignment controller*/ + bool EAC_Exec(EncAlign_Handle_t *pHandle); + + /* It returns true if the encoder has been aligned at least one time*/ + bool EAC_IsAligned(EncAlign_Handle_t *pHandle); + + /* It sets a restart after an encoder alignment*/ + void EAC_SetRestartState(EncAlign_Handle_t *pHandle, bool restart); + + /* Returns true if a restart after an encoder alignment has been requested*/ + bool EAC_GetRestartState(EncAlign_Handle_t *pHandle); + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* ENCALIGNCTRLCLASS_H */ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/encoder_speed_pos_fdbk.c b/src/firmware/motor/mcsdk/encoder_speed_pos_fdbk.c new file mode 100644 index 0000000000..0c714a9575 --- /dev/null +++ b/src/firmware/motor/mcsdk/encoder_speed_pos_fdbk.c @@ -0,0 +1,443 @@ +/** + ****************************************************************************** + * @file encoder_speed_pos_fdbk.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the following features + * of the Encoder component of the Motor Control SDK: + * - computes and stores average mechanical speed + * - computes and stores average mechanical acceleration + * - computes and stores the instantaneous electrical speed + * - calculates the rotor electrical and mechanical angle + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup Encoder + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/encoder_speed_pos_fdbk.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup SpeednPosFdbk + * @{ + */ + +/** @defgroup Encoder Encoder Speed & Position Feedback + * @brief Quadrature Encoder based Speed & Position Feedback implementation + * + * This component is used in applications controlling a motor equipped with a quadrature + * encoder. + * + * This component uses the output of a quadrature encoder to provide a measure of the + * speed and the motor rotor position. + * + * More detail in [Encoder Speed & Position Feedback + * module](rotor_speed_pos_feedback_qenc.md). + * + * @{ + */ + +/* Private defines -----------------------------------------------------------*/ + + +/** + * @brief It initializes the hardware peripherals + required for the speed position sensor management using ENCODER + sensors. + * @param pHandle: handler of the current instance of the encoder component + */ +__weak void ENC_Init(ENCODER_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + TIM_TypeDef *TIMx = pHandle->TIMx; + uint8_t bufferSize; + uint8_t index; + +#ifdef TIM_CNT_UIFCPY + LL_TIM_EnableUIFRemap(TIMx); +#define ENC_MAX_OVERFLOW_NB ((uint16_t)2048) /* 2^11*/ +#else +#define ENC_MAX_OVERFLOW_NB (1) +#endif + /* Reset counter */ + LL_TIM_SetCounter(TIMx, 0); + + /*Calculations of convenience*/ + pHandle->U32MAXdivPulseNumber = UINT32_MAX / ((uint32_t)pHandle->PulseNumber); + pHandle->SpeedSamplingFreqUnit = + ((uint32_t)pHandle->SpeedSamplingFreqHz * (uint32_t)SPEED_UNIT); + + /* Set IC filter for both channel 1 & 2*/ + LL_TIM_IC_SetFilter(TIMx, LL_TIM_CHANNEL_CH1, + ((uint32_t)pHandle->ICx_Filter << 20U)); + LL_TIM_IC_SetFilter(TIMx, LL_TIM_CHANNEL_CH2, + ((uint32_t)pHandle->ICx_Filter << 20U)); + + LL_TIM_ClearFlag_UPDATE(TIMx); + LL_TIM_EnableIT_UPDATE(TIMx); + + /* Enable the counting timer*/ + LL_TIM_EnableCounter(TIMx); + + /* Erase speed buffer */ + bufferSize = pHandle->SpeedBufferSize; + + for (index = 0U; index < bufferSize; index++) + { + pHandle->DeltaCapturesBuffer[index] = 0; + } +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + } +#endif +} + +/** + * @brief Clear software FIFO where the captured rotor angle variations are stored. + * This function must be called before starting the motor to initialize + * the speed measurement process. + * @param pHandle: handler of the current instance of the encoder component + */ +__weak void ENC_Clear(ENCODER_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + uint8_t index; + + for (index = 0u; index < pHandle->SpeedBufferSize; index++) + { + pHandle->DeltaCapturesBuffer[index] = 0; + } + pHandle->SensorIsReliable = true; +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + } +#endif +} + +/** + * @brief It calculates the rotor electrical and mechanical angle, on the basis + * of the instantaneous value of the timer counter. + * @param pHandle: handler of the current instance of the encoder component + * @retval Measured electrical angle in [s16degree](measurement_units.md) format. + */ +__weak int16_t ENC_CalcAngle(ENCODER_Handle_t *pHandle) +{ + int16_t elAngle; /* s16degree format */ +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + if (NULL == pHandle) + { + elAngle = 0; + } + else + { +#endif + int16_t mecAngle; /* s16degree format */ + uint32_t uwtemp1; + int32_t wtemp1; + /* PR 52926 We need to keep only the 16 LSB, bit 31 could be at 1 + if the overflow occurs just after the entry in the High frequency task */ + uwtemp1 = (LL_TIM_GetCounter(pHandle->TIMx) & 0xffffU) * + (pHandle->U32MAXdivPulseNumber); +#ifndef FULL_MISRA_C_COMPLIANCY_ENC_SPD_POS + wtemp1 = + (int32_t)uwtemp1 >> + 16U; // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 +#else + wtemp1 = (int32_t)uwtemp1 / 65536; +#endif + /*Computes and stores the rotor mechanical angle*/ + mecAngle = (int16_t)wtemp1; + + int16_t hMecAnglePrev = pHandle->_Super.hMecAngle; + + pHandle->_Super.hMecAngle = mecAngle; + + /*Computes and stores the rotor electrical angle*/ + elAngle = mecAngle * (int16_t)(pHandle->_Super.bElToMecRatio); + + pHandle->_Super.hElAngle = elAngle; + + int16_t hMecSpeedDpp = mecAngle - hMecAnglePrev; + pHandle->_Super.wMecAngle += ((int32_t)hMecSpeedDpp); +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + } +#endif + /*Returns rotor electrical angle*/ + return (elAngle); +} + +/** + * @brief This method must be called with the periodicity defined by parameter + * SpeedSamplingFreqUnit. The method generates a capture event on + * a channel, computes and stores average mechanical speed expressed in the unit + * defined by #SPEED_UNIT (on the basis of the buffer filled by Medium Frequency + * Task), computes and stores average mechanical acceleration expressed in + * #SPEED_UNIT/SpeedSamplingFreq, computes and stores the instantaneous electrical speed + * in Digit Per control Period unit [dpp](measurement_units.md), updates the index of the + * speed buffer, then checks, stores and returns the reliability state + * of the sensor. + * @param pHandle: handler of the current instance of the encoder component + * @param pMecSpeedUnit pointer used to return the rotor average mechanical speed + * expressed in the unit defined by #SPEED_UNIT + * @retval true = sensor information is reliable. false = sensor information is not + * reliable + */ +__weak bool ENC_CalcAvrgMecSpeedUnit(ENCODER_Handle_t *pHandle, int16_t *pMecSpeedUnit) +{ + bool bReliability; +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + if ((NULL == pHandle) || (NULL == pMecSpeedUnit)) + { + bReliability = false; + } + else + { +#endif + int32_t wtemp1; + int32_t wtemp2; + uint32_t OverflowCntSample; + uint32_t CntCapture; + uint32_t directionSample; + int32_t wOverallAngleVariation = 0; + TIM_TypeDef *TIMx = pHandle->TIMx; + uint8_t bBufferSize = pHandle->SpeedBufferSize; + uint8_t bBufferIndex; +#ifdef TIM_CNT_UIFCPY + uint8_t OFbit; +#else + uint8_t OFbit = 0U; +#endif + +#ifdef TIM_CNT_UIFCPY + /* disable Interrupt generation */ + LL_TIM_DisableIT_UPDATE(TIMx); +#endif + CntCapture = LL_TIM_GetCounter(TIMx); + OverflowCntSample = pHandle->TimerOverflowNb; + pHandle->TimerOverflowNb = 0; + directionSample = LL_TIM_GetDirection(TIMx); +#ifdef TIM_CNT_UIFCPY + OFbit = __LL_TIM_GETFLAG_UIFCPY(CntCapture); + if (0U == OFbit) + { + /* Nothing to do */ + } + else + { + /* If OFbit is set, overflow has occured since IT has been disabled. + We have to take this overflow into account in the angle computation, + but we must not take it into account a second time in the accmulator, + so we have to clear the pending flag. If the OFbit is not set, it does not + mean that an Interrupt has not occured since the last read, but it has not + been taken into accout, we must not clear the interrupt in order to accumulate + it */ + LL_TIM_ClearFlag_UPDATE(TIMx); + } + + LL_TIM_EnableIT_UPDATE(TIMx); + CLEAR_BIT(CntCapture, TIM_CNT_UIFCPY); +#endif + + /* If UIFCPY is not present, OverflowCntSample can not be used safely for + speed computation, but we still use it to check that we do not exceed one overflow + (sample frequency not less than mechanical motor speed */ + + if ((OverflowCntSample + OFbit) > ENC_MAX_OVERFLOW_NB) + { + pHandle->TimerOverflowError = true; + } + else + { + /* Nothing to do */ + } + + /*Calculation of delta angle*/ + if (LL_TIM_COUNTERDIRECTION_DOWN == directionSample) + { + /* encoder timer down-counting*/ + /* if UIFCPY not present Overflow counter can not be safely used -> limitation + * to 1 OF. */ +#ifndef TIM_CNT_UIFCPY + OverflowCntSample = (CntCapture > pHandle->PreviousCapture) ? 1 : 0; +#endif + pHandle->DeltaCapturesBuffer[pHandle->DeltaCapturesIndex] = + ((int32_t)CntCapture) - ((int32_t)pHandle->PreviousCapture) - + ((((int32_t)OverflowCntSample) + (int32_t)OFbit) * + ((int32_t)pHandle->PulseNumber)); + } + else + { + /* encoder timer up-counting*/ + /* if UIFCPY not present Overflow counter can not be safely used -> limitation + * to 1 OF. */ +#ifndef TIM_CNT_UIFCPY + OverflowCntSample = (CntCapture < pHandle->PreviousCapture) ? 1 : 0; +#endif + pHandle->DeltaCapturesBuffer[pHandle->DeltaCapturesIndex] = + ((int32_t)CntCapture) - ((int32_t)pHandle->PreviousCapture) + + ((((int32_t)OverflowCntSample) + (int32_t)OFbit) * + ((int32_t)pHandle->PulseNumber)); + } + + + /*Computes & returns average mechanical speed */ + for (bBufferIndex = 0U; bBufferIndex < bBufferSize; bBufferIndex++) + { + wOverallAngleVariation += pHandle->DeltaCapturesBuffer[bBufferIndex]; + } + wtemp1 = wOverallAngleVariation * ((int32_t)pHandle->SpeedSamplingFreqUnit); + wtemp2 = ((int32_t)pHandle->PulseNumber) * ((int32_t)pHandle->SpeedBufferSize); + wtemp1 = ((0 == wtemp2) ? wtemp1 : (wtemp1 / wtemp2)); + + *pMecSpeedUnit = (int16_t)wtemp1; + + /*Computes & stores average mechanical acceleration */ + pHandle->_Super.hMecAccelUnitP = + (int16_t)(wtemp1 - pHandle->_Super.hAvrMecSpeedUnit); + + /*Stores average mechanical speed */ + pHandle->_Super.hAvrMecSpeedUnit = (int16_t)wtemp1; + + /*Computes & stores the instantaneous electrical speed [dpp], var wtemp1*/ + wtemp1 = pHandle->DeltaCapturesBuffer[pHandle->DeltaCapturesIndex] * + ((int32_t)pHandle->SpeedSamplingFreqHz) * + ((int32_t)pHandle->_Super.bElToMecRatio); + wtemp1 /= ((int32_t)pHandle->PulseNumber); + wtemp1 *= ((int32_t)pHandle->_Super.DPPConvFactor); + wtemp1 /= ((int32_t)pHandle->_Super.hMeasurementFrequency); + + pHandle->_Super.hElSpeedDpp = (int16_t)wtemp1; + + /*last captured value update*/ + pHandle->PreviousCapture = + (CntCapture >= (uint32_t)65535) ? 65535U : (uint16_t)CntCapture; + /*Buffer index update*/ + pHandle->DeltaCapturesIndex++; + + if (pHandle->DeltaCapturesIndex >= pHandle->SpeedBufferSize) + { + pHandle->DeltaCapturesIndex = 0U; + } + else + { + /* nothing to do */ + } + + /*Checks the reliability status, then stores and returns it*/ + if (pHandle->TimerOverflowError) + { + bReliability = false; + pHandle->SensorIsReliable = false; + pHandle->_Super.bSpeedErrorNumber = pHandle->_Super.bMaximumSpeedErrorsNumber; + } + else + { + bReliability = SPD_IsMecSpeedReliable(&pHandle->_Super, pMecSpeedUnit); + } +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + } +#endif + return (bReliability); +} + +/** + * @brief It set instantaneous rotor mechanical angle. + * As a consequence, timer counter is computed and updated. + * @param pHandle: handler of the current instance of the encoder component + * @param hMecAngle new value of rotor mechanical angle in + * [s16degree](measurement_units.md) format. + */ +__weak void ENC_SetMecAngle(ENCODER_Handle_t *pHandle, int16_t hMecAngle) +{ +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + TIM_TypeDef *TIMx = pHandle->TIMx; + + uint16_t hAngleCounts; + uint16_t hMecAngleuint; + int16_t localhMecAngle = hMecAngle; + + pHandle->_Super.hMecAngle = localhMecAngle; + pHandle->_Super.hElAngle = + localhMecAngle * (int16_t)pHandle->_Super.bElToMecRatio; + if (localhMecAngle < 0) + { + localhMecAngle *= -1; + hMecAngleuint = 65535U - ((uint16_t)localhMecAngle); + } + else + { + hMecAngleuint = (uint16_t)localhMecAngle; + } + + hAngleCounts = + (uint16_t)((((uint32_t)hMecAngleuint) * ((uint32_t)pHandle->PulseNumber)) / + 65535U); + + TIMx->CNT = (uint16_t)hAngleCounts; +#ifdef NULL_PTR_CHECK_ENC_SPD_POS_FDB + } +#endif +} + +/** + * @brief TIMER ENCODER Overflow interrupt counter update + * @param pHandleVoid: handler of the current instance of the encoder component + */ +__weak void *ENC_IRQHandler(void *pHandleVoid) +{ + ENCODER_Handle_t *pHandle = + (ENCODER_Handle_t *)pHandleVoid; // cstat !MISRAC2012-Rule-11.5 + + /*Updates the number of overflows occurred*/ + /* the handling of overflow error is done in ENC_CalcAvrgMecSpeedUnit */ + pHandle->TimerOverflowNb += 1U; + + return (MC_NULL); +} +/** + * @} + */ + +/** + * @} + */ + +/** @} */ + + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/encoder_speed_pos_fdbk.h b/src/firmware/motor/mcsdk/encoder_speed_pos_fdbk.h new file mode 100644 index 0000000000..9fd7c0b0ae --- /dev/null +++ b/src/firmware/motor/mcsdk/encoder_speed_pos_fdbk.h @@ -0,0 +1,140 @@ +/** + ****************************************************************************** + * @file encoder_speed_pos_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Encoder Speed & Position Feedback component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup Encoder + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef ENCODER_SPEEDNPOSFDBK_H +#define ENCODER_SPEEDNPOSFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "speed_pos_fdbk.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednPosFdbk + * @{ + */ + + /** @addtogroup Encoder + * @{ + */ + + /* Exported constants --------------------------------------------------------*/ + +#define GPIO_NoRemap_TIMx ((uint32_t)(0)) +#define ENC_DMA_PRIORITY DMA_Priority_High +#define ENC_SPEED_ARRAY_SIZE ((uint8_t)16) /* 2^4 */ + + /** + * @brief ENCODER class parameters definition + */ + typedef struct + { + SpeednPosFdbk_Handle_t _Super; /*!< SpeednPosFdbk handle definition. */ + + TIM_TypeDef *TIMx; /*!< Timer used for ENCODER sensor management.*/ + + uint32_t SpeedSamplingFreqUnit; /*!< Frequency at which motor speed is to be + computed. It must be equal to the frequency + at which function SPD_CalcAvrgMecSpeedUnit + is called.*/ + int32_t DeltaCapturesBuffer[ENC_SPEED_ARRAY_SIZE]; /*!< Buffer used to store + captured variations of timer counter*/ + + + uint32_t U32MAXdivPulseNumber; /*!< It stores U32MAX/hPulseNumber */ + + uint16_t SpeedSamplingFreqHz; /*!< Frequency (Hz) at which motor speed + is to be computed. */ + + /* SW Settings */ + uint16_t PulseNumber; /*!< Number of pulses per revolution, provided by each + of the two encoder signals, multiplied by 4 */ + + volatile uint16_t TimerOverflowNb; /*!< Number of overflows occurred since + last speed measurement event*/ + uint16_t PreviousCapture; /*!< Timer counter value captured during + previous speed measurement event*/ + + uint8_t SpeedBufferSize; /*!< Size of the buffer used to calculate the average + speed. It must be <= 16.*/ + + + bool SensorIsReliable; /*!< Flag to indicate sensor/decoding is not + properly working.*/ + + uint8_t ICx_Filter; /*!< Input Capture filter selection */ + + volatile uint8_t DeltaCapturesIndex; /*!< Buffer index */ + + bool TimerOverflowError; /*!< true if the number of overflow + occurred is greater than 'define' + ENC_MAX_OVERFLOW_NB*/ + + } ENCODER_Handle_t; + + + /* IRQ implementation of the TIMER ENCODER */ + void *ENC_IRQHandler(void *pHandleVoid); + + /* It initializes the hardware peripherals (TIMx, GPIO and NVIC) + * required for the speed position sensor management using ENCODER + * sensors. */ + void ENC_Init(ENCODER_Handle_t *pHandle); + + /* Clear software FIFO where are "pushed" rotor angle variations captured. */ + void ENC_Clear(ENCODER_Handle_t *pHandle); + + /* It calculates the rotor electrical and mechanical angle, on the basis + * of the instantaneous value of the timer counter. */ + int16_t ENC_CalcAngle(ENCODER_Handle_t *pHandle); + + /* The method generates a capture event on a channel, computes & stores average + * mechanical speed */ + bool ENC_CalcAvrgMecSpeedUnit(ENCODER_Handle_t *pHandle, int16_t *pMecSpeedUnit); + + /* It set instantaneous rotor mechanical angle. */ + void ENC_SetMecAngle(ENCODER_Handle_t *pHandle, int16_t hMecAngle); + + + /** + * @} + */ + + /** + * @} + */ + + /** @} */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /*ENCODER_SPEEDNPOSFDBK_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/feed_forward_ctrl.c b/src/firmware/motor/mcsdk/feed_forward_ctrl.c new file mode 100644 index 0000000000..59d0c6aac3 --- /dev/null +++ b/src/firmware/motor/mcsdk/feed_forward_ctrl.c @@ -0,0 +1,454 @@ +/** + ****************************************************************************** + * @file feed_forward_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the Feed-forward + * Control component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + * @ingroup FeedForwardCtrl + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/feed_forward_ctrl.h" + +#include + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/bus_voltage_sensor.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/r_divider_bus_voltage_sensor.h" +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" +#include "firmware/motor/mcsdk/speed_torq_ctrl.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup FeedForwardCtrl Feed-forward Control + * @brief Feed-forward Control component of the Motor Control SDK + * + * See the [Feed-forward chapter of the User Manual](feed_forward_current_regulation.md) + * for more details on the theoretical background of this regulator. + * @{ + */ + +/* Private macros ------------------------------------------------------------*/ +#define SEGMNUM (uint8_t)7 /* coeff no. -1 */ +#define SATURATION_TO_S16(a) \ + if ((a) > 32767) \ + { \ + (a) = 32767; \ + } \ + else if ((a) < -32767) \ + { \ + (a) = -32767; \ + } \ + else \ + { \ + } + + + +/** + * @brief Initializes all the component variables + * @param pHandle Feed-forward init structure. + * @param pBusSensor VBus Sensor. + * @param pPIDId Id PID structure. + * @param pPIDIq Iq PID structure. + */ +__weak void FF_Init(FF_Handle_t *pHandle, BusVoltageSensor_Handle_t *pBusSensor, + PID_Handle_t *pPIDId, PID_Handle_t *pPIDIq) +{ +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->wConstant_1D = pHandle->wDefConstant_1D; + pHandle->wConstant_1Q = pHandle->wDefConstant_1Q; + pHandle->wConstant_2 = pHandle->wDefConstant_2; + + pHandle->pBus_Sensor = pBusSensor; + + pHandle->pPID_d = pPIDId; + + pHandle->pPID_q = pPIDIq; +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + } +#endif +} + +/** + * @brief It should be called before each motor start and clears the Feed-forward + * internal variables. + * @param pHandle Feed-forward structure. + */ +__weak void FF_Clear(FF_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->Vqdff.q = (int16_t)0; + pHandle->Vqdff.d = (int16_t)0; +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + } +#endif +} + +/** + * @brief It implements Feed-forward controller by computing new Vqdff value. + * This will be then summed up to PI output in FF_VqdConditioning + * method. + * @param pHandle Feed-forward structure. + * @param Iqdref Iqd reference components used to calculate the Feed-forward + * action. + * @param pSTC Pointer on speed and torque controller structure. + */ +__weak void FF_VqdffComputation(FF_Handle_t *pHandle, qd_t Iqdref, + SpeednTorqCtrl_Handle_t *pSTC) +{ +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int32_t wtemp1, wtemp2; + int16_t hSpeed_dpp; + uint16_t hAvBusVoltage_d; + SpeednPosFdbk_Handle_t *SpeedSensor; + + SpeedSensor = STC_GetSpeedSensor(pSTC); + hSpeed_dpp = SPD_GetElSpeedDpp(SpeedSensor); + hAvBusVoltage_d = VBS_GetAvBusVoltage_d(pHandle->pBus_Sensor) / 2U; + + if (hAvBusVoltage_d != (uint16_t)0) + { + /*q-axes ff voltage calculation */ + wtemp1 = (((int32_t)(hSpeed_dpp)*Iqdref.d) / (int32_t)32768); + wtemp2 = (wtemp1 * pHandle->wConstant_1D) / (int32_t)(hAvBusVoltage_d); + wtemp2 *= (int32_t)2; + + wtemp1 = ((pHandle->wConstant_2 * hSpeed_dpp) / (int32_t)hAvBusVoltage_d) * + (int32_t)16; + + wtemp2 = wtemp1 + wtemp2 + pHandle->VqdAvPIout.q; + + SATURATION_TO_S16(wtemp2) + + pHandle->Vqdff.q = (int16_t)(wtemp2); + + /* d-axes ff voltage calculation */ + wtemp1 = (((int32_t)(hSpeed_dpp)*Iqdref.q) / (int32_t)32768); + wtemp2 = (wtemp1 * pHandle->wConstant_1Q) / (int32_t)(hAvBusVoltage_d); + wtemp2 *= (int32_t)2; + + wtemp2 = (int32_t)pHandle->VqdAvPIout.d - wtemp2; + + SATURATION_TO_S16(wtemp2) + + pHandle->Vqdff.d = (int16_t)(wtemp2); + } + else + { + pHandle->Vqdff.q = (int16_t)0; + pHandle->Vqdff.d = (int16_t)0; + } +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + } +#endif +} + +// cstat #MISRAC2012-Rule-2.2_b +/* False positive */ +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief It returns the Vqd components computed by input plus the Feed-forward + * action and store the last Vqd values in the internal variable. + * @param pHandle Feed-forward structure. + * @param Vqd Initial value of Vqd to be manipulated by Feed-forward action . + * @retval qd_t Vqd conditioned values. + */ +__weak qd_t FF_VqdConditioning(FF_Handle_t *pHandle, qd_t Vqd) +{ + qd_t lVqd; +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + if (NULL == pHandle) + { + lVqd.q = 0; + lVqd.d = 0; + } + else + { +#endif + int32_t wtemp; + + pHandle->VqdPIout = Vqd; + + wtemp = (int32_t)(Vqd.q) + pHandle->Vqdff.q; + + SATURATION_TO_S16(wtemp) + + lVqd.q = (int16_t)wtemp; + + wtemp = (int32_t)(Vqd.d) + pHandle->Vqdff.d; + + SATURATION_TO_S16(wtemp) + + lVqd.d = (int16_t)wtemp; +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + } +#endif + return (lVqd); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief It low-pass filters the Vqd voltage coming from the speed PI. Filter + * bandwidth depends on hVqdLowPassFilterBW parameter. + * @param pHandle Feed-forward structure. + */ +__weak void FF_DataProcess(FF_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int32_t wAux; + int32_t lowPassFilterBW = (int32_t)pHandle->hVqdLowPassFilterBW - (int32_t)1; + +#ifndef FULL_MISRA_C_COMPLIANCY_FWD_FDB + /* Computation of average Vqd as output by PI(D) current controllers, used by + Feed-forward controller algorithm */ + wAux = (int32_t)(pHandle->VqdAvPIout.q) * lowPassFilterBW; + wAux += pHandle->VqdPIout.q; + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + pHandle->VqdAvPIout.q = (int16_t)(wAux >> pHandle->hVqdLowPassFilterBWLOG); + + wAux = (int32_t)(pHandle->VqdAvPIout.d) * lowPassFilterBW; + wAux += pHandle->VqdPIout.d; + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + pHandle->VqdAvPIout.d = (int16_t)(wAux >> pHandle->hVqdLowPassFilterBWLOG); + +#else + /* Computation of average Vqd as output by PI(D) current controllers, used by + Feed-forward controller algorithm */ + wAux = (int32_t)(pHandle->VqdAvPIout.q) * lowPassFilterBW; + wAux += pHandle->VqdPIout.q; + + pHandle->VqdAvPIout.q = (int16_t)(wAux / (int32_t)(pHandle->hVqdLowPassFilterBW)); + + wAux = (int32_t)(pHandle->VqdAvPIout.d) * lowPassFilterBW; + wAux += pHandle->VqdPIout.d; + + pHandle->VqdAvPIout.d = (int16_t)(wAux / (int32_t)(pHandle->hVqdLowPassFilterBW)); +#endif +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + } +#endif +} + +/** + * @brief Use this method to initialize FF variables in START_TO_RUN state. + * @param pHandle Feed-forward structure. + */ +__weak void FF_InitFOCAdditionalMethods(FF_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->VqdAvPIout.q = 0; + pHandle->VqdAvPIout.d = 0; + PID_SetIntegralTerm(pHandle->pPID_q, 0); + PID_SetIntegralTerm(pHandle->pPID_d, 0); +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + } +#endif +} + +/** + * @brief Use this method to set new constants values used by + * Feed-forward algorithm. + * @param pHandle Feed-forward structure. + * @param sNewConstants The FF_TuningStruct_t containing constants used by + * Feed-forward algorithm. + */ +__weak void FF_SetFFConstants(FF_Handle_t *pHandle, FF_TuningStruct_t sNewConstants) +{ +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->wConstant_1D = sNewConstants.wConst_1D; + pHandle->wConstant_1Q = sNewConstants.wConst_1Q; + pHandle->wConstant_2 = sNewConstants.wConst_2; +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + } +#endif +} + + +// cstat #MISRAC2012-Rule-2.2_b +/* False positive */ +/** + * @brief Use this method to get current constants values used by + * Feed-forward algorithm. + * @param pHandle Feed-forward structure. + * @retval FF_TuningStruct_t Values of the constants used by + * Feed-forward algorithm. + */ +__weak FF_TuningStruct_t FF_GetFFConstants(FF_Handle_t *pHandle) +{ + FF_TuningStruct_t LocalConstants; +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + if (NULL == pHandle) + { + LocalConstants.wConst_1D = 0; + LocalConstants.wConst_1Q = 0; + LocalConstants.wConst_2 = 0; + } + else + { +#endif + LocalConstants.wConst_1D = pHandle->wConstant_1D; + LocalConstants.wConst_1Q = pHandle->wConstant_1Q; + LocalConstants.wConst_2 = pHandle->wConstant_2; +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + } +#endif + return (LocalConstants); +} + + +/** + * @brief Use this method to get present values for the Vqd Feed-forward + * components. + * @param pHandle Feed-forward structure. + * @retval qd_t Vqd Feed-forward components. + */ +__weak qd_t FF_GetVqdff(const FF_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + qd_t retqt; + if (NULL == pHandle) + { + retqt.q = 0; + retqt.d = 0; + } + else + { + retqt = pHandle->Vqdff; + } + return (retqt); +#else + return (pHandle->Vqdff); +#endif +} + +/** + * @brief Use this method to get the averaged output values of qd axes + * currents PI regulators. + * @param pHandle Feed-forward structure. + * @retval qd_t Averaged output of qd axes currents PI regulators. + */ +__weak qd_t FF_GetVqdAvPIout(const FF_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_FEED_FWD_CTRL + qd_t retqt; + if (NULL == pHandle) + { + retqt.q = 0; + retqt.d = 0; + } + else + { + retqt = pHandle->VqdAvPIout; + } + return (retqt); +#else + return (pHandle->VqdAvPIout); +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/feed_forward_ctrl.h b/src/firmware/motor/mcsdk/feed_forward_ctrl.h new file mode 100644 index 0000000000..dc65bf9c3d --- /dev/null +++ b/src/firmware/motor/mcsdk/feed_forward_ctrl.h @@ -0,0 +1,157 @@ +/** + ****************************************************************************** + * @file feed_forward_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Feed Forward Control component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup FeedForwardCtrl + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FEEDFORWARDCTRL_H +#define FEEDFORWARDCTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "bus_voltage_sensor.h" +#include "mc_type.h" +#include "speed_pos_fdbk.h" +#include "speed_torq_ctrl.h" + + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup FeedForwardCtrl + * @{ + */ + + /** + * @brief Handle structure of the Feed-forward Component + */ + typedef struct + { + qd_t Vqdff; /**< Feed Forward controller @f$I_{qd}@f$ contribution to @f$V_{qd}@f$ + */ + qd_t VqdPIout; /**< @f$V_{qd}@f$ as output by PID controller */ + qd_t VqdAvPIout; /**< Averaged @f$V_{qd}@f$ as output by PID controller */ + int32_t wConstant_1D; /**< Feed forward default constant for the @f$d@f$ axis */ + int32_t wConstant_1Q; /**< Feed forward default constant for the @f$q@f$ axis */ + int32_t wConstant_2; /**< Default constant value used by Feed-forward algorithm */ + BusVoltageSensor_Handle_t *pBus_Sensor; /**< Related bus voltage sensor */ + PID_Handle_t *pPID_q; /*!< Related PI for @f$I_{q}@f$ regulator */ + PID_Handle_t *pPID_d; /*!< Related PI for @f$I_{d}@f$ regulator */ + uint16_t hVqdLowPassFilterBW; /**< Use this parameter to configure the Vqd + first order software filter bandwidth. In + case FULL_MISRA_COMPLIANCY, + hVqdLowPassFilterBW is used and equal to + FOC_CurrController call rate [Hz]/ + FilterBandwidth[Hz]. On the contrary, if + FULL_MISRA_COMPLIANCY is not defined, + hVqdLowPassFilterBWLOG is used and equal to + log with base two of previous definition */ + int32_t wDefConstant_1D; /**< Feed forward default constant for d axes */ + int32_t wDefConstant_1Q; /**< Feed forward default constant for q axes */ + int32_t wDefConstant_2; /**< Default constant value used by + Feed-forward algorithm*/ + uint16_t hVqdLowPassFilterBWLOG; /**< hVqdLowPassFilterBW expressed as power of 2. + E.g. if gain divisor is 512 the value + must be 9 because 2^9 = 512 */ + + } FF_Handle_t; + + + + /* + * Initializes all the component variables + */ + void FF_Init(FF_Handle_t *pHandle, BusVoltageSensor_Handle_t *pBusSensor, + PID_Handle_t *pPIDId, PID_Handle_t *pPIDIq); + + /* + * It should be called before each motor restart and clears the Feed-forward + * internal variables. + */ + void FF_Clear(FF_Handle_t *pHandle); + + /* + * It implements Feed-forward controller by computing new Vqdff value. + * This will be then summed up to PI output in FF_VqdConditioning + * method. + */ + void FF_VqdffComputation(FF_Handle_t *pHandle, qd_t Iqdref, + SpeednTorqCtrl_Handle_t *pSTC); + + /* + * It returns the Vqd components computed by input plus the Feed-forward + * action and store the last Vqd values in the internal variable. + */ + qd_t FF_VqdConditioning(FF_Handle_t *pHandle, qd_t Vqd); + + /* + * It low-pass filters the Vqd voltage coming from the speed PI. Filter + * bandwidth depends on hVqdLowPassFilterBW parameter. + */ + void FF_DataProcess(FF_Handle_t *pHandle); + + /* + * Use this method to initialize FF variables in START_TO_RUN state. + */ + void FF_InitFOCAdditionalMethods(FF_Handle_t *pHandle); + + /* + * Use this method to set new constants values used by + * Feed-forward algorithm. + */ + void FF_SetFFConstants(FF_Handle_t *pHandle, FF_TuningStruct_t sNewConstants); + + /* + * Use this method to get present constants values used by + * Feed-forward algorithm. + */ + FF_TuningStruct_t FF_GetFFConstants(FF_Handle_t *pHandle); + + /* + * Use this method to get present values for the Vqd Feed-forward + * components. + */ + qd_t FF_GetVqdff(const FF_Handle_t *pHandle); + + /* + * Use this method to get the averaged output values of qd axes + * currents PI regulators. + */ + qd_t FF_GetVqdAvPIout(const FF_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* FEEDFORWARDCTRL_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/flux_weakening_ctrl.c b/src/firmware/motor/mcsdk/flux_weakening_ctrl.c new file mode 100644 index 0000000000..d368716849 --- /dev/null +++ b/src/firmware/motor/mcsdk/flux_weakening_ctrl.c @@ -0,0 +1,342 @@ +/** + ****************************************************************************** + * @file flux_weakening_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implements the Flux Weakening + * Control component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup FluxWeakeningCtrl + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/flux_weakening_ctrl.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/pid_regulator.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup FluxWeakeningCtrl Flux Weakening Control + * @brief Flux Weakening (FW) Control component of the Motor Control SDK + * + * The Flux Weakening Control component modifies Idq reference to reach a speed higher + * than rated one. To do so it uses its own PID controller to control the current + * reference and acts also on the PID speed controller. + * + * Flux Weakening Control component needs to be initialized before it can be used. This is + * done with the FW_Init() function. Ensure that PID speed has been correctly initialized + * prior to use flux weakiening component. + * + * The controller functions implemented by the FW_CalcCurrRef() functions is based on + * 16-bit integer arithmetics The controller output values returned by this functions is + * also 16-bit integers. This makes it possible to use this component efficiently on all + * STM2 MCUs. + * + * For more information, please refer to [Flux Weakening + * documentation](flux_weakening_control.md) + * + * @{ + */ + +/** + * @brief Initializes flux weakening component handler, it should be called + * once during Motor Control initialization. + * @param pHandle pointer to flux weakening component handler. + * @param pPIDSpeed pointer to speed PID strutcture. + * @param PIDFluxWeakeningHandle pointer to FW PID strutcture. + */ +__weak void FW_Init(FW_Handle_t *pHandle, PID_Handle_t *pPIDSpeed, + PID_Handle_t *pPIDFluxWeakeningHandle) +{ +#ifdef NULL_PTR_CHECK_FLUX_WEAK + if (NULL == pHandle) + { + /* Mothing to do */ + } + else + { +#endif + pHandle->hFW_V_Ref = pHandle->hDefaultFW_V_Ref; + pHandle->pFluxWeakeningPID = pPIDFluxWeakeningHandle; + pHandle->pSpeedPID = pPIDSpeed; +#ifdef NULL_PTR_CHECK_FLUX_WEAK + } +#endif +} + +/** + * @brief Clears the Flux weakening internal variables except the target + * voltage (hFW_V_Ref). It should be called before each motor restart + * @param pHandle pointer to flux weakening component handler. + */ +__weak void FW_Clear(FW_Handle_t *pHandle) +{ + qd_t V_null = {(int16_t)0, (int16_t)0}; +#ifdef NULL_PTR_CHECK_FLUX_WEAK + if (NULL == pHandle) + { + /* Mothing to do */ + } + else + { +#endif + PID_SetIntegralTerm(pHandle->pFluxWeakeningPID, (int32_t)0); + pHandle->AvVolt_qd = V_null; + pHandle->AvVoltAmpl = (int16_t)0; + pHandle->hIdRefOffset = (int16_t)0; +#ifdef NULL_PTR_CHECK_FLUX_WEAK + } +#endif +} + +/** + * @brief Computes Iqdref according to the flux weakening algorithm. + * As soon as the speed increases beyond the nominal one, flux weakening + * algorithm takes place and handles Idref value. Finally, accordingly + * with new Idref, a new Iqref saturation value is also computed and + * put into speed PI. this routine should be called during background task. + * @param pHandle pointer to flux weakening component handler. + * @param Iqdref current reference that will be + * modified, if needed, by the flux weakening algorithm. + * @retval qd_t Computed Iqdref. + */ +__weak qd_t FW_CalcCurrRef(FW_Handle_t *pHandle, qd_t Iqdref) +{ + qd_t IqdrefRet; +#ifdef NULL_PTR_CHECK_FLUX_WEAK + if (NULL == pHandle) + { + IqdrefRet.d = 0; + IqdrefRet.q = 0; + } + else + { +#endif + int32_t wIdRef; + int32_t wIqSatSq; + int32_t wIqSat; + int32_t wAux1; + int16_t Aux2; + uint32_t wVoltLimit_Ref; + int16_t hId_fw; + + /* Computation of the Id contribution coming from flux weakening algorithm */ + wVoltLimit_Ref = ((uint32_t)(pHandle->hFW_V_Ref) * pHandle->hMaxModule) / 1000U; + Aux2 = MCM_Modulus(pHandle->AvVolt_qd.q, pHandle->AvVolt_qd.d); + pHandle->AvVoltAmpl = Aux2; + + hId_fw = PI_Controller(pHandle->pFluxWeakeningPID, + (int32_t)wVoltLimit_Ref - (int32_t)Aux2); + + /* If the Id coming from flux weakening algorithm (Id_fw) is positive, keep + unchanged Idref, otherwise sum it to last Idref available when Id_fw was + zero */ + if (hId_fw >= (int16_t)0) + { + pHandle->hIdRefOffset = Iqdref.d; + wIdRef = (int32_t)Iqdref.d; + } + else + { + wIdRef = (int32_t)pHandle->hIdRefOffset + hId_fw; + } + + /* Saturate new Idref to prevent the rotor from being demagnetized */ + if (wIdRef < pHandle->hDemagCurrent) + { + wIdRef = pHandle->hDemagCurrent; + } + else + { + /* Nothing to do */ + } + + IqdrefRet.d = (int16_t)wIdRef; + + /* New saturation for Iqref */ + wIqSatSq = pHandle->wNominalSqCurr - (wIdRef * wIdRef); + wIqSat = MCM_Sqrt(wIqSatSq); + + /* Iqref saturation value used for updating integral term limitations of + speed PI */ + wAux1 = wIqSat * (int32_t)PID_GetKIDivisor(pHandle->pSpeedPID); + + PID_SetLowerIntegralTermLimit(pHandle->pSpeedPID, -wAux1); + PID_SetUpperIntegralTermLimit(pHandle->pSpeedPID, wAux1); + + /* Iqref saturation value used for updating integral term limitations of + speed PI */ + if (Iqdref.q > wIqSat) + { + IqdrefRet.q = (int16_t)wIqSat; + } + else if (Iqdref.q < -wIqSat) + { + IqdrefRet.q = -(int16_t)wIqSat; + } + else + { + IqdrefRet.q = Iqdref.q; + } +#ifdef NULL_PTR_CHECK_FLUX_WEAK + } +#endif + return (IqdrefRet); +} + +// cstat #ATH-shift-bounds +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Applies a low-pass filter on both Vqd voltage components. Filter + * bandwidth depends on hVqdLowPassFilterBW parameter. It shall + * be called during current controller task. + * @param pHandle pointer to flux weakening component handler. + * @param Vqd Voltage componets to be averaged. + */ +__weak void FW_DataProcess(FW_Handle_t *pHandle, qd_t Vqd) +{ +#ifdef NULL_PTR_CHECK_FLUX_WEAK + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int32_t wAux; + int32_t lowPassFilterBW = (int32_t)(pHandle->hVqdLowPassFilterBW) - (int32_t)1; + +#ifndef FULL_MISRA_C_COMPLIANCY_FLUX_WEAK + wAux = (int32_t)(pHandle->AvVolt_qd.q) * lowPassFilterBW; + wAux += Vqd.q; + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + pHandle->AvVolt_qd.q = (int16_t)(wAux >> pHandle->hVqdLowPassFilterBWLOG); + + wAux = (int32_t)(pHandle->AvVolt_qd.d) * lowPassFilterBW; + wAux += Vqd.d; + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + pHandle->AvVolt_qd.d = (int16_t)(wAux >> pHandle->hVqdLowPassFilterBWLOG); +#else + wAux = (int32_t)(pHandle->AvVolt_qd.q) * lowPassFilterBW; + wAux += Vqd.q; + + pHandle->AvVolt_qd.q = (int16_t)(wAux / (int32_t)(pHandle->hVqdLowPassFilterBW)); + + wAux = (int32_t)(pHandle->AvVolt_qd.d) * lowPassFilterBW; + wAux += Vqd.d; + + pHandle->AvVolt_qd.d = (int16_t)(wAux / (int32_t)pHandle->hVqdLowPassFilterBW); +#endif +#ifdef NULL_PTR_CHECK_FLUX_WEAK + } +#endif + return; +} + + +/** + * @brief Sets a new value for the voltage reference used by + * flux weakening algorithm. + * @param pHandle pointer to flux weakening component handler. + * @param hNewVref New target voltage value, expressed in tenth of percentage + * points of available voltage. + */ +__weak void FW_SetVref(FW_Handle_t *pHandle, uint16_t hNewVref) +{ +#ifdef NULL_PTR_CHECK_FLUX_WEAK + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hFW_V_Ref = hNewVref; +#ifdef NULL_PTR_CHECK_FLUX_WEAK + } +#endif +} + +/** + * @brief Returns the present value of target voltage used by flux + * weakening algorihtm. + * @param pHandle pointer to flux weakening component handler. + * @retval int16_t Present target voltage value expressed in tenth of + * percentage points of available voltage. + */ +__weak uint16_t FW_GetVref(FW_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_FLUX_WEAK + return ((NULL == pHandle) ? 0U : pHandle->hFW_V_Ref); +#else + return (pHandle->hFW_V_Ref); +#endif +} + +/** + * @brief Returns the present value of voltage actually used by flux + * weakening algorihtm. + * @param pHandle pointer to flux weakening component handler. + * @retval int16_t Present averaged phase stator voltage value, expressed + * in s16V (0-to-peak), where + * PhaseVoltage(V) = [PhaseVoltage(s16A) * Vbus(V)] /[sqrt(3) *32767]. + */ +__weak int16_t FW_GetAvVAmplitude(FW_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_FLUX_WEAK + return ((NULL == pHandle) ? 0 : pHandle->AvVoltAmpl); +#else + return (pHandle->AvVoltAmpl); +#endif +} + +/** + * @brief Returns the present voltage actually used by flux + * weakening algorihtm as percentage of available voltage. + * @param pHandle pointer to flux weakening component handler. + * @retval uint16_t Present averaged phase stator voltage value, expressed in + * tenth of percentage points of available voltage. + */ +__weak uint16_t FW_GetAvVPercentage(FW_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_FLUX_WEAK + return ((NULL == pHandle) ? 0U + : (uint16_t)((uint32_t)(pHandle->AvVoltAmpl) * 1000U / + (uint32_t)(pHandle->hMaxModule))); +#else + return ((uint16_t)((uint32_t)(pHandle->AvVoltAmpl) * 1000U / + (uint32_t)(pHandle->hMaxModule))); +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/flux_weakening_ctrl.h b/src/firmware/motor/mcsdk/flux_weakening_ctrl.h new file mode 100644 index 0000000000..a1c302b625 --- /dev/null +++ b/src/firmware/motor/mcsdk/flux_weakening_ctrl.h @@ -0,0 +1,141 @@ +/** + ****************************************************************************** + * @file flux_weakening_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides all definitions and functions prototypes for the + * Flux Weakening Control component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup FluxWeakeningCtrl + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FLUXWEAKENINGCTRL_H +#define FLUXWEAKENINGCTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" +#include "pid_regulator.h" + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup FluxWeakeningCtrl + * @{ + */ + + /** + * @brief Flux Weakening Control Component handle structure + */ + typedef struct + { + PID_Handle_t *pFluxWeakeningPID; /**< @brief PI object used for flux weakening */ + PID_Handle_t *pSpeedPID; /**< @brief PI object used for speed control */ + uint16_t hFW_V_Ref; /**< @brief Voltage reference, + expressed in tenth ofpercentage points */ + qd_t AvVolt_qd; /**< @brief Average stator voltage in qd + reference frame */ + int16_t AvVoltAmpl; /**< @brief Average stator voltage amplitude */ + int16_t hIdRefOffset; /**< @brief Id reference offset */ + uint16_t hMaxModule; /**< @brief Circle limitation maximum allowed module */ + + uint16_t hDefaultFW_V_Ref; /**< @brief Default flux weakening voltage reference, + tenth of percentage points*/ + int16_t hDemagCurrent; /**< @brief Demagnetization current in s16A: + Current(Amp) = [Current(s16A) * Vdd micro]/ + [65536 * Rshunt * Aop] */ + int32_t wNominalSqCurr; /**< @brief Squared motor nominal current in (s16A)^2 + where: + Current(Amp) = [Current(s16A) * Vdd micro]/ + [65536 * Rshunt * Aop] */ + uint16_t hVqdLowPassFilterBW; /**< @brief Use this parameter to configure the Vqd + first order software filter bandwidth. + hVqdLowPassFilterBW = FOC_CurrController + call rate [Hz]/ FilterBandwidth[Hz] in + case FULL_MISRA_COMPLIANCY is defined. + On the contrary, if FULL_MISRA_COMPLIANCY + is not defined, hVqdLowPassFilterBW is + equal to log with base two of previous + definition */ + uint16_t hVqdLowPassFilterBWLOG; /**< @brief hVqdLowPassFilterBW expressed as + power of 2. E.g. if gain divisor is 512 the + value must be 9 because 2^9 = 512 */ + } FW_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /** + * Initializes flux weakening component handler. + */ + void FW_Init(FW_Handle_t *pHandle, PID_Handle_t *pPIDSpeed, + PID_Handle_t *pPIDFluxWeakeningHandle); + + /** + * Clears the flux weakening internal variables + */ + void FW_Clear(FW_Handle_t *pHandle); + + /** + * Computes Iqdref according the flux weakening algorithm. + */ + qd_t FW_CalcCurrRef(FW_Handle_t *pHandle, qd_t Iqdref); + + /** + * Applies a low-pass filter on both Vqd voltage components. + */ + void FW_DataProcess(FW_Handle_t *pHandle, qd_t Vqd); + + /** + * Sets a new value for the voltage reference used by + * flux weakening algorithm. + */ + void FW_SetVref(FW_Handle_t *pHandle, uint16_t hNewVref); + + /** + * Returns the present value of target voltage used by flux + * weakening algorihtm. + */ + uint16_t FW_GetVref(FW_Handle_t *pHandle); + + /** + * Returns the present value of voltage actually used by flux + * weakening algorihtm. + */ + int16_t FW_GetAvVAmplitude(FW_Handle_t *pHandle); + + /** + * Returns the measure of present voltage actually used by flux + * weakening algorihtm as percentage of available voltage. + */ + uint16_t FW_GetAvVPercentage(FW_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* FLUXWEAKENINGCTRL_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/gap_gate_driver_ctrl.c b/src/firmware/motor/mcsdk/gap_gate_driver_ctrl.c new file mode 100644 index 0000000000..68997053b7 --- /dev/null +++ b/src/firmware/motor/mcsdk/gap_gate_driver_ctrl.c @@ -0,0 +1,938 @@ +/** + ****************************************************************************** + * @file gap_gate_driver_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the GAP component of the Motor Control SDK that provides support + * the STGAPxx galvanically isolated gate drivers family. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup GAP_GATE_DRIVER_CTRL + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/gap_gate_driver_ctrl.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_spi.h" + +/** + * @addtogroup MCSDK + * @{ + */ + +/** + * @defgroup GAP_GATE_DRIVER_CTRL STGAP1x controller + * @brief A component to interface with the configuration and diagnostic + * features of STGAP1x gate drivers through SPI + * + * The STGAP1x gate drivers family offers galvanically isolated gate drivers + * for high-power MOSFET and IGBT applications. These devices provide advanced + * configuration and diagnostic features that are accessible through their SPI + * interface. Several STGAP1x devices can be daisy-chained on an SPI bus. + * + * The STGAP1x controller component allows for configuring any number of STGAP1x + * devices daisy-chained on an SPI bus and for accessing their diagnostic + * registers. + * + * The GAP driver configuration is performed at the first steps of the MCboot(). + * In a MCSDK project up to seven gate drivers might be configured: + * + * 1 brake STGAP1AS_BRAKE + * + * 3 high and low side PWM signals + STGAP1AS_UH, + STGAP1AS_UL, + STGAP1AS_VH, + STGAP1AS_VL, + STGAP1AS_WH, + STGAP1AS_WL. + * + * More information on STGAP1x can be find on st.com: [Isolated Gate + Drivers](https://www.st.com/en/motor-drivers/isolated-gate-drivers.html) + * + * @{ + */ + +/* Private defines -----------------------------------------------------------*/ +#define GAP_STARTCONFIG \ + 0x2A /**< @brief CRC data computation value to start GAP driver configuration. */ +#define GAP_STOPCONFIG \ + 0x3A /**< @brief CRC data computation value to stop GAP driver configuration. */ +#define GAP_WRITEREG \ + 0x80 /**< @brief CRC data computation value for writing register. \ + */ +#define GAP_READREG 0xA0 /**< @brief CRC data computation value for reading register. */ +#define GAP_RESETREG 0xC0 /**< @brief CRC data computation value to reset a register. */ +#define GAP_RESETSTATUS \ + 0xD0 /**< @brief CRC data computation value to reset a status register. */ +#define GAP_GLOBALRESET \ + 0xEA /**< @brief CRC data computation value to reset GAP driver. */ +#define GAP_SLPEEP \ + 0xF5 /**< @brief CRC data computation value to set GAP driver in sleep mode. */ +#define GAP_NOP 0x00 /**< @brief CRC data computation value for no operation. */ + +#define GAP_ERROR_CODE_FROM_DEVICE_MASK \ + (uint32_t)(0xFF000000) /**< @brief ERROR code mask */ + +#define WAITTIME 5000 /**< @brief 860u wait time duration. */ +#define WAITTRCHK 50 /**< @brief 8.6u wait time duration. */ +#define WAITTSENSECHK 50 /**< @brief 8.6u wait time duration. */ +#define WAITTGCHK 50 /**< @brief 8.6u wait time duration. */ +#define WAITTDESATCHK 50 /**< @brief 8.6u wait time duration. */ + +/* Global variables ----------------------------------------------------------*/ +static void GAP_SD_Deactivate(GAP_Handle_t *pHandle_t); +static void GAP_SD_Activate(GAP_Handle_t *pHandle_t); +static void GAP_CS_Deactivate(GAP_Handle_t *pHandle_t); +static void GAP_CS_Activate(GAP_Handle_t *pHandle_t); +static uint16_t GAP_SPI_Send(GAP_Handle_t *pHandle_t, uint16_t value); + +/** + * @brief Checks errors of GAP devices + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @param errorNow Buffer of returned bitfields containing error flags + * coming from GAP device that are currently active.\n + * The buffer have to be provided from the caller. + * @param errorOccurred Buffer of returned bitfields containing error flags + * coming from GAP device that are over.\n + * The buffer have to be provided from the caller. + * @retval bool It returns false if an error occurs, otherwise return true. + */ +__weak bool GAP_CheckErrors(GAP_Handle_t *pHandle, uint32_t *error_now, + uint32_t *error_occurred) +{ + bool ret_val = false; + uint32_t errorFromDevices[MAX_DEVICES_NUMBER]; + + if ((error_now) && (error_occurred)) + { + uint8_t index1, index2; + uint8_t ret_read[MAX_DEVICES_NUMBER]; + + // /* If current error is device not programmable try to re-configure before + // read the status registers */ + // if ((pDVars->wGAP_ErrorsNow[0] & GAP_ERROR_CODE_DEVICES_NOT_PROGRAMMABLE) || + // (pDVars->wGAP_ErrorsNow[0] & GAP_ERROR_CODE_SPI_CRC)) + // { + // if (GAP_Configuration(pHandle)) + // { + // pDVars->wGAP_ErrorsNow[0] &= ~GAP_ERROR_CODE_DEVICES_NOT_PROGRAMMABLE; + // pDVars->wGAP_ErrorsNow[0] &= ~GAP_ERROR_CODE_SPI_CRC; + // } + // } + + + index2 = pHandle->DeviceNum; + ret_val = GAP_ReadRegs(pHandle, ret_read, STATUS1); + for (index1 = 0; index1 < index2; index1++) + { + errorFromDevices[index1] = (ret_read[index1] << 16); + } + ret_val = GAP_ReadRegs(pHandle, ret_read, STATUS2); + for (index1 = 0; index1 < index2; index1++) + { + /* Clear GATE bit from STATUS2 - no error if 1 */ + ret_read[index1] &= 0xFE; + errorFromDevices[index1] |= (ret_read[index1] << 8); + } + ret_val = GAP_ReadRegs(pHandle, ret_read, STATUS3); + for (index1 = 0; index1 < index2; index1++) + { + errorFromDevices[index1] |= ret_read[index1]; + } + + for (index1 = 0; index1 < index2; index1++) + { + pHandle->GAP_ErrorsNow[index1] &= GAP_ERROR_CODE_FROM_DEVICE_MASK; + pHandle->GAP_ErrorsNow[index1] |= errorFromDevices[index1]; + pHandle->GAP_ErrorsOccurred[index1] |= pHandle->GAP_ErrorsNow[index1]; + error_now[index1] = pHandle->GAP_ErrorsNow[index1]; + error_occurred[index1] = pHandle->GAP_ErrorsOccurred[index1]; + } + } + return ret_val; +} + +/** + * @brief Clears the fault state of GAP devices. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @retval none. + */ +__weak void GAP_FaultAck(GAP_Handle_t *pHandle) +{ + uint8_t index1, index2; + uint16_t value; + + GAP_SD_Activate(pHandle); + value = GAP_CRCCalculate(GAP_RESETSTATUS, 0xFF); + GAP_CS_Activate(pHandle); + index2 = pHandle->DeviceNum; + + for (index1 = 0; index1 < index2; index1++) + { + GAP_SPI_Send(pHandle, value); + } + GAP_CS_Deactivate(pHandle); + GAP_SD_Deactivate(pHandle); + wait(WAITTIME); + + for (index1 = 0; index1 < index2; index1++) + { + pHandle->GAP_ErrorsOccurred[index1] = GAP_ERROR_CLEAR; + } +} + +/** + * @brief Programs the GAP devices with the settled parameters. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @retval bool It returns false if at least one device is not programmable, + * otherwise return true. + */ +__weak bool GAP_Configuration(GAP_Handle_t *pHandle) +{ + bool ret_val; + + LL_SPI_Enable(pHandle->SPIx); + + /* Configure devices with settled parameters */ + GAP_DevicesConfiguration(pHandle); + + /* Verify if device has been programmed */ + ret_val = GAP_IsDevicesProgrammed(pHandle); + + if (!ret_val) + { + /* At least one device is not programmable */ + pHandle->GAP_ErrorsNow[0] |= GAP_ERROR_CODE_DEVICES_NOT_PROGRAMMABLE; + pHandle->GAP_ErrorsOccurred[0] |= GAP_ERROR_CODE_DEVICES_NOT_PROGRAMMABLE; + } + return ret_val; +} + +/** + * @brief Checks if the GAP devices are programmed with the settled parameters. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @retval True if the GAP devices are already programmed with the settled + * parameters. + */ +__weak bool GAP_IsDevicesProgrammed(GAP_Handle_t *pHandle) +{ + bool ret_val = true; + uint8_t index1, index2 = pHandle->DeviceNum; + uint8_t read_reg_values[MAX_DEVICES_NUMBER]; + + GAP_ReadRegs(pHandle, read_reg_values, CFG1); + + for (index1 = 0; index1 < index2; index1++) + { + if ((pHandle->DeviceParams[index1].CFG1 & CFG1_REG_MASK) != + read_reg_values[index1]) + { + ret_val = false; + break; + } + } + + if (ret_val) + { + GAP_ReadRegs(pHandle, read_reg_values, CFG2); + for (index1 = 0; index1 < index2; index1++) + { + if ((pHandle->DeviceParams[index1].CFG2 & CFG2_REG_MASK) != + read_reg_values[index1]) + { + ret_val = false; + break; + } + } + } + if (ret_val) + { + GAP_ReadRegs(pHandle, read_reg_values, CFG3); + for (index1 = 0; index1 < index2; index1++) + { + if ((pHandle->DeviceParams[index1].CFG3 & CFG3_REG_MASK) != + read_reg_values[index1]) + { + ret_val = false; + break; + } + } + } + if (ret_val) + { + GAP_ReadRegs(pHandle, read_reg_values, CFG4); + for (index1 = 0; index1 < index2; index1++) + { + if ((pHandle->DeviceParams[index1].CFG4 & CFG4_REG_MASK) != + read_reg_values[index1]) + { + ret_val = false; + break; + } + } + } + if (ret_val) + { + GAP_ReadRegs(pHandle, read_reg_values, CFG5); + for (index1 = 0; index1 < index2; index1++) + { + if ((pHandle->DeviceParams[index1].CFG5 & CFG5_REG_MASK) != + read_reg_values[index1]) + { + ret_val = false; + break; + } + } + } + if (ret_val) + { + GAP_ReadRegs(pHandle, read_reg_values, DIAG1); + for (index1 = 0; index1 < index2; index1++) + { + if ((pHandle->DeviceParams[index1].DIAG1 & DIAG1_REG_MASK) != + read_reg_values[index1]) + { + ret_val = false; + break; + } + } + } + if (ret_val) + { + GAP_ReadRegs(pHandle, read_reg_values, DIAG2); + for (index1 = 0; index1 < index2; index1++) + { + if ((pHandle->DeviceParams[index1].DIAG2 & DIAG2_REG_MASK) != + read_reg_values[index1]) + { + ret_val = false; + break; + } + } + } + return ret_val; +} + +/** + * @brief Programs the GAP devices with the settled parameters. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @retval bool It returns false if an error occurs, otherwise return true. + */ +__weak bool GAP_DevicesConfiguration(GAP_Handle_t *pHandle) +{ + bool ret_val = true; + uint8_t index1, DeviceNum = pHandle->DeviceNum; + uint8_t write_reg_values[MAX_DEVICES_NUMBER]; + + GAP_StartConfig(pHandle); + + /* Global Reset before programming */ + GAP_GlobalReset(pHandle); + + for (index1 = 0; index1 < DeviceNum; index1++) + { + write_reg_values[index1] = pHandle->DeviceParams[index1].CFG1; + } + ret_val = GAP_WriteRegs(pHandle, write_reg_values, CFG1); + + if (ret_val) + { + for (index1 = 0; index1 < DeviceNum; index1++) + { + write_reg_values[index1] = pHandle->DeviceParams[index1].CFG2; + } + ret_val = GAP_WriteRegs(pHandle, write_reg_values, CFG2); + } + + if (ret_val) + { + for (index1 = 0; index1 < DeviceNum; index1++) + { + write_reg_values[index1] = pHandle->DeviceParams[index1].CFG3; + } + ret_val = GAP_WriteRegs(pHandle, write_reg_values, CFG3); + } + if (ret_val) + { + for (index1 = 0; index1 < DeviceNum; index1++) + { + write_reg_values[index1] = pHandle->DeviceParams[index1].CFG4; + } + ret_val = GAP_WriteRegs(pHandle, write_reg_values, CFG4); + } + if (ret_val) + { + for (index1 = 0; index1 < DeviceNum; index1++) + { + write_reg_values[index1] = pHandle->DeviceParams[index1].CFG5; + } + ret_val = GAP_WriteRegs(pHandle, write_reg_values, CFG5); + } + if (ret_val) + { + for (index1 = 0; index1 < DeviceNum; index1++) + { + write_reg_values[index1] = pHandle->DeviceParams[index1].DIAG1; + } + ret_val = GAP_WriteRegs(pHandle, write_reg_values, DIAG1); + } + if (ret_val) + { + for (index1 = 0; index1 < DeviceNum; index1++) + { + write_reg_values[index1] = pHandle->DeviceParams[index1].DIAG2; + } + ret_val = GAP_WriteRegs(pHandle, write_reg_values, DIAG2); + } + + GAP_StopConfig(pHandle); + + /* Fault reset */ + GAP_FaultAck(pHandle); + + return ret_val; +} + +/** + * @brief Calculates CRC from data and creates 16bit value with data as MSB and + * CRC as LSB. + * @param data 8bit value used to calculate CRC. + * @retval uint16_t It returns the 16bit value with data as MSB and + * CRC as LSB. + */ +__weak uint16_t GAP_CRCCalculate(uint8_t data, uint8_t crc_initial_value) +{ + uint8_t crc = crc_initial_value; + uint8_t poly = 0x07; + uint8_t crc_temp; + uint8_t crctab[8]; + uint8_t index1, index2; + + uint16_t value; + value = data; + value <<= 8; + + for (index2 = 0; index2 < 8; index2++) + { + crctab[index2] = (crc >> index2) & 0x1; + } + + for (index2 = 0; index2 < 8; index2++) + { + crc_temp = (crctab[7] << 7) + (crctab[6] << 6) + (crctab[5] << 5) + + (crctab[4] << 4) + (crctab[3] << 3) + (crctab[2] << 2) + + (crctab[1] << 1) + (crctab[0]); + crctab[0] = ((data >> (7 - index2)) & 0x1) ^ crctab[7]; + + for (index1 = 1; index1 < 8; index1++) + { + crctab[index1] = (crctab[0] & ((poly >> index1) & 0x1)) ^ + ((crc_temp >> (index1 - 1)) & 0x1); + } + } + + crc = (crctab[7] << 7) + (crctab[6] << 6) + (crctab[5] << 5) + (crctab[4] << 4) + + (crctab[3] << 3) + (crctab[2] << 2) + (crctab[1] << 1) + (crctab[0] << 0); + crc ^= 0xFF; + + value |= crc; + return value; +} + +/** + * @brief Verifies the CRC from dataIn and extracts the 8bit data value (out). + * @param out Reference for the extracted 8bit data value. + * @param dataIn 16bit value with data as MSB and CRC as LSB. + * @retval bool It returns true if CRC is correct, false otherwise. + */ +__weak bool GAP_CRCCheck(uint8_t *out, uint16_t data_in) +{ + bool ret_val = false; + uint8_t data = (uint8_t)(data_in >> 8); + uint8_t received_crc = (uint8_t)(data_in); + uint8_t crc = (uint8_t)(GAP_CRCCalculate(data, 0xFF)) ^ 0xFF; + + if (crc == received_crc) + { + *out = data; + ret_val = true; + } + return ret_val; +} + +/** + * @brief Waits a time interval proportional to count. + * @param count Number of count to be waited. + * @retval none + */ +__weak void wait(uint16_t count) +{ + volatile uint16_t wait_cnt; + + for (wait_cnt = 0; wait_cnt < count; wait_cnt++) + { + /* Nothing to do */ + } +} + +/** + * @brief Returns the register mask starting from it address. + * @param reg Register address GAP_Registers_Handle_t. + * @retval uint8_t Mask to be and-ed bit wise to data to filter it. + */ +__weak uint8_t GAP_RegMask(GAP_Registers_Handle_t reg) +{ + uint8_t ret_val; + switch (reg) + { + case CFG1: + { + ret_val = CFG1_REG_MASK; + } + break; + case CFG2: + { + ret_val = CFG2_REG_MASK; + } + break; + case CFG3: + { + ret_val = CFG3_REG_MASK; + } + break; + case CFG4: + { + ret_val = CFG4_REG_MASK; + } + break; + case CFG5: + { + ret_val = CFG5_REG_MASK; + } + break; + case STATUS1: + { + ret_val = STATUS1_REG_MASK; + } + break; + case STATUS2: + { + ret_val = STATUS2_REG_MASK; + } + break; + case STATUS3: + { + ret_val = STATUS3_REG_MASK; + } + break; + case TEST1: + { + ret_val = TEST1_REG_MASK; + } + break; + case DIAG1: + { + ret_val = DIAG1_REG_MASK; + } + break; + case DIAG2: + { + ret_val = DIAG2_REG_MASK; + } + break; + default: + { + ret_val = 0x00; + } + break; + } + return ret_val; +} + +/** + * @brief Reads all data in the daisy chain related to register reg. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @param pDataRead Pointer to the buffer in which will be stored the readed + * data. The buffer have to be provided from the caller. + * @param reg Register to be read. It must be one of the register defined in + * GAP_Registers_Handle_t. + * @retval bool It returns false if an error occurs, otherwise return true. + */ +__weak bool GAP_ReadRegs(GAP_Handle_t *pHandle, uint8_t *pDataRead, + GAP_Registers_Handle_t reg) +{ + bool ret_val = false; + uint8_t index1; + uint8_t device; + uint8_t data; + uint16_t value; + + if (pDataRead) + { + value = GAP_CRCCalculate(GAP_READREG | reg, 0xFF); + GAP_CS_Activate(pHandle); + + for (index1 = 0; index1 < pHandle->DeviceNum; index1++) + { + GAP_SPI_Send(pHandle, value); + } + + GAP_CS_Deactivate(pHandle); + wait(WAITTIME); + value = GAP_CRCCalculate(GAP_NOP, 0xFF); + GAP_CS_Activate(pHandle); + + ret_val = true; + + for (index1 = 0; index1 < pHandle->DeviceNum; index1++) + { + device = pHandle->DeviceNum - index1 - 1; + + if (pHandle->DeviceParams[device].CFG1 & GAP_CFG1_CRC_SPI) + { + if (GAP_CRCCheck(&data, GAP_SPI_Send(pHandle, value))) + { + pDataRead[device] = data & GAP_RegMask(reg); + } + else + { + pDataRead[device] = 0x00; + pHandle->GAP_ErrorsNow[0] |= GAP_ERROR_CODE_SPI_CRC; + pHandle->GAP_ErrorsOccurred[0] |= GAP_ERROR_CODE_SPI_CRC; + ret_val = false; + } + } + else + { + pDataRead[device] = + (uint8_t)(GAP_SPI_Send(pHandle, value) >> 8) & GAP_RegMask(reg); + } + } + GAP_CS_Deactivate(pHandle); + } + return ret_val; +} + +/** + * @brief Switches the device to the configuration mode allowing writing configuration + * values in configuration registers. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @retval none. + */ +__weak void GAP_StartConfig(GAP_Handle_t *pHandle) +{ + uint8_t index; + uint16_t value; + + GAP_SD_Activate(pHandle); + + value = GAP_CRCCalculate(GAP_STARTCONFIG, 0xFF); + GAP_CS_Activate(pHandle); + + for (index = 0; index < pHandle->DeviceNum; index++) + { + GAP_SPI_Send(pHandle, value); + } + GAP_CS_Deactivate(pHandle); + wait(WAITTIME); +} + +/** + * @brief Quits the configuration mode and make all changes effective. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @retval none. + */ +__weak void GAP_StopConfig(GAP_Handle_t *pHandle) +{ + uint8_t index; + uint16_t value; + + value = GAP_CRCCalculate(GAP_STOPCONFIG, 0xFF); + GAP_CS_Activate(pHandle); + + for (index = 0; index < pHandle->DeviceNum; index++) + { + GAP_SPI_Send(pHandle, value); + } + GAP_CS_Deactivate(pHandle); + wait(WAITTIME); + GAP_SD_Deactivate(pHandle); +} + +/** + * @brief Writes data in the daisy chain into the register reg. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @param pDataWrite Pointer to the buffer in which are stored the data + * to be written in the register reg. The buffer have to be provided + * from the caller. + * @param reg Register to be write. It must be one of the register defined in + * GAP_Registers_Handle_t. + * @retval bool It returns false if an error occurs, otherwise return true. + */ +__weak bool GAP_WriteRegs(GAP_Handle_t *pHandle, uint8_t *pDataWrite, + GAP_Registers_Handle_t reg) +{ + bool ret_val = false; + + if (pDataWrite) + { + uint8_t crc; + uint8_t index; + uint16_t value; + + value = GAP_CRCCalculate(GAP_WRITEREG | reg, 0xFF); + crc = (uint8_t)(value); + GAP_CS_Activate(pHandle); + + for (index = 0; index < pHandle->DeviceNum; index++) + { + GAP_SPI_Send(pHandle, value); + } + GAP_CS_Deactivate(pHandle); + wait(WAITTIME); + + GAP_CS_Activate(pHandle); + ret_val = true; + + for (index = 0; index < pHandle->DeviceNum; index++) + { + value = GAP_CRCCalculate(pDataWrite[index], crc ^ 0xFF); + GAP_SPI_Send(pHandle, value); + } + + GAP_CS_Deactivate(pHandle); + wait(WAITTIME); + } + return ret_val; +} + +/** + * @brief Resets all the registers to the default and releases all the failure flag. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @retval none. + */ +__weak void GAP_GlobalReset(GAP_Handle_t *pHandle) +{ + uint8_t index; + uint16_t value; + + value = GAP_CRCCalculate(GAP_GLOBALRESET, 0xFF); + GAP_CS_Activate(pHandle); + + for (index = 0; index < pHandle->DeviceNum; index++) + { + GAP_SPI_Send(pHandle, value); + } + GAP_CS_Deactivate(pHandle); + wait(WAITTIME); +} + +/** + * @brief Resets selected status register. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @param reg Register to be reset. It must be one of the STATUS register + * defined in GAP_Registers_Handle_t. + * @retval bool It returns false if an error occurs, otherwise return true. + */ +__weak bool GAP_ResetStatus(GAP_Handle_t *pHandle, GAP_Registers_Handle_t reg) +{ + bool ret_val = false; + uint8_t index; + uint16_t value; + GAP_SD_Activate(pHandle); + value = GAP_CRCCalculate(GAP_RESETREG | reg, 0xFF); + GAP_CS_Activate(pHandle); + for (index = 0; index < pHandle->DeviceNum; index++) + { + GAP_SPI_Send(pHandle, value); + } + GAP_CS_Deactivate(pHandle); + GAP_SD_Deactivate(pHandle); + return ret_val; +} + +/** + * @brief It performs the selected test on each GAP devices. + * @attention pHandle function should be called just in IDLE state. + * @param pHandle Handle of the GAP component GAP_Handle_t. + * @param testMode Test mode to be executed. It shall be one of the + * test modes present in the GAP_TestMode_t. + * @retval bool It returns true if an error occurs, otherwise return false. + */ +__weak bool GAP_Test(GAP_Handle_t *pHandle, GAP_TestMode_t testMode) +{ + bool ret_val = false; + bool invertResult = false; + + uint8_t testModeData; + uint8_t clr[MAX_DEVICES_NUMBER]; + uint8_t data[MAX_DEVICES_NUMBER]; + uint8_t index1, index2 = pHandle->DeviceNum; + uint8_t statusMask; + uint16_t wait_cnt; + + switch (testMode) + { + case GOFF_CHK: + { + testModeData = GAP_TEST1_GOFFCHK; + wait_cnt = WAITTGCHK; + statusMask = GAP_STATUS1_DESAT; + } + break; + case GON_CHK: + { + testModeData = GAP_TEST1_GONCHK; + wait_cnt = WAITTGCHK; + statusMask = GAP_STATUS1_TSD; + } + break; + case GAP_TEST1_DESCHK: + { + testModeData = DESAT_CHK; + wait_cnt = WAITTDESATCHK; + statusMask = GAP_STATUS1_DESAT; + invertResult = true; + } + break; + case SENSE_RESISTOR_CHK: + { + testModeData = GAP_TEST1_RCHK; + wait_cnt = WAITTRCHK; + statusMask = GAP_STATUS1_SENSE; + } + break; + case SENSE_COMPARATOR_CHK: + { + testModeData = GAP_TEST1_SNSCHK; + wait_cnt = WAITTSENSECHK; + statusMask = GAP_STATUS1_SENSE; + invertResult = true; + } + break; + default: + { + ret_val = true; + } + break; + } + + for (index1 = 0; index1 < index2; index1++) + { + data[index1] = testModeData; + clr[index1] = 0x00; + } + GAP_WriteRegs(pHandle, data, TEST1); + wait(wait_cnt); + GAP_ReadRegs(pHandle, data, STATUS1); + /* Clear TEST1 regs */ + GAP_WriteRegs(pHandle, clr, TEST1); + /* Clear STATUS1 regs */ + GAP_ResetStatus(pHandle, STATUS1); + + for (index1 = 0; index1 < index2; index1++) + { + if (invertResult) + { + if ((data[index1] & statusMask) == 0) + { + ret_val = true; + } + } + else + { + if ((data[index1] & statusMask) != 0) + { + ret_val = true; + } + } + } + + return ret_val; +} + +/** + * @brief This function sends a 16bit value through the configured SPI and + * returns the 16-bit value received during communication. + * @param pHandle_t Handle of the GAP component GAP_Handle_t. + * @param value Value to be sent through SPI. + * @retval uint16_t Received 16bit value. + */ +uint16_t GAP_SPI_Send(GAP_Handle_t *pHandle_t, uint16_t value) +{ + SPI_TypeDef *SPIx = pHandle_t->SPIx; + /* Wait for SPI Tx buffer empty */ + while (LL_SPI_IsActiveFlag_TXE(SPIx) == 0) + ; + /* Send SPI data */ + LL_SPI_TransmitData16(SPIx, value); + /* Wait for SPIz data reception */ + while (LL_SPI_IsActiveFlag_RXNE(SPIx) == 0) + ; + /* Read SPIz received data */ + return LL_SPI_ReceiveData16(SPIx); +} + +/** + * @brief Deactivates SD pin. + * @param pHandle_t Handle of the GAP component GAP_Handle_t. + * @retval none. + */ +void GAP_SD_Deactivate(GAP_Handle_t *pHandle_t) +{ + LL_GPIO_SetOutputPin(pHandle_t->NSDPort, pHandle_t->NSDPin); +} + +/** + * @brief Activates SD pin. + * @param pHandle_t Handle of the GAP component GAP_Handle_t. + * @retval none. + */ +void GAP_SD_Activate(GAP_Handle_t *pHandle_t) +{ + LL_GPIO_ResetOutputPin(pHandle_t->NSDPort, pHandle_t->NSDPin); +} + +/** + * @brief Deactivates CS pin. + * @param pHandle_t Handle of the GAP component GAP_Handle_t. + * @retval none. + */ +void GAP_CS_Deactivate(GAP_Handle_t *pHandle_t) +{ + LL_GPIO_SetOutputPin(pHandle_t->NCSPort, pHandle_t->NCSPin); +} + +/** + * @brief Activates CS pin. + * @param pHandle_t Handle of the GAP component GAP_Handle_t. + * @retval none. + */ +void GAP_CS_Activate(GAP_Handle_t *pHandle_t) +{ + LL_GPIO_ResetOutputPin(pHandle_t->NCSPort, pHandle_t->NCSPin); +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/gap_gate_driver_ctrl.h b/src/firmware/motor/mcsdk/gap_gate_driver_ctrl.h new file mode 100644 index 0000000000..d476c309ed --- /dev/null +++ b/src/firmware/motor/mcsdk/gap_gate_driver_ctrl.h @@ -0,0 +1,543 @@ +/** + ****************************************************************************** + * @file gap_gate_driver_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * GAP component of the Motor Control SDK that provides support + * the STGAPxx galvanically isolated gate drivers family. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup GAP_GATE_DRIVER_CTRL + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GAP_GATE_DRIVER_CTR_H +#define __GAP_GATE_DRIVER_CTR_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/mc_type.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup GAP_GATE_DRIVER_CTRL + * @{ + */ + +#define GPIO_NoRemap_SPI ((uint32_t)(0)) +#define MAX_DEVICES_NUMBER 7 /**< @brief Number of GAP used in the project. */ + +#define CFG1_REG_MASK (uint8_t)(0xFF) /**< @brief Data mask for CFG1 register. */ +#define CFG2_REG_MASK (uint8_t)(0xFF) /**< @brief Data mask for CFG2 register. */ +#define CFG3_REG_MASK (uint8_t)(0xFF) /**< @brief Data mask for CFG3 register. */ +#define CFG4_REG_MASK (uint8_t)(0x3F) /**< @brief Data mask for CFG4 register. */ +#define CFG5_REG_MASK (uint8_t)(0x0F) /**< @brief Data mask for CFG5 register. */ +#define STATUS1_REG_MASK (uint8_t)(0xFF) /**< @brief Data mask for STATUS1 register. */ +#define STATUS2_REG_MASK (uint8_t)(0x06) /**< @brief Data mask for STATUS2 register. */ +#define STATUS3_REG_MASK (uint8_t)(0x1F) /**< @brief Data mask for STATUS3 register. */ +#define TEST1_REG_MASK (uint8_t)(0x1F) /**< @brief Data mask for TEST1 register. */ +#define DIAG1_REG_MASK (uint8_t)(0xFF) /**< @brief Data mask for DIAG1 register. */ +#define DIAG2_REG_MASK (uint8_t)(0xFF) /**< @brief Data mask for DIAG2 register. */ + +#define GAP_ERROR_CLEAR (uint32_t)(0x00000000) /**< @brief No ERROR occured. */ +#define GAP_ERROR_CODE_UVLOD \ + (uint32_t)(0x00000001) /**< @brief Under Voltage Lockout ERROR occured. */ +#define GAP_ERROR_CODE_OVLOD \ + (uint32_t)(0x00000002) /**< @brief Over Voltage Lockout ERROR occured. */ +#define GAP_ERROR_CODE_REGERRL \ + (uint32_t)(0x00000004) /**< @brief Configuration procedure occured. */ +#define GAP_ERROR_CODE_SPI_ERR \ + (uint32_t)(0x00000008) /**< @brief SPI communication ERROR occured. */ +#define GAP_ERROR_CODE_DT_ERR \ + (uint32_t)(0x00000010) /**< @brief Deadtime ERROR occured. */ +#define GAP_ERROR_CODE_CFG \ + (uint32_t)(0x00000020) /**< @brief Configuration ERROR occured. */ +#define GAP_ERROR_CODE_GATE \ + (uint32_t)(0x00000100) /**< @brief GATE path ERROR occured. \ + */ +#define GAP_ERROR_CODE_ASC \ + (uint32_t)(0x00000200) /**< @brief Asynchronous stop command ERROR occured. */ +#define GAP_ERROR_CODE_REGERRR \ + (uint32_t)(0x00000400) /**< @brief Configuration procedure occured. */ +#define GAP_ERROR_CODE_TWN \ + (uint32_t)(0x00010000) /**< @brief Temperature warning threshold ERROR occured. */ +#define GAP_ERROR_CODE_TSD \ + (uint32_t)(0x00020000) /**< @brief Temperature threshold ERROR occured. */ +#define GAP_ERROR_CODE_UVLOL \ + (uint32_t)(0x00040000) /**< @brief Under Voltage Lockout on VL ERROR occured. */ +#define GAP_ERROR_CODE_UVLOH \ + (uint32_t)(0x00080000) /**< @brief Under Voltage Lockout on VH ERROR occured. */ +#define GAP_ERROR_CODE_SENSE \ + (uint32_t)(0x00100000) /**< @brief sensor SENS voltage ERROR occured. */ +#define GAP_ERROR_CODE_DESAT \ + (uint32_t)(0x00200000) /**< @brief sensor Desaturation protection ERROR occured. */ +#define GAP_ERROR_CODE_OVLOL \ + (uint32_t)(0x00400000) /**< @brief Over Voltage Lockout on VL ERROR occured. */ +#define GAP_ERROR_CODE_OVLOH \ + (uint32_t)(0x00800000) /**< @brief Over Voltage Lockout on VH ERROR occured. */ +#define GAP_ERROR_CODE_SPI_CRC \ + (uint32_t)(0x40000000) /**< @brief CRC SPI ERROR occured. */ +#define GAP_ERROR_CODE_DEVICES_NOT_PROGRAMMABLE \ + (uint32_t)(0x80000000) /**< @brief Device access ERROR occured. */ + +#define GAP_CFG1_CRC_SPI \ + (uint8_t)(0x80) /**< @brief CFG1 register: SPI communication protocol CRC enable. */ +#define GAP_CFG1_UVLOD \ + (uint8_t)(0x40) /**< @brief CFG1 register: UVLO protection on VDD supply voltage \ + enable. */ +#define GAP_CFG1_SD_FLAG \ + (uint8_t)(0x20) /**< @brief CFG1 register: SD pin functionality. */ +#define GAP_CFG1_DIAG_EN \ + (uint8_t)(0x10) /**< @brief CFG1 register: IN-/DIAG2 pin functionality. */ +#define GAP_CFG1_DT_DISABLE \ + (uint8_t)(0x00) /**< @brief CFG1 register: No deadtime value. */ +#define GAP_CFG1_DT_250NS \ + (uint8_t)(0x04) /**< @brief CFG1 register: 250ns deadtime value. */ +#define GAP_CFG1_DT_800NS \ + (uint8_t)(0x08) /**< @brief CFG1 register: 800ns deadtime value. */ +#define GAP_CFG1_DT_1200NS \ + (uint8_t)(0x0C) /**< @brief CFG1 register: 1200ns deadtime value. */ +#define GAP_CFG1_INFILTER_DISABLE \ + (uint8_t)(0x00) /**< @brief CFG1 register: No Input deglitch time value. */ +#define GAP_CFG1_INFILTER_210NS \ + (uint8_t)(0x01) /**< @brief CFG1 register: 210ns Input deglitch time value. */ +#define GAP_CFG1_INFILTER_560NS \ + (uint8_t)(0x02) /**< @brief CFG1 register: 560ns Input deglitch time value. */ +#define GAP_CFG1_INFILTER_70NS \ + (uint8_t)(0x03) /**< @brief CFG1 register: 70ns Input deglitch time value. */ + +#define GAP_CFG2_SENSETH_100MV \ + (uint8_t)(0x00) /**< @brief CFG2 register: 100mV SENSE comparator threshold value. \ + */ +#define GAP_CFG2_SENSETH_125MV \ + (uint8_t)(0x20) /**< @brief CFG2 register: 125mV SENSE comparator threshold value. \ + */ +#define GAP_CFG2_SENSETH_150MV \ + (uint8_t)(0x40) /**< @brief CFG2 register: 150mV SENSE comparator threshold value. \ + */ +#define GAP_CFG2_SENSETH_175MV \ + (uint8_t)(0x60) /**< @brief CFG2 register: 175mV SENSE comparator threshold value. \ + */ +#define GAP_CFG2_SENSETH_200MV \ + (uint8_t)(0x80) /**< @brief CFG2 register: 200mV SENSE comparator threshold value. \ + */ +#define GAP_CFG2_SENSETH_250MV \ + (uint8_t)(0xA0) /**< @brief CFG2 register: 250mV SENSE comparator threshold value. \ + */ +#define GAP_CFG2_SENSETH_300MV \ + (uint8_t)(0xC0) /**< @brief CFG2 register: 300mV SENSE comparator threshold value. \ + */ +#define GAP_CFG2_SENSETH_400MV \ + (uint8_t)(0xE0) /**< @brief CFG2 register: 400mV SENSE comparator threshold value. \ + */ +#define GAP_CFG2_DESATCURR_250UA \ + (uint8_t)( \ + 0x00) /**< @brief CFG2 register: 250uA current value sourced by the DESAT. */ +#define GAP_CFG2_DESATCURR_500UA \ + (uint8_t)( \ + 0x08) /**< @brief CFG2 register: 500uA current value sourced by the DESAT. */ +#define GAP_CFG2_DESATCURR_750UA \ + (uint8_t)( \ + 0x10) /**< @brief CFG2 register: 750uA current value sourced by the DESAT. */ +#define GAP_CFG2_DESATCURR_1000UA \ + (uint8_t)( \ + 0x18) /**< @brief CFG2 register: 1000uA current value sourced by the DESAT. */ +#define GAP_CFG2_DESATTH_3V \ + (uint8_t)(0x00) /**< @brief CFG2 register: 3V DESAT comparator threshold value. */ +#define GAP_CFG2_DESATTH_4V \ + (uint8_t)(0x01) /**< @brief CFG2 register: 4V DESAT comparator threshold value. */ +#define GAP_CFG2_DESATTH_5V \ + (uint8_t)(0x02) /**< @brief CFG2 register: 5V DESAT comparator threshold value. */ +#define GAP_CFG2_DESATTH_6V \ + (uint8_t)(0x03) /**< @brief CFG2 register: 6V DESAT comparator threshold value. */ +#define GAP_CFG2_DESATTH_7V \ + (uint8_t)(0x04) /**< @brief CFG2 register: 7V DESAT comparator threshold value. */ +#define GAP_CFG2_DESATTH_8V \ + (uint8_t)(0x05) /**< @brief CFG2 register: 8V DESAT comparator threshold value. */ +#define GAP_CFG2_DESATTH_9V \ + (uint8_t)(0x06) /**< @brief CFG2 register: 9V DESAT comparator threshold value. */ +#define GAP_CFG2_DESATTH_10V \ + (uint8_t)(0x07) /**< @brief CFG2 register: 10V DESAT comparator threshold value. */ + +#define GAP_CFG3_2LTOTH_7_0V \ + (uint8_t)(0x00) /**< @brief CFG3 register: 7V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_7_5V \ + (uint8_t)(0x10) /**< @brief CFG3 register: 7.5V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_8_0V \ + (uint8_t)(0x20) /**< @brief CFG3 register: 8V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_8_5V \ + (uint8_t)(0x30) /**< @brief CFG3 register: 8.5V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_9_0V \ + (uint8_t)(0x40) /**< @brief CFG3 register: 9V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_9_5V \ + (uint8_t)(0x50) /**< @brief CFG3 register: 9.5V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_10_0V \ + (uint8_t)(0x60) /**< @brief CFG3 register: 10V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_10_5V \ + (uint8_t)(0x70) /**< @brief CFG3 register: 10.5V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_11_0V \ + (uint8_t)(0x80) /**< @brief CFG3 register: 11V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_11_5V \ + (uint8_t)(0x90) /**< @brief CFG3 register: 11.5V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_12_0V \ + (uint8_t)(0xA0) /**< @brief CFG3 register: 12V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_12_5V \ + (uint8_t)(0xB0) /**< @brief CFG3 register: 12.5V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_13_0V \ + (uint8_t)(0xC0) /**< @brief CFG3 register: 13V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_13_5V \ + (uint8_t)(0xD0) /**< @brief CFG3 register: 13.5V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_14_0V \ + (uint8_t)(0xE0) /**< @brief CFG3 register: 14V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTH_14_5V \ + (uint8_t)(0xF0) /**< @brief CFG3 register: 14.5V threshold voltage value which is \ + actively forced during the 2-level turnoff sequence. */ +#define GAP_CFG3_2LTOTIME_DISABLE \ + (uint8_t)(0x00) /**< @brief CFG3 register: No duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_0_75_US \ + (uint8_t)(0x01) /**< @brief CFG3 register: 0.75us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_1_00_US \ + (uint8_t)(0x02) /**< @brief CFG3 register: 1us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_1_50_US \ + (uint8_t)(0x03) /**< @brief CFG3 register: 1.5us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_2_00_US \ + (uint8_t)(0x04) /**< @brief CFG3 register: 2us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_2_50_US \ + (uint8_t)(0x05) /**< @brief CFG3 register: 2.5us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_3_00_US \ + (uint8_t)(0x06) /**< @brief CFG3 register: 3us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_3_50_US \ + (uint8_t)(0x07) /**< @brief CFG3 register: 3.5us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_3_75_US \ + (uint8_t)(0x08) /**< @brief CFG3 register: 3.75us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_4_00_US \ + (uint8_t)(0x09) /**< @brief CFG3 register: 4us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_4_25_US \ + (uint8_t)(0x0A) /**< @brief CFG3 register: 4.25us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_4_50_US \ + (uint8_t)(0x0B) /**< @brief CFG3 register: 4.5us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_4_75_US \ + (uint8_t)(0x0C) /**< @brief CFG3 register: 4.75us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_5_00_US \ + (uint8_t)(0x0D) /**< @brief CFG3 register: 5us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_5_25_US \ + (uint8_t)(0x0E) /**< @brief CFG3 register: 5.25us duration time value of the 2-level \ + turn-off sequence. */ +#define GAP_CFG3_2LTOTIME_5_50_US \ + (uint8_t)(0x0F) /**< @brief CFG3 register: 5.5us duration time value of the 2-level \ + turn-off sequence. */ + +#define GAP_CFG4_OVLO \ + (uint8_t)(0x20) /**< @brief CFG4 register: enables the OVLO protection on the VH and \ + VL power supply. */ +#define GAP_CFG4_UVLOLATCH \ + (uint8_t)(0x10) /**< @brief CFG4 register: sets if the UVLO is latched or not. */ +#define GAP_CFG4_UVLOTH_VH_DISABLE \ + (uint8_t)(0x00) /**< @brief CFG4 register: disables the UVLO threshold on the \ + positive power supply. */ +#define GAP_CFG4_UVLOTH_VH_10V \ + (uint8_t)(0x01) /**< @brief CFG4 register: sets the VH positive supply voltage UVLO \ + threshold to 10v on the positive power supply. */ +#define GAP_CFG4_UVLOTH_VH_12V \ + (uint8_t)(0x02) /**< @brief CFG4 register: sets the VH positive supply voltage UVLO \ + threshold to 12v on the positive power supply. */ +#define GAP_CFG4_UVLOTH_VH_14V \ + (uint8_t)(0x03) /**< @brief CFG4 register: sets the VH positive supply voltage UVLO \ + threshold to 140v on the positive power supply. */ +#define GAP_CFG4_UVLOTH_VL_DISABLE \ + (uint8_t)(0x00) /**< @brief CFG4 register: disables the UVLO threshold on the \ + negative power supply. */ +#define GAP_CFG4_UVLOTH_VL_N3V \ + (uint8_t)(0x04) /**< @brief CFG4 register: sets the VL negative supply voltage UVLO \ + threshold to -3v on the negative power supply. */ +#define GAP_CFG4_UVLOTH_VL_N5V \ + (uint8_t)(0x08) /**< @brief CFG4 register: sets the VL negative supply voltage UVLO \ + threshold to -5v on the negative power supply. */ +#define GAP_CFG4_UVLOTH_VL_N7V \ + (uint8_t)(0x0C) /**< @brief CFG4 register: sets the VL negative supply voltage UVLO \ + threshold to -7v on the negative power supply. */ + +#define GAP_CFG5_2LTO_ON_FAULT \ + (uint8_t)(0x08) /**< @brief CFG5 register: 2LTO active only after a fault event. */ +#define GAP_CFG5_CLAMP_EN \ + (uint8_t)(0x04) /**< @brief CFG5 register: enables enable the Miller clamp feature. \ + */ +#define GAP_CFG5_DESAT_EN \ + (uint8_t)(0x02) /**< @brief CFG5 register: enables the DESAT desaturation protection \ + function comparator. */ +#define GAP_CFG5_SENSE_EN \ + (uint8_t)(0x01) /**< @brief CFG5 register: enables the sense overcurrent function \ + comparator. */ + +#define GAP_STATUS1_OVLOH \ + (uint8_t)(0x80) /**< @brief STATUS1 register: VH overvoltage flag is forced high \ + when VH is over OVVHoff threshold. */ +#define GAP_STATUS1_OVLOL \ + (uint8_t)(0x40) /**< @brief STATUS1 register: VL overvoltage flag is forced high \ + when VL is over OVVLoff threshold. */ +#define GAP_STATUS1_DESAT \ + (uint8_t)(0x20) /**< @brief STATUS1 register: Desaturation flag is forced high when \ + DESAT pin voltage reach VDESATth threshold. */ +#define GAP_STATUS1_SENSE \ + (uint8_t)(0x10) /**< @brief STATUS1 register: Sense flag is forced high when SENSE \ + pin voltage reach VSENSEth threshold. */ +#define GAP_STATUS1_UVLOH \ + (uint8_t)(0x08) /**< @brief STATUS1 register: VH undervoltage flag is forced high \ + when VH is below VHoff threshold. */ +#define GAP_STATUS1_UVLOL \ + (uint8_t)(0x04) /**< @brief STATUS1 register: VL undervoltage flag is forced high \ + when VL is over VLoff threshold. */ +#define GAP_STATUS1_TSD \ + (uint8_t)(0x02) /**< @brief STATUS1 register: Thermal shutdown protection flag is \ + forced high when overtemperature shutdown threshold is reached.*/ +#define GAP_STATUS1_TWN \ + (uint8_t)(0x01) /**< @brief STATUS1 register: Thermal warning flag is forced high \ + when overtemperature shutdown threshold is reached. */ + +#define GAP_STATUS2_REGERRR \ + (uint8_t)( \ + 0x02) /**< @brief STATUS2 register: Register or communication error on isolated \ + side is forced high when: 1 Programming procedure is not correctly \ + performed. 2 Isolated interface communication fails. 3 An unexpected \ + register value change occurs in one of the remote registers. It is also \ + latched at power-up/reset and from Sleep state. */ +#define GAP_STATUS2_ASC \ + (uint8_t)(0x01) /**< @brief STATUS2 register: ASC pin status. When ASC pin is high \ + the flag reports '1', otherwise is '0'.. */ + +#define GAP_STATUS3_CFG (uint8_t)(0x20) /**< @brief STATUS3 register: CFG error flag. */ +#define GAP_STATUS3_DT_ERR \ + (uint8_t)(0x10) /**< @brief STATUS3 register: Deadtime error flag is forced high \ + when a violation of internal DT is detected. */ +#define GAP_STATUS3_SPI_ERR \ + (uint8_t)( \ + 0x08) /**< @brief STATUS3 register: SPI communication error flag is forced high \ + when the SPI communication fails cause: 1 Wrong CRC check. 2 Wrong \ + number of CK rising edges. 3 Attempt to execute a not-allowed command. \ + 4 Attempt to read, write or reset at a not available address. */ +#define GAP_STATUS3_REGERRL \ + (uint8_t)( \ + 0x04) /**< @brief STATUS3 register: Register or communication error on low \ + voltage side is forced high when: - 1 Programming procedure is not \ + correctly performed. 2 Isolated interface communication fails. 3 An \ + unexpected register value change occurs in one of the remote registers. \ + * It is latched at power-up/reset also. */ +#define GAP_STATUS3_OVLOD \ + (uint8_t)(0x02) /**< @brief STATUS3 register: VDD overvoltage flag is forced high \ + when VDD is over OVVDDoff threshold. */ +#define GAP_STATUS3_UVLOD \ + (uint8_t)( \ + 0x01) /**< @brief STATUS3 register: VDD undervoltage flag is forced high when \ + VDD is below VDDon threshold. It is latched at power-up/reset also. */ + +#define GAP_TEST1_GOFFCHK \ + (uint8_t)( \ + 0x10) /**< @brief TEST1 register: enables the GOFF to gate path check mode */ +#define GAP_TEST1_GONCHK \ + (uint8_t)(0x08) /**< @brief TEST1 register: enables the GON to gate path check mode \ + */ +#define GAP_TEST1_DESCHK \ + (uint8_t)(0x04) /**< @brief TEST1 register: enables the DESAT comparator check mode \ + */ +#define GAP_TEST1_SNSCHK \ + (uint8_t)(0x02) /**< @brief TEST1 register: enables the SENSE comparator check mode \ + */ +#define GAP_TEST1_RCHK \ + (uint8_t)(0x01) /**< @brief TEST1 register: enables the SENSE resistor check mode */ + +#define GAP_DIAG_SPI_REGERR \ + (uint8_t)(0x80) /**< @brief DIAG register: enables the DIAGxCFG event SPI \ + communication error or register failure */ +#define GAP_DIAG_UVLOD_OVLOD \ + (uint8_t)(0x40) /**< @brief DIAG register: enables the DIAGxCFG event VDD power \ + supply failure */ +#define GAP_DIAG_UVLOH_UVLOL \ + (uint8_t)(0x20) /**< @brief DIAG register: enables the DIAGxCFG event Undervoltage \ + failure */ +#define GAP_DIAG_OVLOH_OVLOL \ + (uint8_t)(0x10) /**< @brief DIAG register: enables the DIAGxCFG event Overvoltage \ + failure */ +#define GAP_DIAG_DESAT_SENSE \ + (uint8_t)(0x08) /**< @brief DIAG register: enables the DIAGxCFG event SDesaturation \ + and sense detection */ +#define GAP_DIAG_ASC_DT_ERR \ + (uint8_t)(0x04) /**< @brief DIAG register: enables the DIAGxCFG event ASC feedback \ + */ +#define GAP_DIAG_TSD \ + (uint8_t)( \ + 0x02) /**< @brief DIAG register: enables the DIAGxCFG event Thermal shutdown */ +#define GAP_DIAG_TWN \ + (uint8_t)( \ + 0x01) /**< @brief DIAG register: enables the DIAGxCFG event Thermal warning */ +#define GAP_DIAG_NONE (uint8_t)(0x00) /**< @brief DIAG register: No DIAGxCFG event. */ + + /** Define the GAP register enum. + * + */ + typedef enum + { + CFG1 = 0x0C, /*!< Address of CFG1 register (low voltage side). */ + CFG2 = 0x1D, /*!< Address of CFG2 register (isolated side). */ + CFG3 = 0x1E, /*!< Address of CFG3 register (isolated side). */ + CFG4 = 0x1F, /*!< Address of CFG4 register (isolated side). */ + CFG5 = 0x19, /*!< Address of CFG5 register (isolated side). */ + STATUS1 = 0x02, /*!< Address of STATUS1 register (low voltage side). + The STATUS1 is a read only register that reports some device + failure flags. */ + STATUS2 = 0x01, /*!< Address of STATUS2 register (low voltage side). */ + STATUS3 = 0x0A, /*!< Address of STATUS3 register (low voltage side). */ + TEST1 = 0x11, /*!< Address of TEST1 register (isolated side). */ + DIAG1 = 0x05, /*!< Address of DIAG1CFG registers (low voltage side). */ + DIAG2 = 0x06 /*!< Address of DIAG2CFG registers (low voltage side). */ + } GAP_Registers_Handle_t; + + /** Define test modes + * + */ + typedef enum + { + SENSE_RESISTOR_CHK, /*!< Security check to verify the connection between the + device and the sense shunt resistor and to verify the + optional sense resistor filter network is not open. */ + SENSE_COMPARATOR_CHK, /*!< Security check to verify the functionality of the sense + comparator. */ + GON_CHK, /*!< Security check to verify the path integrity including the driver's + GON output, the GON (turn-on) gate resistor, the power switch gate + and the CLAMP pin. */ + GOFF_CHK, /*!< Security check to verify the path integrity including the driver's + GOFF output, the GOFF (turn-off) gate resistor, the power switch gate + and the CLAMP pin. */ + DESAT_CHK /*!< Security check to verify the functionality of the de-saturation. */ + } GAP_TestMode_t; + + /** + * @brief GAP class register bank definition + * + * This structure contains configuration value for register bank of the GAP driver. + * + */ + typedef struct + { + uint8_t CFG1; /*!< Configuration value for CFG1 register. */ + uint8_t CFG2; /*!< Configuration value for CFG2 register. */ + uint8_t CFG3; /*!< Configuration value for CFG3 register. */ + uint8_t CFG4; /*!< Configuration value for CFG4 register. */ + uint8_t CFG5; /*!< Configuration value for CFG5 register. */ + uint8_t DIAG1; /*!< Configuration value for DIAG1 register. */ + uint8_t DIAG2; /*!< Configuration value for DIAG2 register. */ + } GAP_DeviceParams_Handle_t; + + /** + * @brief Handle of the GAP component + * + * This structure holds all the parameters needed to access and manage GAP drivers. + */ + typedef struct + { + uint8_t DeviceNum; /*!< Number of GAP used in the daisy chain. */ + GAP_DeviceParams_Handle_t + DeviceParams[MAX_DEVICES_NUMBER]; /*!< Device parameters pointers */ + /* SPI related parameters. */ + SPI_TypeDef *SPIx; + GPIO_TypeDef + *NCSPort; /*!< GPIO port used by NCS. It must be equal to GPIOx x= A, B, ...*/ + uint16_t NCSPin; /*!< GPIO pin used by NCS. It must be equal to GPIO_Pin_x x= 0, + 1, ...*/ + GPIO_TypeDef + *NSDPort; /*!< GPIO port used by NSD. It must be equal to GPIOx x= A, B, ...*/ + uint16_t NSDPin; /*!< GPIO pin used by NSD. It must be equal to GPIO_Pin_x x= 0, + 1, ...*/ + uint32_t + GAP_ErrorsNow[MAX_DEVICES_NUMBER]; /*!< Bitfield with extra error codes that + is currently active. The error code + available are listed here (TBF).*/ + uint32_t GAP_ErrorsOccurred[MAX_DEVICES_NUMBER]; /*!< Bitfield with extra error + codes that occurs and is over. + The error code available are + listed here (TBF).*/ + } GAP_Handle_t; + + + /* Exported functions ------------------------------------------------------- */ + + bool GAP_CheckErrors(GAP_Handle_t *pHandle, uint32_t *error_now, + uint32_t *error_occurred); + void GAP_FaultAck(GAP_Handle_t *pHandle); + bool GAP_Configuration(GAP_Handle_t *pHandle); + bool GAP_IsDevicesProgrammed(GAP_Handle_t *pHandle); + bool GAP_DevicesConfiguration(GAP_Handle_t *pHandle); + uint16_t GAP_CRCCalculate(uint8_t data, uint8_t crc_initial_value); + bool GAP_CRCCheck(uint8_t *out, uint16_t data_in); + void wait(uint16_t count); + uint8_t GAP_RegMask(GAP_Registers_Handle_t reg); + bool GAP_ReadRegs(GAP_Handle_t *pHandle, uint8_t *pDataRead, + GAP_Registers_Handle_t reg); + void GAP_StartConfig(GAP_Handle_t *pHandle); + void GAP_StopConfig(GAP_Handle_t *pHandle); + bool GAP_WriteRegs(GAP_Handle_t *pHandle, uint8_t *pDataWrite, + GAP_Registers_Handle_t reg); + void GAP_GlobalReset(GAP_Handle_t *pHandle); + bool GAP_ResetStatus(GAP_Handle_t *pHandle, GAP_Registers_Handle_t reg); + bool GAP_Test(GAP_Handle_t *pHandle, GAP_TestMode_t testMode); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* __GAP_GATE_DRIVER_CTR_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/hall_speed_pos_fdbk.c b/src/firmware/motor/mcsdk/hall_speed_pos_fdbk.c new file mode 100644 index 0000000000..49e98e76fd --- /dev/null +++ b/src/firmware/motor/mcsdk/hall_speed_pos_fdbk.c @@ -0,0 +1,972 @@ + +/** + ****************************************************************************** + * @file hall_speed_pos_fdbk.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features of + * the Hall Speed & Position Feedback component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup hall_speed_pos_fdbk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/hall_speed_pos_fdbk.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup SpeednPosFdbk + * @{ + */ + +/** @addtogroup hall_speed_pos_fdbk + * @{ + */ + +/** + * @defgroup hall_speed_pos_fdbk Hall Speed & Position Feedback + * + * @brief Hall Sensor based Speed & Position Feedback implementation + * + * This component is used in applications controlling a motor equipped with Hall effect + * sensors. + * + * This component uses the output of two Hall effects sensors to provide a measure of the + * speed and the position of the rotor of the motor. + * + * @todo Document the Hall Speed & Position Feedback "module". + * + * @{ + */ + +/* Private defines -----------------------------------------------------------*/ + +/* Lower threshold to reques a decrease of clock prescaler */ +#define LOW_RES_THRESHOLD ((uint16_t)0x5500U) + +#define HALL_COUNTER_RESET ((uint16_t)0U) + +#define S16_120_PHASE_SHIFT (int16_t)(65536 / 3) +#define S16_60_PHASE_SHIFT (int16_t)(65536 / 6) + +#define STATE_0 (uint8_t)0 +#define STATE_1 (uint8_t)1 +#define STATE_2 (uint8_t)2 +#define STATE_3 (uint8_t)3 +#define STATE_4 (uint8_t)4 +#define STATE_5 (uint8_t)5 +#define STATE_6 (uint8_t)6 +#define STATE_7 (uint8_t)7 + +#define NEGATIVE (int8_t) - 1 +#define POSITIVE (int8_t)1 + +/* With digit-per-PWM unit (here 2*PI rad = 0xFFFF): */ +#define HALL_MAX_PSEUDO_SPEED ((int16_t)0x7FFF) + +#define CCER_CC1E_Set ((uint16_t)0x0001) +#define CCER_CC1E_Reset ((uint16_t)0xFFFE) + +static void HALL_Init_Electrical_Angle(HALL_Handle_t *pHandle); + +/** + * @brief It initializes the hardware peripherals (TIMx, GPIO and NVIC) + required for the speed position sensor management using HALL + sensors. + * @param pHandle: handler of the current instance of the hall_speed_pos_fdbk component + */ +__weak void HALL_Init(HALL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + TIM_TypeDef *TIMx = pHandle->TIMx; + + uint16_t hMinReliableElSpeedUnit = + pHandle->_Super.hMinReliableMecSpeedUnit * pHandle->_Super.bElToMecRatio; + uint16_t hMaxReliableElSpeedUnit = + pHandle->_Super.hMaxReliableMecSpeedUnit * pHandle->_Super.bElToMecRatio; + uint8_t bSpeedBufferSize; + uint8_t bIndex; + + /* Adjustment factor: minimum measurable speed is x time less than the minimum + reliable speed */ + hMinReliableElSpeedUnit /= 4U; + + /* Adjustment factor: maximum measurable speed is x time greater than the + maximum reliable speed */ + hMaxReliableElSpeedUnit *= 2U; + + pHandle->OvfFreq = (uint16_t)(pHandle->TIMClockFreq / 65536U); + + /* SW Init */ + if (0U == hMinReliableElSpeedUnit) + { + /* Set fixed to 150 ms */ + pHandle->HallTimeout = 150U; + } + else + { + /* Set accordingly the min reliable speed */ + /* 1000 comes from mS + * 6 comes from the fact that sensors are toggling each 60 deg = 360/6 deg */ + pHandle->HallTimeout = + (1000U * (uint16_t)SPEED_UNIT) / (6U * hMinReliableElSpeedUnit); + } + + /* Compute the prescaler to the closet value of the TimeOut (in mS )*/ + pHandle->HALLMaxRatio = (pHandle->HallTimeout * pHandle->OvfFreq) / 1000U; + + /* Align MaxPeriod to a multiple of Overflow.*/ + pHandle->MaxPeriod = pHandle->HALLMaxRatio * 65536UL; + + pHandle->SatSpeed = hMaxReliableElSpeedUnit; + + pHandle->PseudoFreqConv = + ((pHandle->TIMClockFreq / 6U) / pHandle->_Super.hMeasurementFrequency) * + pHandle->_Super.DPPConvFactor; + + if (0U == hMaxReliableElSpeedUnit) + { + pHandle->MinPeriod = ((uint32_t)SPEED_UNIT * (pHandle->TIMClockFreq / 6UL)); + } + else + { + pHandle->MinPeriod = (((uint32_t)SPEED_UNIT * (pHandle->TIMClockFreq / 6UL)) / + hMaxReliableElSpeedUnit); + } + + pHandle->PWMNbrPSamplingFreq = + ((pHandle->_Super.hMeasurementFrequency * pHandle->PWMFreqScaling) / + pHandle->SpeedSamplingFreqHz) - + 1U; + + /* Reset speed reliability */ + pHandle->SensorIsReliable = true; + + /* Set IC filter for Channel 1 (ICF1) */ + LL_TIM_IC_SetFilter(TIMx, LL_TIM_CHANNEL_CH1, (uint32_t)(pHandle->ICx_Filter)); + + /* Force the TIMx prescaler with immediate access (gen update event) + */ + LL_TIM_SetPrescaler(TIMx, pHandle->HALLMaxRatio); + LL_TIM_GenerateEvent_UPDATE(TIMx); + + /* Clear the TIMx's pending flags */ + WRITE_REG(TIMx->SR, 0); + + /* Selected input capture and Update (overflow) events generate interrupt */ + + /* Source of Update event is only counter overflow/underflow */ + LL_TIM_SetUpdateSource(TIMx, LL_TIM_UPDATESOURCE_COUNTER); + + LL_TIM_EnableIT_CC1(TIMx); + LL_TIM_EnableIT_UPDATE(TIMx); + LL_TIM_SetCounter(TIMx, HALL_COUNTER_RESET); + + LL_TIM_CC_EnableChannel(TIMx, LL_TIM_CHANNEL_CH1); + LL_TIM_EnableCounter(TIMx); + + /* Erase speed buffer */ + bSpeedBufferSize = pHandle->SpeedBufferSize; + + for (bIndex = 0u; bIndex < bSpeedBufferSize; bIndex++) + { + pHandle->SensorPeriod[bIndex] = (int32_t)pHandle->MaxPeriod; + } +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Clear software FIFO where are "pushed" latest speed information + * This function must be called before starting the motor to initialize + * the speed measurement process. + * @param pHandle: handler of the current instance of the hall_speed_pos_fdbk component* + */ +__weak void HALL_Clear(HALL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + TIM_TypeDef *TIMx = pHandle->TIMx; + + /* Mask interrupts to insure a clean intialization */ + LL_TIM_DisableIT_CC1(TIMx); + + pHandle->RatioDec = false; + pHandle->RatioInc = false; + + /* Reset speed reliability */ + pHandle->SensorIsReliable = true; + + /* Acceleration measurement not implemented.*/ + pHandle->_Super.hMecAccelUnitP = 0; + + pHandle->FirstCapt = 0U; + pHandle->BufferFilled = 0U; + pHandle->OVFCounter = 0U; + + pHandle->CompSpeed = 0; + + pHandle->Direction = POSITIVE; + + /* Initialize speed buffer index */ + pHandle->SpeedFIFOIdx = 0U; + + /* Clear speed error counter */ + pHandle->_Super.bSpeedErrorNumber = 0; + + /* Re-initialize partly the timer */ + LL_TIM_SetPrescaler(TIMx, pHandle->HALLMaxRatio); + + LL_TIM_SetCounter(TIMx, HALL_COUNTER_RESET); + + LL_TIM_EnableCounter(TIMx); + + LL_TIM_EnableIT_CC1(TIMx); + + HALL_Init_Electrical_Angle(pHandle); +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Update the rotor electrical angle integrating the last measured + * instantaneous electrical speed express in dpp. + * @param pHandle: handler of the current instance of the hall_speed_pos_fdbk component + * @retval int16_t Measured electrical angle in s16degree format. + */ +__weak int16_t HALL_CalcElAngle(HALL_Handle_t *pHandle) +{ + int16_t retValue; +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + if (NULL == pHandle) + { + retValue = 0; + } + else + { +#endif + + if (pHandle->_Super.hElSpeedDpp != HALL_MAX_PSEUDO_SPEED) + { + pHandle->IncrementElAngle += pHandle->_Super.hElSpeedDpp + pHandle->CompSpeed; + pHandle->PrevRotorFreq = pHandle->_Super.hElSpeedDpp; + + if (pHandle->IncrementElAngle >= S16_60_PHASE_SHIFT) + { + pHandle->_Super.hElAngle += + pHandle->_Super.hElSpeedDpp + pHandle->CompSpeed - + (pHandle->IncrementElAngle - S16_60_PHASE_SHIFT) - 1; + pHandle->IncrementElAngle = S16_60_PHASE_SHIFT; + } + else if (pHandle->IncrementElAngle <= -S16_60_PHASE_SHIFT) + { + pHandle->_Super.hElAngle += + pHandle->_Super.hElSpeedDpp + pHandle->CompSpeed - + (pHandle->IncrementElAngle + S16_60_PHASE_SHIFT) + 1; + pHandle->IncrementElAngle = -S16_60_PHASE_SHIFT; + } + else + { + pHandle->MeasuredElAngle += pHandle->_Super.hElSpeedDpp; + pHandle->_Super.hElAngle += + pHandle->_Super.hElSpeedDpp + pHandle->CompSpeed; + } + } + else + { + pHandle->_Super.hElAngle += pHandle->PrevRotorFreq; + } + + retValue = pHandle->_Super.hElAngle; +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + } +#endif + return (retValue); +} + +/** + * @brief This method must be called - at least - with the same periodicity + * on which speed control is executed. + * This method compute and store rotor istantaneous el speed (express + * in dpp considering the measurement frequency) in order to provide it + * to HALL_CalcElAngle function and SPD_GetElAngle. + * Then compute rotor average el speed (express in dpp considering the + * measurement frequency) based on the buffer filled by IRQ, then - as + * a consequence - compute, store and return - through parameter + * hMecSpeedUnit - the rotor average mech speed, expressed in Unit. + * Then check, store and return the reliability state of + * the sensor; in this function the reliability is measured with + * reference to specific parameters of the derived + * sensor (HALL) through internal variables managed by IRQ. + * @param pHandle: handler of the current instance of the hall_speed_pos_fdbk component + * @param hMecSpeedUnit pointer to int16_t, used to return the rotor average + * mechanical speed (expressed in the unit defined by #SPEED_UNIT) + * @retval true = sensor information is reliable + * false = sensor information is not reliable + */ +__weak bool HALL_CalcAvrgMecSpeedUnit(HALL_Handle_t *pHandle, int16_t *hMecSpeedUnit) +{ + bool bReliability; +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + if ((NULL == pHandle) || (NULL == hMecSpeedUnit)) + { + bReliability = false; + } + else + { +#endif + TIM_TypeDef *TIMx = pHandle->TIMx; + + if (pHandle->SensorIsReliable) + { + /* No errors have been detected during rotor speed information + extrapolation */ + if (LL_TIM_GetPrescaler(TIMx) >= pHandle->HALLMaxRatio) + { + /* At start-up or very low freq */ + /* Based on current prescaler value only */ + pHandle->_Super.hElSpeedDpp = 0; + *hMecSpeedUnit = 0; + } + else + { + pHandle->_Super.hElSpeedDpp = pHandle->AvrElSpeedDpp; + if (0 == pHandle->AvrElSpeedDpp) + { + /* Speed is too low */ + *hMecSpeedUnit = 0; + } + else + { + /* Check if speed is not to fast */ + if (pHandle->AvrElSpeedDpp != HALL_MAX_PSEUDO_SPEED) + { + if (true == pHandle->HallMtpa) + { + pHandle->CompSpeed = 0; + } + else + { + pHandle->DeltaAngle = + pHandle->MeasuredElAngle - pHandle->_Super.hElAngle; + pHandle->CompSpeed = + (int16_t)((int32_t)(pHandle->DeltaAngle) / + (int32_t)(pHandle->PWMNbrPSamplingFreq)); + } + /* Convert el_dpp to MecUnit */ + *hMecSpeedUnit = + (int16_t)((pHandle->AvrElSpeedDpp * + (int32_t)pHandle->_Super.hMeasurementFrequency * + (int32_t)SPEED_UNIT) / + ((int32_t)(pHandle->_Super.DPPConvFactor) * + (int32_t)(pHandle->_Super.bElToMecRatio))); + } + else + { + *hMecSpeedUnit = (int16_t)pHandle->SatSpeed; + } + } + } + bReliability = SPD_IsMecSpeedReliable(&pHandle->_Super, hMecSpeedUnit); + } + else + { + bReliability = false; + pHandle->_Super.bSpeedErrorNumber = pHandle->_Super.bMaximumSpeedErrorsNumber; + /* If speed is not reliable the El and Mec speed is set to 0 */ + pHandle->_Super.hElSpeedDpp = 0; + *hMecSpeedUnit = 0; + } + + pHandle->_Super.hAvrMecSpeedUnit = *hMecSpeedUnit; +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + } +#endif + + return (bReliability); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Example of private method of the class HALL to implement an MC IRQ function + * to be called when TIMx capture event occurs + * @param pHandle: handler of the current instance of the hall_speed_pos_fdbk component + */ +__weak void *HALL_TIMx_CC_IRQHandler(void *pHandleVoid) +{ + uint32_t wCaptBuf; + uint16_t hPrscBuf; + uint16_t hHighSpeedCapture; + HALL_Handle_t *pHandle = (HALL_Handle_t *)pHandleVoid; // cstat !MISRAC2012-Rule-11.5 + TIM_TypeDef *TIMx = pHandle->TIMx; + uint8_t bPrevHallState; + int8_t PrevDirection; + + if (pHandle->SensorIsReliable) + { + /* A capture event generated this interrupt */ + bPrevHallState = pHandle->HallState; + PrevDirection = pHandle->Direction; + + if (DEGREES_120 == pHandle->SensorPlacement) + { + pHandle->HallState = + (uint8_t)((LL_GPIO_IsInputPinSet(pHandle->H3Port, pHandle->H3Pin) << 2U) | + (LL_GPIO_IsInputPinSet(pHandle->H2Port, pHandle->H2Pin) << 1U) | + LL_GPIO_IsInputPinSet(pHandle->H1Port, pHandle->H1Pin)); + } + else + { + pHandle->HallState = + (uint8_t)(((LL_GPIO_IsInputPinSet(pHandle->H2Port, pHandle->H2Pin) ^ 1U) + << 2U) | + (LL_GPIO_IsInputPinSet(pHandle->H3Port, pHandle->H3Pin) << 1U) | + LL_GPIO_IsInputPinSet(pHandle->H1Port, pHandle->H1Pin)); + } + + switch (pHandle->HallState) + { + case STATE_5: + { + if (STATE_4 == bPrevHallState) + { + pHandle->Direction = POSITIVE; + pHandle->MeasuredElAngle = pHandle->PhaseShift; + } + else if (STATE_1 == bPrevHallState) + { + pHandle->Direction = NEGATIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift + S16_60_PHASE_SHIFT); + } + else + { + /* Nothing to do */ + } + break; + } + + case STATE_1: + { + if (STATE_5 == bPrevHallState) + { + pHandle->Direction = POSITIVE; + pHandle->MeasuredElAngle = pHandle->PhaseShift + S16_60_PHASE_SHIFT; + } + else if (STATE_3 == bPrevHallState) + { + pHandle->Direction = NEGATIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift + S16_120_PHASE_SHIFT); + } + else + { + /* Nothing to do */ + } + break; + } + + case STATE_3: + { + if (STATE_1 == bPrevHallState) + { + pHandle->Direction = POSITIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift + S16_120_PHASE_SHIFT); + } + else if (STATE_2 == bPrevHallState) + { + pHandle->Direction = NEGATIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift + S16_120_PHASE_SHIFT + + S16_60_PHASE_SHIFT); + } + else + { + /* Nothing to do */ + } + break; + } + + case STATE_2: + { + if (STATE_3 == bPrevHallState) + { + pHandle->Direction = POSITIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift + S16_120_PHASE_SHIFT + + S16_60_PHASE_SHIFT); + } + else if (STATE_6 == bPrevHallState) + { + pHandle->Direction = NEGATIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift - S16_120_PHASE_SHIFT); + } + else + { + /* Nothing to do */ + } + break; + } + + case STATE_6: + { + if (STATE_2 == bPrevHallState) + { + pHandle->Direction = POSITIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift - S16_120_PHASE_SHIFT); + } + else if (STATE_4 == bPrevHallState) + { + pHandle->Direction = NEGATIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift - S16_60_PHASE_SHIFT); + } + else + { + /* Nothing to do */ + } + break; + } + + case STATE_4: + { + if (STATE_6 == bPrevHallState) + { + pHandle->Direction = POSITIVE; + pHandle->MeasuredElAngle = + (int16_t)(pHandle->PhaseShift - S16_60_PHASE_SHIFT); + } + else if (STATE_5 == bPrevHallState) + { + pHandle->Direction = NEGATIVE; + pHandle->MeasuredElAngle = (int16_t)(pHandle->PhaseShift); + } + else + { + /* Nothing to do */ + } + break; + } + + default: + { + /* Bad hall sensor configutarion so update the speed reliability */ + pHandle->SensorIsReliable = false; + break; + } + } + + /* We need to check that the direction has not changed. + If it is the case, the sign of the current speed can be the opposite of the + average speed, and the average time can be close to 0 which lead to a + computed speed close to the infinite, and bring instability. */ + if (pHandle->Direction != PrevDirection) + { + /* Setting BufferFilled to 0 will prevent to compute the average speed based + on the SpeedPeriod buffer values */ + pHandle->BufferFilled = 0U; + pHandle->SpeedFIFOIdx = 0U; + } + + if (true == pHandle->HallMtpa) + { + pHandle->_Super.hElAngle = pHandle->MeasuredElAngle; + } + else + { + /* Nothing to do */ + } + + /* Reset incremental value */ + pHandle->IncrementElAngle = pHandle->_Super.hElAngle - pHandle->MeasuredElAngle; + + /* Discard first capture */ + if (0U == pHandle->FirstCapt) + { + pHandle->FirstCapt++; + (void)LL_TIM_IC_GetCaptureCH1(TIMx); + } + else + { + /* used to validate the average speed measurement */ + if (pHandle->BufferFilled < pHandle->SpeedBufferSize) + { + pHandle->BufferFilled++; + } + else + { + /* Nothing to do */ + } + + /* Store the latest speed acquisition */ + hHighSpeedCapture = (uint16_t)LL_TIM_IC_GetCaptureCH1(TIMx); + wCaptBuf = (uint32_t)hHighSpeedCapture; + hPrscBuf = (uint16_t)LL_TIM_GetPrescaler(TIMx); + + /* Add the numbers of overflow to the counter */ + wCaptBuf += ((uint32_t)pHandle->OVFCounter) * 0x10000UL; + + if (pHandle->OVFCounter != 0U) + { + /* Adjust the capture using prescaler */ + uint16_t hAux; + hAux = hPrscBuf + 1U; + wCaptBuf *= hAux; + + if (pHandle->RatioInc) + { + pHandle->RatioInc = false; /* Previous capture caused overflow */ + /* Don't change prescaler (delay due to preload/update mechanism) */ + } + else + { + if (LL_TIM_GetPrescaler(TIMx) < + pHandle->HALLMaxRatio) /* Avoid OVF w/ very low freq */ + { + LL_TIM_SetPrescaler( + TIMx, LL_TIM_GetPrescaler(TIMx) + + 1U); /* To avoid OVF during speed decrease */ + pHandle->RatioInc = + true; /* new prsc value updated at next capture only */ + } + else + { + /* Nothing to do */ + } + } + } + else + { + /* If prsc preload reduced in last capture, store current register + 1 */ + if (pHandle->RatioDec) /* and don't decrease it again */ + { + /* Adjust the capture using prescaler */ + uint16_t hAux; + hAux = hPrscBuf + 2U; + wCaptBuf *= hAux; + + pHandle->RatioDec = false; + } + else /* If prescaler was not modified on previous capture */ + { + /* Adjust the capture using prescaler */ + uint16_t hAux = hPrscBuf + 1U; + wCaptBuf *= hAux; + + if (hHighSpeedCapture < + LOW_RES_THRESHOLD) /* If capture range correct */ + { + if (LL_TIM_GetPrescaler(TIMx) > + 0U) /* or prescaler cannot be further reduced */ + { + LL_TIM_SetPrescaler( + TIMx, LL_TIM_GetPrescaler(TIMx) - + 1U); /* Increase accuracy by decreasing prsc */ + /* Avoid decrementing again in next capt.(register preload + * delay) */ + pHandle->RatioDec = true; + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do */ + } + } + } + + /* Filtering to fast speed... could be a glitch ? */ + /* the HALL_MAX_PSEUDO_SPEED is temporary in the buffer, and never included in + * average computation*/ + if (wCaptBuf < pHandle->MinPeriod) + { + /* Nothing to do */ +#ifdef NOT_IMPLEMENTED /* Not yet implemented */ + pHandle->AvrElSpeedDpp = HALL_MAX_PSEUDO_SPEED; +#endif + } + else + { + pHandle->ElPeriodSum -= + pHandle + ->SensorPeriod[pHandle->SpeedFIFOIdx]; /* value we gonna removed + from the accumulator */ + if (wCaptBuf >= pHandle->MaxPeriod) + { + pHandle->SensorPeriod[pHandle->SpeedFIFOIdx] = + (int32_t)pHandle->MaxPeriod * pHandle->Direction; + } + else + { + pHandle->SensorPeriod[pHandle->SpeedFIFOIdx] = (int32_t)wCaptBuf; + pHandle->SensorPeriod[pHandle->SpeedFIFOIdx] *= pHandle->Direction; + } + pHandle->ElPeriodSum += pHandle->SensorPeriod[pHandle->SpeedFIFOIdx]; + /* Update pointers to speed buffer */ + pHandle->SpeedFIFOIdx++; + if (pHandle->SpeedFIFOIdx == pHandle->SpeedBufferSize) + { + pHandle->SpeedFIFOIdx = 0U; + } + if (pHandle->SensorIsReliable) + { + if ((pHandle->BufferFilled < pHandle->SpeedBufferSize) && + (wCaptBuf != 0U)) + { + uint32_t tempReg = (pHandle->PseudoFreqConv / wCaptBuf) * + (uint32_t)pHandle->Direction; + pHandle->AvrElSpeedDpp = (int16_t)tempReg; + } + else + { + /* Average speed allow to smooth the mechanical sensors + * misalignement */ + pHandle->AvrElSpeedDpp = + (int16_t)((int32_t)pHandle->PseudoFreqConv / + (pHandle->ElPeriodSum / + (int32_t) + pHandle->SpeedBufferSize)); /* Average value */ + } + } + else /* Sensor is not reliable */ + { + pHandle->AvrElSpeedDpp = 0; + } + } + /* Reset the number of overflow occurred */ + pHandle->OVFCounter = 0U; + } + } + return (MC_NULL); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Example of private method of the class HALL to implement an MC IRQ function + * to be called when TIMx update event occurs + * @param pHandle: handler of the current instance of the hall_speed_pos_fdbk component + */ +__weak void *HALL_TIMx_UP_IRQHandler(void *pHandleVoid) +{ + HALL_Handle_t *pHandle = (HALL_Handle_t *)pHandleVoid; // cstat !MISRAC2012-Rule-11.5 + TIM_TypeDef *TIMx = pHandle->TIMx; + + if (pHandle->SensorIsReliable) + { + uint16_t hMaxTimerOverflow; + /* an update event occured for this interrupt request generation */ + pHandle->OVFCounter++; + + hMaxTimerOverflow = + (uint16_t)(((uint32_t)pHandle->HallTimeout * pHandle->OvfFreq) / + ((LL_TIM_GetPrescaler(TIMx) + 1U) * 1000U)); + if (pHandle->OVFCounter >= hMaxTimerOverflow) + { + /* Set rotor speed to zero */ + pHandle->_Super.hElSpeedDpp = 0; + + /* Reset the electrical angle according the hall sensor configuration */ + HALL_Init_Electrical_Angle(pHandle); + + /* Reset the overflow counter */ + pHandle->OVFCounter = 0U; + + /* Reset first capture flag */ + pHandle->FirstCapt = 0U; + + /* Reset the SensorSpeed buffer*/ + uint8_t bIndex; + for (bIndex = 0U; bIndex < pHandle->SpeedBufferSize; bIndex++) + { + pHandle->SensorPeriod[bIndex] = (int32_t)pHandle->MaxPeriod; + } + pHandle->BufferFilled = 0U; + pHandle->AvrElSpeedDpp = 0; + pHandle->SpeedFIFOIdx = 0U; + uint32_t tempReg = pHandle->MaxPeriod * pHandle->SpeedBufferSize; + pHandle->ElPeriodSum = (int32_t)tempReg; + } + } + return (MC_NULL); +} + +/** + * @brief Read the logic level of the three Hall sensor and individuates in this + * way the position of the rotor (+/- 30�). Electrical angle is then + * initialized. + * @param pHandle: handler of the current instance of the hall_speed_pos_fdbk component + */ +static void HALL_Init_Electrical_Angle(HALL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (DEGREES_120 == pHandle->SensorPlacement) + { + pHandle->HallState = + (uint8_t)((LL_GPIO_IsInputPinSet(pHandle->H3Port, pHandle->H3Pin) << 2U) | + (LL_GPIO_IsInputPinSet(pHandle->H2Port, pHandle->H2Pin) << 1U) | + LL_GPIO_IsInputPinSet(pHandle->H1Port, pHandle->H1Pin)); + } + else + { + pHandle->HallState = + (uint8_t)(((LL_GPIO_IsInputPinSet(pHandle->H2Port, pHandle->H2Pin) ^ 1U) + << 2U) | + (LL_GPIO_IsInputPinSet(pHandle->H3Port, pHandle->H3Pin) << 1U) | + LL_GPIO_IsInputPinSet(pHandle->H1Port, pHandle->H1Pin)); + } + + switch (pHandle->HallState) + { + case STATE_5: + { + pHandle->_Super.hElAngle = + (int16_t)(pHandle->PhaseShift + (S16_60_PHASE_SHIFT / 2)); + break; + } + + case STATE_1: + { + pHandle->_Super.hElAngle = + (int16_t)(pHandle->PhaseShift + S16_60_PHASE_SHIFT + + (S16_60_PHASE_SHIFT / 2)); + break; + } + + case STATE_3: + { + pHandle->_Super.hElAngle = + (int16_t)(pHandle->PhaseShift + S16_120_PHASE_SHIFT + + (S16_60_PHASE_SHIFT / 2)); + break; + } + + case STATE_2: + { + pHandle->_Super.hElAngle = + (int16_t)(pHandle->PhaseShift - S16_120_PHASE_SHIFT - + (S16_60_PHASE_SHIFT / 2)); + break; + } + + case STATE_6: + { + pHandle->_Super.hElAngle = + (int16_t)(pHandle->PhaseShift - S16_60_PHASE_SHIFT - + (S16_60_PHASE_SHIFT / 2)); + break; + } + + case STATE_4: + { + pHandle->_Super.hElAngle = + (int16_t)(pHandle->PhaseShift - (S16_60_PHASE_SHIFT / 2)); + break; + } + + default: + { + /* Bad hall sensor configutarion so update the speed reliability */ + pHandle->SensorIsReliable = false; + break; + } + } + /* Reset incremental value */ + pHandle->IncrementElAngle = 0; + + /* Initialize the measured angle */ + pHandle->MeasuredElAngle = pHandle->_Super.hElAngle; + pHandle->CompSpeed = 0; + +#ifdef NULL_PTR_CHECK_HALL_SPD_POS_FDB + } +#endif +} + +#ifdef NOT_IMPLEMENTED /* Not yet implemented */ +/** + * @brief It could be used to set istantaneous information on rotor mechanical + * angle. + * Note: Mechanical angle management is not implemented in this + * version of Hall sensor class. + * @param pHandle pointer on related component instance + * @param hMecAngle istantaneous measure of rotor mechanical angle + */ +__weak void HALL_SetMecAngle(HALL_Handle_t *pHandle, int16_t hMecAngle) {} +#endif +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/** @} */ + +/************************ (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/hall_speed_pos_fdbk.h b/src/firmware/motor/mcsdk/hall_speed_pos_fdbk.h new file mode 100644 index 0000000000..c71f740498 --- /dev/null +++ b/src/firmware/motor/mcsdk/hall_speed_pos_fdbk.h @@ -0,0 +1,241 @@ + +/** + ****************************************************************************** + * @file hall_speed_pos_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Hall Speed & Position Feedback component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup hall_speed_pos_fdbk + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef HALL_SPEEDNPOSFDBK_H +#define HALL_SPEEDNPOSFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednPosFdbk + * @{ + */ + + /** @addtogroup hall_speed_pos_fdbk + * @{ + */ + +#define HALL_SPEED_FIFO_SIZE ((uint8_t)18) + +/* HALL SENSORS PLACEMENT ----------------------------------------------------*/ +#define DEGREES_120 0u +#define DEGREES_60 1u + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief HALL component parameters definition + * + * + */ + + typedef struct + { + SpeednPosFdbk_Handle_t _Super; + /* SW Settings */ + uint8_t SensorPlacement; /*!< Define here the mechanical position of the sensors + with reference to an electrical cycle. + Allowed values are: DEGREES_120 or DEGREES_60.*/ + + int16_t PhaseShift; /*!< Define here in s16degree the electrical phase shift + between the low to high transition of signal H1 and + the maximum of the Bemf induced on phase A.*/ + + uint16_t SpeedSamplingFreqHz; /*!< Frequency (Hz) at which motor speed is to + be computed. It must be equal to the frequency + at which function SPD_CalcAvrgMecSpeedUnit + is called.*/ + + uint8_t SpeedBufferSize; /*!< Size of the buffer used to calculate the average + speed. It must be less than 18.*/ + + /* HW Settings */ + uint32_t TIMClockFreq; /*!< Timer clock frequency express in Hz.*/ + + TIM_TypeDef *TIMx; /*!< Timer used for HALL sensor management.*/ + + GPIO_TypeDef *H1Port; + /*!< HALL sensor H1 channel GPIO input port (if used, + after re-mapping). It must be GPIOx x= A, B, ...*/ + + uint32_t H1Pin; /*!< HALL sensor H1 channel GPIO output pin (if used, + after re-mapping). It must be GPIO_Pin_x x= 0, 1, + ...*/ + + GPIO_TypeDef *H2Port; + /*!< HALL sensor H2 channel GPIO input port (if used, + after re-mapping). It must be GPIOx x= A, B, ...*/ + + uint32_t H2Pin; /*!< HALL sensor H2 channel GPIO output pin (if used, + after re-mapping). It must be GPIO_Pin_x x= 0, 1, + ...*/ + + GPIO_TypeDef *H3Port; + /*!< HALL sensor H3 channel GPIO input port (if used, + after re-mapping). It must be GPIOx x= A, B, ...*/ + + uint32_t H3Pin; /*!< HALL sensor H3 channel GPIO output pin (if used, + after re-mapping). It must be GPIO_Pin_x x= 0, 1, + ...*/ + + uint32_t ICx_Filter; /*!< Input Capture filter selection */ + + bool SensorIsReliable; /*!< Flag to indicate a wrong configuration + of the Hall sensor signanls.*/ + + volatile bool RatioDec; /*!< Flag to avoid consecutive prescaler + decrement.*/ + volatile bool RatioInc; /*!< Flag to avoid consecutive prescaler + increment.*/ + volatile uint8_t FirstCapt; /*!< Flag used to discard first capture for + the speed measurement*/ + volatile uint8_t BufferFilled; /*!< Indicate the number of speed measuremt + present in the buffer from the start. + It will be max bSpeedBufferSize and it + is used to validate the start of speed + averaging. If bBufferFilled is below + bSpeedBufferSize the instantaneous + measured speed is returned as average + speed.*/ + volatile uint8_t OVFCounter; /*!< Count overflows if prescaler is too low + */ + + int32_t + SensorPeriod[HALL_SPEED_FIFO_SIZE]; /*!< Holding the last period captures */ + + uint8_t SpeedFIFOIdx; /*!< Pointer of next element to be stored in + the speed sensor buffer*/ + + int32_t ElPeriodSum; /* Period accumulator used to speed up the average speed + computation*/ + + int16_t PrevRotorFreq; /*!< Used to store the last valid rotor electrical + speed in dpp used when HALL_MAX_PSEUDO_SPEED + is detected */ + int8_t Direction; /*!< Instantaneous direction of rotor between two + captures*/ + + int16_t AvrElSpeedDpp; /*!< It is the averaged rotor electrical speed express + in s16degree per current control period.*/ + + uint8_t HallState; /*!< Current HALL state configuration */ + + int16_t DeltaAngle; /*!< Delta angle at the Hall sensor signal edge between + current electrical rotor angle of synchronism. + It is in s16degrees.*/ + int16_t MeasuredElAngle; /*!< This is the electrical angle measured at each + Hall sensor signal edge. It is considered the + best measurement of electrical rotor angle.*/ + + int16_t IncrementElAngle; /*!< This is the cumulated electrical angle between + two consecutive Hall sensor commutations.*/ + + int16_t CompSpeed; /*!< Speed compensation factor used to syncronize + the current electrical angle with the target + electrical angle. */ + + uint16_t HALLMaxRatio; /*!< Max TIM prescaler ratio defining the lowest + expected speed feedback.*/ + uint16_t SatSpeed; /*!< Returned value if the measured speed is above the + maximum realistic.*/ + uint32_t PseudoFreqConv; /*!< Conversion factor between time interval Delta T + between HALL sensors captures, express in timer + counts, and electrical rotor speed express in dpp. + Ex. Rotor speed (dpp) = wPseudoFreqConv / Delta T + It will be ((CKTIM / 6) / (SAMPLING_FREQ)) * 65536.*/ + + uint32_t MaxPeriod; /*!< Time delay between two sensor edges when the speed + of the rotor is the minimum realistic in the + application: this allows to discriminate too low + freq for instance. + This period shoud be expressed in timer counts and + it will be: + wMaxPeriod = ((10 * CKTIM) / 6) / MinElFreq(0.1Hz).*/ + + uint32_t MinPeriod; + /*!< Time delay between two sensor edges when the speed + of the rotor is the maximum realistic in the + application: this allows discriminating glitches + for instance. + This period shoud be expressed in timer counts and + it will be: + wSpeedOverflow = ((10 * CKTIM) / 6) / MaxElFreq(0.1Hz).*/ + + uint16_t HallTimeout; /*!< Max delay between two Hall sensor signal to assert + zero speed express in milliseconds.*/ + + uint16_t OvfFreq; /*!< Frequency of timer overflow (from 0 to 0x10000) + it will be: hOvfFreq = CKTIM /65536.*/ + uint16_t PWMNbrPSamplingFreq; /*!< Number of current control periods inside + each speed control periods it will be: + (hMeasurementFrequency / hSpeedSamplingFreqHz) - 1.*/ + uint8_t PWMFreqScaling; /*!< Scaling factor to allow to store a PWMFrequency + greater than 16 bits */ + + bool HallMtpa; /* if true at each sensor toggling, the true angle is set without + ramp*/ + + } HALL_Handle_t; + + void *HALL_TIMx_UP_IRQHandler(void *pHandleVoid); + void *HALL_TIMx_CC_IRQHandler(void *pHandleVoid); + void HALL_Init(HALL_Handle_t *pHandle); + void HALL_Clear(HALL_Handle_t *pHandle); + int16_t HALL_CalcElAngle(HALL_Handle_t *pHandle); + bool HALL_CalcAvrgMecSpeedUnit(HALL_Handle_t *pHandle, int16_t *hMecSpeedUnit); +#ifdef NOT_IMPLEMENTED /* Not yet implemented */ + void HALL_SetMecAngle(HALL_Handle_t *pHandle, int16_t hMecAngle); +#endif + /** + * @} + */ + + /** + * @} + */ + + /** @} */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /*HALL_SPEEDNPOSFDBK_H*/ +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/ics_dd_pwmncurrfdbk.h b/src/firmware/motor/mcsdk/ics_dd_pwmncurrfdbk.h new file mode 100644 index 0000000000..5150498693 --- /dev/null +++ b/src/firmware/motor/mcsdk/ics_dd_pwmncurrfdbk.h @@ -0,0 +1,125 @@ +/** + ****************************************************************************** + * @file ics_dd_pwmncurrfdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * ICS DD PWM current feedback component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup PWMnCurrFdbk_ICS_DD + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ICS_DD_PWMNCURRFDBK_H +#define __ICS_DD_PWMNCURRFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup pwm_curr_fdbk + * @{ + */ + + /** @defgroup PWMnCurrFdbk_ICS_DD Insulated Current Sensing Parameters + * + * @brief Common definitions for Insulated Current Sensors based PWM & Current + * Feedback components + * @{ + */ + +#define GPIO_NoRemap_TIM1 ((uint32_t)(0)) +#define SHIFTED_TIMs ((uint8_t)1) +#define NO_SHIFTED_TIMs ((uint8_t)0) + + + /** + * @brief ICS_DD parameters definition + */ + typedef struct + { + TIM_TypeDef *TIMx; /**< It contains the pointer to the timer + used for PWM generation. It must + equal to TIM1 if bInstanceNbr is + equal to 1, to TIM8 otherwise */ + GPIO_TypeDef *pwm_en_u_port; /**< enable signal phase U port.*/ + GPIO_TypeDef *pwm_en_v_port; /**< enable signal phase V port.*/ + GPIO_TypeDef *pwm_en_w_port; /**< enable signal phase W port.*/ + uint32_t pwm_en_u_pin; /**< enable signal phase U pin.*/ + uint32_t pwm_en_v_pin; /**< enable signal phase V pin.*/ + uint32_t pwm_en_w_pin; /**< enable signal phase W pin.*/ + uint16_t Tw; /**< It is used for switching the context + in dual MC. It contains biggest delay + (expressed in counter ticks) between + the counter crest and ADC latest + trigger */ + uint8_t InstanceNbr; /**< Instance number with reference to PWMC + base class. It is necessary to properly + synchronize TIM8 with TIM1 at + peripheral initializations */ + uint8_t FreqRatio; /**< It is used in case of dual MC to + synchronize TIM1 and TIM8. It has + effect only on the second instanced + object and must be equal to the + ratio between the two PWM frequencies + (higher/lower). Supported values are + 1, 2 or 3 */ + uint8_t IsHigherFreqTim; /**< When bFreqRatio is greather than 1 + this param is used to indicate if this + instance is the one with the highest + frequency. Allowed value are: HIGHER_FREQ + or LOWER_FREQ */ + uint8_t IaChannel; /**< ADC channel used for conversion of + current Ia. It must be equal to + ADC_CHANNEL_x x= 0, ..., 15*/ + uint8_t IbChannel; /**< ADC channel used for conversion of + current Ib. It must be equal to + ADC_CHANNEL_x x= 0, ..., 15*/ + uint8_t RepetitionCounter; /**< It expresses the number of PWM + periods to be elapsed before compare + registers are updated again. In + particular: + RepetitionCounter= (2* #PWM periods)-1 + */ + LowSideOutputsFunction_t LowSideOutputs; /**< Low side or enabling signals + generation method are defined + here.*/ + /* Emergency input signal initialization -------------------------------------*/ + FunctionalState EmergencyStop; /**< It enable/disable the management of + an emergency input instantaneously + stopping PWM generation. It must be + either equal to ENABLE or DISABLE */ + } ICS_Params_t; + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /*__ICS_DD_PWMNCURRFDBK_H*/ +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/inrush_current_limiter.c b/src/firmware/motor/mcsdk/inrush_current_limiter.c new file mode 100644 index 0000000000..1d1b1aacd7 --- /dev/null +++ b/src/firmware/motor/mcsdk/inrush_current_limiter.c @@ -0,0 +1,169 @@ +/** + ****************************************************************************** + * @file inrush_current_limiter.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions implementing the + * Inrush Current Limiter feature of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup ICL + */ + +/* Includes ------------------------------------------------------------------*/ +#include "inrush_current_limiter.h" + +#include "mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup ICL Inrush Current Limiter + * @brief Inrush Current Limiter component of the Motor Control SDK + * + * Inrush current limiter acts on the NTC bypass relay according to the DC bus level in + * order to limit the current when charging DC bulk capacitor. + * In order to work properly, it needs to point on the Vbus and digital output handlers + * to measure the DC bus and control the NTC bypass relay. Inrush current limiter has + * its own state machine described below: + * + * ![](ICL_FSM.svg) + * + * @{ + */ + + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Initializes all the needed ICL component variables. + * It shall be called only once during Motor Control initialization. + * @param pHandle: handler of the current instance of the ICL component + * @param pVBS the bus voltage sensor used by the ICL. + * @param pDOUT the digital output used by the ICL. + */ +__weak void ICL_Init(ICL_Handle_t *pHandle, BusVoltageSensor_Handle_t *pVBS, + DOUT_handle_t *pDOUT) +{ + pHandle->pVBS = pVBS; + pHandle->pDOUT = pDOUT; + DOUT_SetOutputState(pDOUT, ACTIVE); +} + +/** + * @brief Executes the inrush current limiter state machine and shall be + * called during background task. + * @param pHandle handler of the current instance of the ICL component + * @retval ICLState_t returns the current ICL state machine + */ +__weak ICL_State_t ICL_Exec(ICL_Handle_t *pHandle) +{ + /* ICL actions.*/ + switch (pHandle->ICLstate) + { + case ICL_ACTIVATION: + { + /* ICL activation: counting the step before pass in ICL_ACTIVE */ + if (pHandle->hICLTicksCounter == 0u) + { + pHandle->ICLstate = ICL_ACTIVE; + pHandle->hICLTicksCounter = pHandle->hICLChargingDelayTicks; + } + else + { + pHandle->hICLTicksCounter--; + } + } + break; + + case ICL_DEACTIVATION: + { + /* ICL deactivation: counting the step before pass in ICL_INACTIVE.*/ + if (pHandle->hICLTicksCounter == 0u) + { + pHandle->ICLstate = ICL_INACTIVE; + } + else + { + pHandle->hICLTicksCounter--; + } + } + break; + + case ICL_ACTIVE: + { + /* ICL is active: if bus is present and capacitor charging time elapsed*/ + if (pHandle->hICLTicksCounter == 0u) + { + if (VBS_GetAvBusVoltage_d(pHandle->pVBS) > pHandle->hICLVoltageThreshold) + { + DOUT_SetOutputState(pHandle->pDOUT, INACTIVE); + pHandle->ICLstate = ICL_DEACTIVATION; + pHandle->hICLTicksCounter = pHandle->hICLSwitchDelayTicks; + } + } + else + { + pHandle->hICLTicksCounter--; + } + } + break; + + case ICL_INACTIVE: + { + /* ICL is inactive: if bus is not present activate the ICL */ + if (VBS_CheckVbus(pHandle->pVBS) == MC_UNDER_VOLT) + { + DOUT_SetOutputState(pHandle->pDOUT, ACTIVE); + pHandle->ICLstate = ICL_ACTIVATION; + pHandle->hICLTicksCounter = pHandle->hICLSwitchDelayTicks; + } + } + break; + + case ICL_IDLE: + default: + { + } + break; + } + + return pHandle->ICLstate; +} + + +/** + * @brief Returns the current state of the ICL state machine. + * @param pHandle: handler of the current instance of the ICL component + * @retval ICLState_t returns the current ICL state machine + */ +__weak ICL_State_t ICL_GetState(ICL_Handle_t *pHandle) +{ + return pHandle->ICLstate; +} + + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/inrush_current_limiter.h b/src/firmware/motor/mcsdk/inrush_current_limiter.h new file mode 100644 index 0000000000..9d92cddaa1 --- /dev/null +++ b/src/firmware/motor/mcsdk/inrush_current_limiter.h @@ -0,0 +1,130 @@ +/** + ****************************************************************************** + * @file inrush_current_limiter.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Inrush Current Limiter component featuring the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup ICL + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __INRUSHCURRENTLIMITER_H +#define __INRUSHCURRENTLIMITER_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "bus_voltage_sensor.h" +#include "digital_output.h" +#include "mc_type.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup ICL + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /** + * @brief ICL_State_t defines all the existing ICL states of the state machine + */ + typedef enum + { + ICL_IDLE, /**< @brief stable state */ + ICL_ACTIVATION, /**< @brief transition state */ + ICL_ACTIVE, /**< @brief stable state */ + ICL_DEACTIVATION, /**< @brief transition state */ + ICL_INACTIVE /**< @brief stable state */ + } ICL_State_t; + + + /** + * @brief ICL_Handle_t is used to handle an instance of the InrushCurrentLimiter + * component + */ + typedef struct + { + BusVoltageSensor_Handle_t *pVBS; /**< @brief Vbus handler used for the automatic + ICL component activation/deactivation */ + DOUT_handle_t *pDOUT; /**< @brief digital output handler used to physically + activate/deactivate the ICL component */ + ICL_State_t ICLstate; /**< @brief Current state of the ICL state machine */ + uint16_t hICLTicksCounter; /**< @brief Buffer variable containing the number of + clock events remaining for next state transition */ + uint16_t hICLSwitchDelayTicks; /**< @brief ICL activation/deactivation delay due + to switching action of relay (expressed in ICL + FSM execution ticks) */ + uint16_t hICLChargingDelayTicks; /**< @brief Input capacitors charging delay to be + waited before closing relay (expressed in ICL + FSM execution ticks)*/ + uint16_t hICLVoltageThreshold; /**< @brief Voltage threshold to be reached on Vbus + before closing the relay */ + } ICL_Handle_t; + + + /* Exported constants --------------------------------------------------------*/ + /* Exported macro ------------------------------------------------------------*/ + /* Exported functions ------------------------------------------------------- */ + + /* Initializes all the needed ICL component variables */ + void ICL_Init(ICL_Handle_t *pHandle, BusVoltageSensor_Handle_t *pVBS, + DOUT_handle_t *pDOUT); + + /* Executes the Inrush Current Limiter state machine */ + ICL_State_t ICL_Exec(ICL_Handle_t *pHandle); + + /* Returns the current state of the ICL state machine. */ + ICL_State_t ICL_GetState(ICL_Handle_t *pHandle); + + /** + * @brief Converts the VoltageThreshold configured by the user and updates the + * passed ICL's component threshold value in u16V (bus sensor units) + * @param pHandle: handler of the current instance of the ICL component + * @param hVoltageThreshold : threshold configured by the user to be applied in ICL + * FSM (expressed in Volts) + */ + inline static void ICL_SetVoltageThreshold(ICL_Handle_t *pHandle, + int16_t hVoltageThreshold) + { + uint32_t temp; + + temp = (uint32_t)hVoltageThreshold; + temp *= 65536U; + temp /= pHandle->pVBS->ConversionFactor; + + pHandle->hICLVoltageThreshold = (uint16_t)temp; + } + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* __INRUSHCURRENTLIMITER_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/max_torque_per_ampere.c b/src/firmware/motor/mcsdk/max_torque_per_ampere.c new file mode 100644 index 0000000000..e18402767d --- /dev/null +++ b/src/firmware/motor/mcsdk/max_torque_per_ampere.c @@ -0,0 +1,143 @@ +/** + ****************************************************************************** + * @file max_torque_per_ampere.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Maximum Torque Per Ampere (MTPA) Control component of the Motor Control + *SDK: + * + * * Initialize the parameter for MTPA + * * Calculate and output id and iq reference based on torque input + * * Calculate and output id based on iq input + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + * @ingroup MTPA + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/max_torque_per_ampere.h" + +#include + +#include "firmware/motor/common_defs.h" +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup MTPA Maximum Torque Per Ampere Control + * @brief Maximum Torque Per Ampere (MTPA) Control component of the Motor Control SDK + * + * The torque of the PMSM can be expressed with the equation shown below: + * + * @f[ + * T_e = \frac{3}{2}\times p \times \phi \times i_q + \frac{3}{2}\times + * p\times(L_d-L_q)\times i_q\times i_d + * @f] + * + * When the motor is a surface mount permanent magnet synchronous motor (SM-PMSM), the + * @f$ L_d @f$ and @f$ L_q @f$ are almost the same, so only the @f$ i_q @f$ can influence + * the torque. For internal permanent magnet synchronous motor (I-PMSM), the @f$ L_d @f$ + * is not equal to @f$ L_q @f$. Both @f$ i_d @f$ and @f$ i_q @f$ will influence the + * torque. The aim of the MTPA (maximum-torque-per-ampere) control is to calculate the + * reference currents which maximize the ratio between produced + * electromagnetic torque and copper losses. + * The input of this component + * is the @f$ i_q @f$ reference. The output of this component is @f$ i_d @f$ reference. + * + * @{ + */ + +/** + * @brief Calculates the Id current reference based on input Iq current reference + * @param pHandle Handle on the MTPA component + * @param Iqdref current reference in the Direct-Quadratic reference frame. Expressed + * in the qd_t format. + * + */ +__weak void MTPA_CalcCurrRefFromIq(const MTPA_Handle_t *pHandle, qd_t *Iqdref) +{ +#ifdef NULL_PTR_CHECK_MAX_TRQ_PER_AMP + if ((NULL == pHandle) || (NULL == Iqdref)) + { + /* Nothing to do */ + } + else + { +#endif + int32_t id; + int16_t aux; + int16_t iq; + uint8_t segment; + + iq = ((Iqdref->q < 0) ? (-Iqdref->q) : (Iqdref->q)); /* Teref absolute value */ + + aux = iq / pHandle->SegDiv; + segment = (uint8_t)aux; + + if (segment > SEGMENT_NUM) + { + segment = SEGMENT_NUM; + } + else + { + /* Nothing to do */ + } + +#ifndef FULL_MISRA_C_COMPLIANCY_MAX_TOR + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + id = ((pHandle->AngCoeff[segment] * iq) >> 15) + pHandle->Offset[segment]; +#else + id = ((pHandle->AngCoeff[segment] * iq) / 32768) + pHandle->Offset[segment]; +#endif + Iqdref->d = (int16_t)id; +#ifdef NULL_PTR_CHECK_MAX_TRQ_PER_AMP + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/max_torque_per_ampere.h b/src/firmware/motor/mcsdk/max_torque_per_ampere.h new file mode 100644 index 0000000000..d0b85720a0 --- /dev/null +++ b/src/firmware/motor/mcsdk/max_torque_per_ampere.h @@ -0,0 +1,72 @@ +/** + ****************************************************************************** + * @file max_torque_per_ampere.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief Maximum torque per ampere (MTPA) control for I-PMSM motors + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MTPA + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MAXTORQUEPERAMPERE_H +#define MAXTORQUEPERAMPERE_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup MTPA Maximum Torque Per Ampere Control + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +#define SEGMENT_NUM 7U /* coeff no. -1 */ +#define MTPA_ARRAY_SIZE SEGMENT_NUM + 1U + /** + * @brief Handle structure of max_torque_per_ampere.c + */ + typedef struct + { + int16_t SegDiv; /**< Segments divisor */ + int32_t AngCoeff[MTPA_ARRAY_SIZE]; /**< Angular coefficients table */ + int32_t Offset[MTPA_ARRAY_SIZE]; /**< Offsets table */ + } MTPA_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /* Calculates the Id current ref based on input Iq current */ + void MTPA_CalcCurrRefFromIq(const MTPA_Handle_t *pHandle, qd_t *Iqdref); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* MAXTORQUEPERAMPERE_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/mc_stm_types.h b/src/firmware/motor/mcsdk/mc_stm_types.h new file mode 100644 index 0000000000..19c2ca8070 --- /dev/null +++ b/src/firmware/motor/mcsdk/mc_stm_types.h @@ -0,0 +1,223 @@ + +/** + ****************************************************************************** + * @file mc_stm_types.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief Includes HAL/LL headers relevant to the current configuration. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +#ifndef MC_STM_TYPES_H +#define MC_STM_TYPES_H + +#ifdef FULL_MISRA_C_COMPLIANCY +#define FULL_MISRA_C_COMPLIANCY_ENC_SPD_POS +#define FULL_MISRA_C_COMPLIANCY_FWD_FDB +#define FULL_MISRA_C_COMPLIANCY_FLUX_WEAK +#define FULL_MISRA_C_COMPLIANCY_MAX_TOR +#define FULL_MISRA_C_COMPLIANCY_MC_MATH +#define FULL_MISRA_C_COMPLIANCY_NTC_TEMP +#define FULL_MISRA_C_COMPLIANCY_PID_REGULATOR +#define FULL_MISRA_C_COMPLIANCY_PFC +#define FULL_MISRA_C_COMPLIANCY_PWM_CURR +#define FULL_MISRA_C_COMPLIANCY_PW_CURR_FDB_OVM +#define FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL +#define FULL_MISRA_C_COMPLIANCY_STO_CORDIC +#define FULL_MISRA_C_COMPLIANCY_STO_PLL +#define FULL_MISRA_C_COMPLIANCY_VIRT_SPD_SENS +#endif + +#ifdef NULL_PTR_CHECK +#define NULL_PTR_CHECK_ASP +#define NULL_PTR_CHECK_BUS_VOLT +#define NULL_PTR_CHECK_CRC_LIM +#define NULL_PTR_CHECK_DAC_UI +#define NULL_PTR_CHECK_DIG_OUT +#define NULL_PTR_CHECK_ENC_ALI_CTRL +#define NULL_PTR_CHECK_ENC_SPD_POS_FDB +#define NULL_PTR_CHECK_FEED_FWD_CTRL +#define NULL_PTR_CHECK_FLUX_WEAK +#define NULL_PTR_CHECK_HALL_SPD_POS_FDB +#define NULL_PTR_CHECK_MAX_TRQ_PER_AMP +#define NULL_PTR_CHECK_MCP +#define NULL_PTR_CHECK_MCPA +#define NULL_PTR_CHECK_MC_INT +#define NULL_PTR_CHECK_MC_PERF +#define NULL_PTR_CHECK_MOT_POW_MES +#define NULL_PTR_CHECK_NTC_TEMP_SENS +#define NULL_PTR_CHECK_OPEN_LOOP +#define NULL_PTR_CHECK_PID_REG +#define NULL_PTR_CHECK_POT +#define NULL_PTR_CHECK_POW_COM +#define NULL_PTR_CHECK_PQD_MOT_POW_MEAS +#define NULL_PTR_CHECK_PWR_CUR_FDB +#define NULL_PTR_CHECK_PWM_CUR_FDB_OVM +#define NULL_PTR_CHECK_RDIV_BUS_VLT_SNS +#define NULL_PTR_CHECK_REG_CON_MNG +#define NULL_PTR_CHECK_REG_INT +#define NULL_PTR_CHECK_REV_UP_CTL +#define NULL_PTR_CHECK_RMP_EXT_MNG +#define NULL_PTR_CHECK_R1_PS_PWR_CUR_FDB +#define NULL_PTR_CHECK_R3_2_PWM_CURR_FDB +#define NULL_PTR_CHECK_SPD_POS_FBK +#define NULL_PTR_CHECK_SPD_POT +#define NULL_PTR_CHECK_SPD_REG_POT +#define NULL_PTR_CHECK_SPD_TRQ_CTL +#define NULL_PTR_CHECK_STL_MNG +#define NULL_PTR_CHECK_STO_COR_SPD_POS_FDB +#define NULL_PTR_CHECK_STO_PLL_SPD_POS_FDB +#define NULL_PTR_CHECK_USA_ASP_DRV +#define NULL_PTR_CHECK_VIR_SPD_SEN +#endif + +#ifndef USE_FULL_LL_DRIVER +#define USE_FULL_LL_DRIVER +#endif + +#include + +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_adc.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_bus.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_comp.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_dac.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_dma.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_gpio.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_rcc.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_system.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_tim.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_ll_usart.h" + +/* Make this define visible for all projects */ +#define NBR_OF_MOTORS 1 + +__STATIC_INLINE void LL_DMA_ClearFlag_TC(DMA_TypeDef *DMAx, uint32_t Channel) +{ + if (NULL == DMAx) + { + /* Nothing to do */ + } + else + { + /* Clear TC bits with bits position depending on parameter "Channel" */ + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF1 << ((Channel - LL_DMA_CHANNEL_1) << 2)); + } +} + +// cstat !MISRAC2012-Rule-8.13 +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC(DMA_TypeDef *DMAx, uint32_t Channel) +{ + return ((NULL == DMAx) + ? 0U + : ((READ_BIT(DMAx->ISR, + (DMA_ISR_TCIF1 << ((Channel - LL_DMA_CHANNEL_1) << 2))) == + (DMA_ISR_TCIF1 << ((Channel - LL_DMA_CHANNEL_1) << 2))) + ? 1UL + : 0UL)); +} +// cstat !MISRAC2012-Rule-8.13 +__STATIC_INLINE void LL_DMA_ClearFlag_HT(DMA_TypeDef *DMAx, uint32_t Channel) +{ + if (NULL == DMAx) + { + /* Nothing to do */ + } + else + { + /* Clear HT bits with bits position depending on parameter "Channel" */ + WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF1 << ((Channel - LL_DMA_CHANNEL_1) << 2)); + } +} +// cstat !MISRAC2012-Rule-8.13 +__STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT(DMA_TypeDef *DMAx, uint32_t Channel) +{ + return ((NULL == DMAx) + ? 0U + : ((READ_BIT(DMAx->ISR, + (DMA_ISR_HTIF1 << ((Channel - LL_DMA_CHANNEL_1) << 2))) == + (DMA_ISR_HTIF1 << ((Channel - LL_DMA_CHANNEL_1) << 2))) + ? 1UL + : 0UL)); +} + +/* + * Get ADC group regular conversion data, range fit for + * ADC resolution 12 bits Left Aligned. + * param ADCx ADC instance + * retval Value between Min_Data=0x0000 and Max_Data=0xFFF0 + */ +__STATIC_INLINE uint16_t LL_ADC_REG_ReadConversionData12L(const ADC_TypeDef *ADCx) +{ + return (uint16_t)(READ_REG(ADCx->DR) & 0x0000FFF0UL); +} + +#define CIRCLE_LIMITATION_SQRT_M0 + +/** + * @name Predefined Speed Units + * + * Each of the following symbols defines a rotation speed unit that can be used by the + * functions of the API for their speed parameter. Each Unit is defined by expressing + * the value of 1 Hz in this unit. + * + * These symbols can be used to set the #SPEED_UNIT macro which defines the rotation speed + * unit used by the functions of the API. + * + * @anchor SpeedUnit + */ +/** @{ */ +/** Revolutions Per Minute: 1 Hz is 60 RPM */ +#define U_RPM 60 +/** Tenth of Hertz: 1 Hz is 10 01Hz */ +#define U_01HZ 10 +/* Hundreth of Hertz: 1 Hz is 100 001Hz */ +/* #define _001HZ 100 */ +/** @} */ + +/* USER CODE BEGIN DEFINITIONS */ +/* Definitions placed here will not be erased by code generation */ +/** + * @brief Rotation speed unit used at the interface with the application + * + * This symbols defines the value of 1 Hertz in the unit used by the functions of the API + * for their speed parameters. + * + * For instance, if the chosen unit is the RPM, SPEED_UNIT is defined to 60, since 1 Hz is + * 60 RPM. The default unit is #U_01HZ, set on the initial generation of the project by + * the Workbench. As this symbol is defined in a User Section, custom values set by users + * persist across project regeneration. + * + * PID parameters computed by the Motor Control Workbench for speed regulation are + * suited for a speed in 01Hz. The motor control subsystem internally scales them to adapt + * to the actual speed unit. + * + * This symbol should not be set to a literal numeric value. Rather, it should be set to + * one of the symbols predefined for that purpose such as #U_RPM, #U_01HZ,... See @ref + * SpeedUnit for more details. + * + * Refer to the documentation of the @ref MCIAPI for the functions that use this unit. + * + * @{ + */ +#define SPEED_UNIT U_RPM + +/* USER CODE END DEFINITIONS */ +/*!< Convenient macro to convert user friendly RPM into SpeedUnit used by MC API */ +#define RPM_2_SPEED_UNIT(rpm) ((int16_t)(((rpm)*SPEED_UNIT) / U_RPM)) +/*!< Convenient macro to convert SpeedUnit used by MC API into user friendly RPM */ +#define SPEED_UNIT_2_RPM(speed) ((int16_t)(((speed)*U_RPM) / SPEED_UNIT)) +/** + * @} + */ + +#endif /* MC_STM_TYPES_H */ +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/mc_type.h b/src/firmware/motor/mcsdk/mc_type.h new file mode 100644 index 0000000000..97068e0209 --- /dev/null +++ b/src/firmware/motor/mcsdk/mc_type.h @@ -0,0 +1,461 @@ +/** + ****************************************************************************** + * @file mc_type.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief Motor Control SDK global types definitions + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MC_Type + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MC_TYPE_H +#define MC_TYPE_H + +/* Includes ------------------------------------------------------------------*/ + +#include +#include +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup MC_Type Motor Control types + * @{ + */ + +#include "firmware/motor/mcsdk/mc_stm_types.h" + + /* char definition to match Misra Dir 4.6 typedefs that indicate size and + * signedness should be used in place ofthe basic numerical types */ + typedef int8_t char_t; + +#ifndef _MATH + typedef float float_t; +#endif + +/** @name Macros to use bit banding capability */ +/** @{ */ +#define BB_REG_BIT_SET(regAddr, bit_number) \ + *(uint32_t *)(0x42000000 + (((uint32_t)regAddr - 0x40000000) << 5) + \ + (bit_number << 2)) = (uint32_t)(0x1u) +#define BB_REG_BIT_CLR(regAddr, bit_number) \ + (*(uint32_t *)(0x42000000 + (((uint32_t)regAddr - 0x40000000) << 5) + \ + (bit_number << 2)) = (uint32_t)(0x0u)) +#define BB_REG_BIT_READ(regAddr, bit_number) \ + (*(uint32_t *)(0x42000000 + (((uint32_t)regAddr - 0x40000000) << 5) + \ + (bit_number << 2))) +/** @} */ + +/** @brief Not initialized pointer */ +#define MC_NULL (void *)(0x0) + +/** @name Motor identification macros */ +/** @{ */ +#define M1 (uint8_t)(0x0) /*!< Motor 1.*/ +#define M2 (uint8_t)(0x1) /*!< Motor 2.*/ +#define M_NONE (uint8_t)(0xFF) /*!< None motor.*/ +/** @} */ + +/** + * @anchor fault_codes + * @name Fault codes + * The symbols below define the codes associated to the faults that the + * Motor Control subsystem can raise. + * @{ */ +#define MC_NO_ERROR ((uint16_t)0x0000) /**< @brief No error. */ +#define MC_NO_FAULTS ((uint16_t)0x0000) /**< @brief No error. */ +#define MC_DURATION ((uint16_t)0x0001) /**< @brief Error: FOC rate to high. */ +#define MC_OVER_VOLT ((uint16_t)0x0002) /**< @brief Error: Software over voltage. */ +#define MC_UNDER_VOLT ((uint16_t)0x0004) /**< @brief Error: Software under voltage. */ +#define MC_OVER_TEMP ((uint16_t)0x0008) /**< @brief Error: Software over temperature. */ +#define MC_START_UP ((uint16_t)0x0010) /**< @brief Error: Startup failed. */ +#define MC_SPEED_FDBK ((uint16_t)0x0020) /**< @brief Error: Speed feedback. */ +#define MC_OVER_CURR \ + ((uint16_t)0x0040) /**< @brief Error: Emergency input (Over current). */ +#define MC_SW_ERROR ((uint16_t)0x0080) /**< @brief Software Error. */ +#define MC_DP_FAULT ((uint16_t)0x0400) /**< @brief Error Driver protection fault. */ + +/** @}*/ + +/** @name Dual motor Frequency comparison definition */ +/** @{ */ +#define SAME_FREQ 0U +#define HIGHER_FREQ 1U +#define LOWER_FREQ 2U + +#define HIGHEST_FREQ 1U +#define LOWEST_FREQ 2U +/** @} */ + +/** @name Error codes */ +/** @{ */ +#define MC_SUCCESS ((uint32_t)(0u)) /**< Success. The function executed successfully. */ +#define MC_WRONG_STATE_ERROR \ + ((uint32_t)(1u)) /**< The state machine of the motor is not in a suitable state. */ +#define MC_NO_POLARIZATION_OFFSETS_ERROR \ + ((uint32_t)(2u)) /**< Polarization offsets are needed but missing */ + + /** @} */ + + /** @brief Return type of API functions that return a status */ + typedef uint32_t MC_RetStatus_t; + + /** + * @brief union type definition for u32 to Float conversion and vice versa + */ + // cstat -MISRAC2012-Rule-19.2 + typedef union _FLOAT_U32_ + { + uint32_t U32_Val; + float Float_Val; + } FloatToU32; + // cstat +MISRAC2012-Rule-19.2 + + /** + * @brief Two components q, d type definition + */ + typedef struct + { + int16_t q; + int16_t d; + } qd_t; + + /** + * @brief Two components q, d in float type + */ + + typedef struct + { + float q; + float d; + } qd_f_t; + + /** + * @brief Two components a,b type definition + */ + typedef struct + { + int16_t a; + int16_t b; + } ab_t; + + /** + * @brief Two components a,b in float type + */ + typedef struct + { + float a; + float b; + } ab_f_t; + + /** + * @brief Two components alpha, beta type definition + */ + typedef struct + { + int16_t alpha; + int16_t beta; + } alphabeta_t; + + /* ACIM definitions start */ + typedef struct + { + float fS_Component1; + float fS_Component2; + } Signal_Components; + + /** + * @brief Two components type definition + */ + typedef struct + { + int16_t qVec_Component1; + int16_t qVec_Component2; + } Vector_s16_Components; + /* ACIM definitions end */ + + /** + * @brief SensorType_t type definition, it's used in BusVoltageSensor and + * TemperatureSensor component parameters structures to specify whether the sensor is + * real or emulated by SW. + */ + typedef enum + { + REAL_SENSOR, + VIRTUAL_SENSOR + } SensorType_t; + + /** + * @brief DOutputState_t type definition, it's used by DOUT_SetOutputState method of + * DigitalOutput class to specify the required output state. + */ + typedef enum + { + INACTIVE, + ACTIVE + } DOutputState_t; + + /** + * @brief DrivingMode_t type definition, it's used by Bemf_ADC class to specify the + * driving mode type. + */ + typedef enum + { + VM, /**< @brief Voltage mode. */ + CM /**< @brief Current mode. */ + } DrivingMode_t; + + /** + * @brief Specifies the control modality of the motor. + */ + typedef enum + { + MCM_OBSERVING_MODE = + 0, /**< @brief All transistors are opened in order to let the motor spin + * freely and observe Bemf thanks to phase voltage measurements. + * + * Only relevant when HSO is used. + */ + MCM_OPEN_LOOP_VOLTAGE_MODE, /**< @brief Open loop, duty cycle set as reference. */ + MCM_OPEN_LOOP_CURRENT_MODE, /**< @brief Open loop, q & d currents set as + reference. */ + MCM_SPEED_MODE, /**< @brief Closed loop, Speed mode.*/ + MCM_TORQUE_MODE, /**< @brief Closed loop, Torque mode.*/ + MCM_PROFILING_MODE, /**< @brief FW is configured to execute the motor profiler + * feature. + * + * Only relevant when HSO is used. + */ + MCM_SHORTED_MODE, /**< @brief Low sides are turned on. + * + * Only relevant when HSO is used. + */ + MCM_POSITION_MODE, /**< @brief Closed loop, sensored position control mode. */ + MCM_MODE_NUM /**< @brief Number of modes in enum. */ + } MC_ControlMode_t; + + /** + * @brief Structure type definition for feed-forward constants tuning. + */ + typedef struct + { + int32_t wConst_1D; + int32_t wConst_1Q; + int32_t wConst_2; + } FF_TuningStruct_t; + + /** + * @brief structure type definition for phase offsets setting/getting. In case of + * single shunt only phaseAOffset is relevant. + */ + typedef struct + { + int32_t phaseAOffset; + int32_t phaseBOffset; + int32_t phaseCOffset; + } PolarizationOffsets_t; + + /** + * @brief Current references source type, internal or external to FOCDriveClass. + */ + typedef enum + { + INTERNAL, + EXTERNAL + } CurrRefSource_t; + + /** + * @brief FOC variables structure. + */ + typedef struct + { // cstat !MISRAC2012-Dir-4.8 + + ab_t Iab; /**< @brief Stator current on stator reference frame abc. + * + * @note This field does not exists if HSO is used. + */ + alphabeta_t + Ialphabeta; /**< @brief Stator current on stator reference frame alfa-beta. + * + * @note This field does not exists if HSO is used. + */ + qd_t IqdHF; /**< @brief Stator current on stator reference frame alfa-beta. + * + * @note This field does not exists if HSO is used. + */ + qd_t Iqd; /**< @brief Stator current on rotor reference frame qd. + * + * @note This field does not exists if HSO is used. + */ + qd_t Iqdref; /**< @brief Stator current on rotor reference frame qd. + * + * @note This field does not exists if HSO is used. + */ + int16_t UserIdref; /**< @brief User value for the Idref stator current. + * + * @note This field does not exists if HSO is used. + */ + qd_t Vqd; /**< @brief Phase voltage on rotor reference frame qd. + * + * @note This field does not exists if HSO is used. + */ + alphabeta_t + Valphabeta; /**< @brief Phase voltage on stator reference frame alpha-beta. + * + * @note This field does not exists if HSO is used. + */ + int16_t hTeref; /**< @brief Reference torque. + * + * @note This field does not exists if HSO is used. + */ + int16_t hElAngle; /**< @brief Electrical angle used for reference frame + * transformation. + * + * @note This field does not exists if HSO is used. + */ + uint16_t hCodeError; /**< @brief Error Code. + * + * @note This field does not exists if HSO is used. + */ + CurrRefSource_t bDriveInput; /**< @brief Specifies whether the current reference + * source must be #INTERNAL or #EXTERNAL. + * + * @note This field does not exists if HSO is used. + */ + } FOCVars_t, *pFOCVars_t; + + /** + * @brief 6step variables structure. + */ + typedef struct + { + uint16_t DutyCycleRef; /**< @brief Reference speed. */ + uint16_t hCodeError; /**< @brief error message. */ + CurrRefSource_t + bDriveInput; /**< @brief It specifies whether the current reference source + * must be #INTERNAL or #EXTERNAL. */ + int16_t qElAngle; + } SixStepVars_t, *pSixStepVars_t; + + /** + * @brief Low side or enabling signal definition. + */ + + typedef enum + { + LS_DISABLED = 0x0U, /**< @brief Low side signals and enabling signals always off. + It is equivalent to DISABLED. */ + LS_PWM_TIMER = 0x1U, /**< @brief Low side PWM signals are generated by timer. + It is equivalent to ENABLED. */ + ES_GPIO = 0x2U /**< @brief Enabling signals are managed by GPIOs (L6230 mode). */ + } LowSideOutputsFunction_t; + +/** @name UserInterface related exported definitions. */ +/** @{ */ +#define OPT_NONE 0x00 /**< @brief No UI option selected. */ +#define OPT_COM \ + 0x02 /**< @brief Bit field indicating that the UI uses serial communication. */ +#define OPT_DAC 0x04 /**< @brief Bit field indicating that the UI uses real DAC. */ +#define OPT_DACT 0x08 /**< @brief Bit field indicating that the UI uses RC Timer DAC. */ +#define OPT_DACS \ + 0x10 /**< @brief Bit field indicating that the UI uses SPI communication. */ +#define OPT_DACF3 \ + 0x40 /**< @brief Bit field indicating that the UI uses DAC for STM32F3. */ +#define OPT_DACF072 \ + 0x80 /**< @brief Bit field indicating that the UI uses DAC for STM32F072. */ + /** @} */ + +#define MAIN_SCFG_POS (28) +#define AUX_SCFG_POS (24) + +#define MAIN_SCFG_VALUE(x) (((x) >> MAIN_SCFG_POS) & (uint8_t)0x0F) +#define AUX_SCFG_VALUE(x) (((x) >> AUX_SCFG_POS) & (uint8_t)0x0F) + + /** @name PFC related exported definitions */ + /** @{ */ + +#define PFC_SWE 0x0001U /**< @brief PFC Software error. */ +#define PFC_HW_PROT 0x0002U /**< @brief PFC hardware protection. */ +#define PFC_SW_OVER_VOLT 0x0004U /**< @brief PFC software over voltage. */ +#define PFC_SW_OVER_CURRENT 0x0008U /**< @brief PFC software over current. */ +#define PFC_SW_MAINS_FREQ 0x0010U /**< @brief PFC mains frequency error. */ +#define PFC_SW_MAIN_VOLT 0x0020U /**< @brief PFC mains voltage error. */ +/** @} */ + +/** @name Definitions exported for the DAC channel used as reference for protection. */ +/** @{ */ +#define AO_DISABLED 0x00U /**< @brief Analog output disabled. */ +#define AO_DEBUG 0x01U /**< @brief Analog output debug. */ +#define VREF_OCPM1 \ + 0x02U /**< @brief Voltage reference for over current protection of motor 1. */ +#define VREF_OCPM2 \ + 0x03U /**< @brief Voltage reference for over current protection of motor 2. */ +#define VREF_OCPM12 \ + 0x04U /**< @brief Voltage reference for over current protection of both motors. */ +#define VREF_OVPM12 \ + 0x05U /**< @brief Voltage reference for over voltage protection of both motors. */ +/** @} */ + +/** @name ADC channel number definitions */ +/** @{ */ +#define MC_ADC_CHANNEL_0 0 +#define MC_ADC_CHANNEL_1 1 +#define MC_ADC_CHANNEL_2 2 +#define MC_ADC_CHANNEL_3 3 +#define MC_ADC_CHANNEL_4 4 +#define MC_ADC_CHANNEL_5 5 +#define MC_ADC_CHANNEL_6 6 +#define MC_ADC_CHANNEL_7 7 +#define MC_ADC_CHANNEL_8 8 +#define MC_ADC_CHANNEL_9 9 +#define MC_ADC_CHANNEL_10 10 +#define MC_ADC_CHANNEL_11 11 +#define MC_ADC_CHANNEL_12 12 +#define MC_ADC_CHANNEL_13 13 +#define MC_ADC_CHANNEL_14 14 +#define MC_ADC_CHANNEL_15 15 +#define MC_ADC_CHANNEL_16 16 +#define MC_ADC_CHANNEL_17 17 +#define MC_ADC_CHANNEL_18 18 +#define MC_ADC_CHANNEL_19 19 +#define MC_ADC_CHANNEL_20 20 +#define MC_ADC_CHANNEL_21 21 +#define MC_ADC_CHANNEL_22 22 +/** @} */ + +/** @name Utility macros definitions */ +/** @{ */ +#define RPM2MEC01HZ(rpm) (int16_t)((int32_t)(rpm) / 6) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + /** @} */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* MC_TYPE_H */ +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/mcpa.h b/src/firmware/motor/mcsdk/mcpa.h new file mode 100644 index 0000000000..b2e8eeaf0a --- /dev/null +++ b/src/firmware/motor/mcsdk/mcpa.h @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * @file mcpa.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the Datalog + * of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MCPA_H +#define MCPA_H + +#include "mcptl.h" +extern uint32_t GLOBAL_TIMESTAMP; + + + +typedef struct +{ + MCTL_Handle_t *pTransportLayer; + void **dataPtrTable; + void **dataPtrTableBuff; + uint8_t *dataSizeTable; + uint8_t *dataSizeTableBuff; + uint8_t *currentBuffer; + uint16_t bufferIndex; + uint16_t bufferTxTrigger; + uint16_t bufferTxTriggerBuff; +#ifdef MCP_DEBUG_METRICS + uint16_t bufferMissed; +#endif + uint8_t nbrOfDataLog; + uint8_t HFIndex; + uint8_t MFIndex; + uint8_t HFRate; + uint8_t HFRateBuff; + uint8_t HFNum; + uint8_t HFNumBuff; + uint8_t MFRate; + uint8_t MFRateBuff; + uint8_t MFNum; + uint8_t MFNumBuff; + uint8_t Mark; + uint8_t MarkBuff; +} MCPA_Handle_t; /* MCP Async handle type*/ + + +void MCPA_dataLog(MCPA_Handle_t *pHandle); +uint8_t MCPA_cfgLog(MCPA_Handle_t *pHandle, uint8_t *cfgdata); +void MCPA_flushDataLog(MCPA_Handle_t *pHandle); + +#endif /* MCPA_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/mcptl.c b/src/firmware/motor/mcsdk/mcptl.c new file mode 100644 index 0000000000..9632d45f5f --- /dev/null +++ b/src/firmware/motor/mcsdk/mcptl.c @@ -0,0 +1,30 @@ +/** + ****************************************************************************** + * @file mcptl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief + * + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +#include "mcptl.h" + + +bool MCTL_decodeCRCData(MCTL_Handle_t *pHandle) +{ + return (true); +} + + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/mcptl.h b/src/firmware/motor/mcsdk/mcptl.h new file mode 100644 index 0000000000..7edba7ee65 --- /dev/null +++ b/src/firmware/motor/mcsdk/mcptl.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file mcptl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware definitions of the Motor control protocol + *transport layer of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * + */ +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef MC_TRANSPORT_LAYER +#define MC_TRANSPORT_LAYER + +#define MCTL_SYNC (uint8_t)0xAU +#define MCTL_ASYNC (uint8_t)0x9U + +#define MCTL_SYNC_NOT_EXPECTED 1 + +#include +#include + +typedef struct MCTL_Handle MCTL_Handle_t; // cstat !MISRAC2012-Rule-2.4 +typedef bool (*MCTL_GetBuf)(MCTL_Handle_t *pHandle, void **buffer, uint8_t syncAsync); +typedef uint8_t (*MCTL_SendPacket)(MCTL_Handle_t *pHandle, void *txBuffer, + uint16_t txDataLength, uint8_t syncAsync); +typedef uint8_t *(*MCTL_RXpacketProcess)(MCTL_Handle_t *pHandle, uint16_t *packetLength); + +typedef enum +{ + available = 0, + writeLock = 1, + pending = 2, + readLock = 3, +} buff_access_t; + +typedef struct +{ + uint8_t *buffer; + uint16_t length; + buff_access_t state; +#ifdef MCP_DEBUG_METRICS + /* Debug metrics */ + uint16_t SentNumber; + uint16_t PendingNumber; + uint16_t RequestedNumber; + /* End of Debug metrics */ +#endif +} MCTL_Buff_t; + +struct MCTL_Handle +{ + MCTL_GetBuf fGetBuffer; + MCTL_SendPacket fSendPacket; + MCTL_RXpacketProcess fRXPacketProcess; + uint16_t txSyncMaxPayload; + uint16_t txAsyncMaxPayload; + bool MCP_PacketAvailable; /* Packet available for Motor control protocol*/ +}; + +bool MCTL_decodeCRCData(MCTL_Handle_t *pHandle); + +#endif + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/mp_hall_tuning.c b/src/firmware/motor/mcsdk/mp_hall_tuning.c new file mode 100644 index 0000000000..7ee283fbfd --- /dev/null +++ b/src/firmware/motor/mcsdk/mp_hall_tuning.c @@ -0,0 +1 @@ +#include "firmware/motor/mc_config.h" diff --git a/src/firmware/motor/mcsdk/mp_hall_tuning.h b/src/firmware/motor/mcsdk/mp_hall_tuning.h new file mode 100644 index 0000000000..de2afaba8c --- /dev/null +++ b/src/firmware/motor/mcsdk/mp_hall_tuning.h @@ -0,0 +1,239 @@ +/** + ****************************************************************************** + * @file mp_hall_tuning.h + * @author STMicroelectronics - System Lab - MC Team + * @version 4.2.0 + * @date 20-Aug-2015 18:06 + * @brief This file contains private definition of SelfComCtrl component + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2015 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MP_HALL_TUNING_H +#define __MP_HALL_TUNING_H + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mc_interface.h" +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/bus_voltage_sensor.h" +#include "firmware/motor/mcsdk/circle_limitation.h" +#include "firmware/motor/mcsdk/hall_speed_pos_fdbk.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/mp_one_touch_tuning.h" +#include "firmware/motor/mcsdk/open_loop.h" +#include "firmware/motor/mcsdk/pid_regulator.h" +#include "firmware/motor/mcsdk/pwm_curr_fdbk.h" +#include "firmware/motor/mcsdk/r_divider_bus_voltage_sensor.h" +#include "firmware/motor/mcsdk/ramp_ext_mngr.h" +#include "firmware/motor/mcsdk/revup_ctrl.h" +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" +#include "firmware/motor/mcsdk/speed_torq_ctrl.h" +#include "firmware/motor/mcsdk/sto_pll_speed_pos_fdbk.h" +#include "firmware/motor/mcsdk/virtual_speed_sensor.h" +#include "firmware/motor/pmsm_motor_parameters.h" + +/* Hall Sensors Pins Def------------------------------------------------------*/ +#define NO_COMPLEMENT 0x0 +#define H1 0x1 +#define H2 0x2 +#define H3 0x4 +#define HALL_FLAG_TIMEOUT 1000 +#define WAIT_RAMP_TIMEOUT 10000 + +/** @addtogroup STM32_PMSM_MC_Library + * @{ + */ +/** @addtogroup SelfComCtrl + * @{ + */ +/** @defgroup SelfComCtrl_class_private_types SelfComCtrl class private types + * @{ + */ + + +/** +* @brief HT_State_t enum type definition, it lists all the possible HT + machine states. +*/ +typedef enum +{ + HT_IDLE, /* 0 */ + HT_PRIOR_CHECK, /* 1 */ + HT_START_RAMP, /* 2 */ + HT_WAIT_RAMP, /* 3 */ + HT_WAIT_HALL_FLAG, /* 4 */ + HT_CHECK_HALL_RELIABILITY, /* 5 */ + HT_WAIT_USER_DIRECTION_CHOICE, /* 6 */ + HT_ERROR_RELIABILITY, /* 7 */ + HT_ERROR_PINS_READING, /* 8 */ + HT_WARNING_PHASES_NEED_SWAP, /* 9 */ + HT_DETECTING_CONF, /* 10 */ + HT_DETERMINE_PTC, /* 11 */ + HT_DETECTING_SWAP, /* 12 */ + HT_WAIT_STABILIZATION, /* 13 */ + HT_DETECTING_EDGE, + HT_GET_ANGLE_EDGE, + HT_CALC_EDGE_ANGLE, + HT_EDGE_COMPUTATION, + HT_RST, /* 16 */ + HT_RESULT /* 17 */ +} HT_State_t; + + +/** +* @brief HT_State_t enum type definition, it lists all the possible HT_SHIF_EDGE + machine states. +*/ +typedef enum +{ + SHIFT_EDGE_IDLE, /* 0 */ + SHIFT_EDGE_1, /* 1 */ + SHIFT_EDGE_2, /* 2 */ + SHIFT_EDGE_3, /* 3 */ + SHIFT_EDGE_4, /* 4 */ + SHIFT_EDGE_5, /* 5 */ + SHIFT_EDGE_6, /* 6 */ + SHIFT_EDGE_END /* 7 */ +} ShiftEdge_State_t; + + +/** + * * @brief Handle structure of the HallTuning. + */ +typedef struct +{ + MCI_Handle_t *pMCI; /*!< State machine of related MC.*/ + OTT_Handle_t *pOTT; + HALL_Handle_t *pHALL_M1; + STO_PLL_Handle_t *pSTO_PLL_M1; + + HT_State_t sm_state; /*!< HT state machine state.*/ + + bool HT_Start; + bool directionAlreadyChosen; + bool userWantsToRestart; + bool userWantsToAbort; + bool flagState0; /*!< true if current HALL state configuration is H1=H2=H3=0. Used to + detect 60 degrees Hall configuration */ + bool flagState1; /*!< true if current HALL state configuration H1=H2=H3=1. Used to + detect 60 degrees Hall configuration */ + bool H1Connected; + bool H2Connected; + bool H3Connected; + bool PTCWellPositioned; + bool waitHallFlagCompleted; + bool reliable; + bool edgeAngleDirPos; + + uint8_t bPlacement; + uint8_t bMechanicalWantedDirection; + uint8_t bNewH1; + uint8_t bNewH2; + uint8_t bNewH3; + uint8_t bProgressPercentage; + + int8_t bPinToComplement; + + uint16_t hHallFlagCnt; + uint16_t hWaitRampCnt; + uint16_t hShiftAngleDepth; + + int16_t hPhaseShiftInstantaneous; + int16_t hPhaseShiftCircularMean; + int16_t hPhaseShiftCircularMeanDeg; + int16_t hPhaseShiftCircularMeanNeg; + int16_t hPhaseShiftCircularMeanNegDeg; + + uint32_t previousH1; + uint32_t previousH2; + uint32_t previousH3; + + int32_t wSinMean; + int32_t wCosMean; + + ShiftEdge_State_t shiftEdge_state; + int32_t wSinSum1; + int32_t wCosSum1; + int32_t wSinSum2; + int32_t wCosSum2; + int32_t wSinSum3; + int32_t wCosSum3; + int32_t wSinSum4; + int32_t wCosSum4; + int32_t wSinSum5; + int32_t wCosSum5; + int32_t wSinSum6; + int32_t wCosSum6; + + int16_t hPhaseShiftCircularMean5_1; + int16_t hPhaseShiftCircularMeanDeg5_1; + int16_t hPhaseShiftCircularMean1_3; + int16_t hPhaseShiftCircularMeanDeg1_3; + int16_t hPhaseShiftCircularMean3_2; + int16_t hPhaseShiftCircularMeanDeg3_2; + int16_t hPhaseShiftCircularMean2_6; + int16_t hPhaseShiftCircularMeanDeg2_6; + int16_t hPhaseShiftCircularMean6_4; + int16_t hPhaseShiftCircularMeanDeg6_4; + int16_t hPhaseShiftCircularMean4_5; + int16_t hPhaseShiftCircularMeanDeg4_5; + + + int16_t hPhaseShiftCircularMean5_4; + int16_t hPhaseShiftCircularMeanDeg5_4; + int16_t hPhaseShiftCircularMean4_6; + int16_t hPhaseShiftCircularMeanDeg4_6; + int16_t hPhaseShiftCircularMean6_2; + int16_t hPhaseShiftCircularMeanDeg6_2; + int16_t hPhaseShiftCircularMean2_3; + int16_t hPhaseShiftCircularMeanDeg2_3; + int16_t hPhaseShiftCircularMean3_1; + int16_t hPhaseShiftCircularMeanDeg3_1; + int16_t hPhaseShiftCircularMean1_5; + int16_t hPhaseShiftCircularMeanDeg1_5; + +} HT_Handle_t; + + + +void HT_Init(HT_Handle_t *pHandleHT, bool pRST); +void HT_MF(HT_Handle_t *pHandleHT); +void HT_GetPhaseShift(HT_Handle_t *pHandleHT); +void HT_Stop(HT_Handle_t *pHandleHT); +void HT_SetMechanicalWantedDirection(HT_Handle_t *pHandleHT, uint8_t bMWD); +void HT_SetStart(HT_Handle_t *pHandleHT, bool value); +void HT_SetRestart(HT_Handle_t *pHandleHT); +void HT_SetAbort(HT_Handle_t *pHandleHT); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /*__MP_HALL_TUNING_H*/ + +/******************* (C) COPYRIGHT 2019 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/mp_one_touch_tuning.h b/src/firmware/motor/mcsdk/mp_one_touch_tuning.h new file mode 100644 index 0000000000..65758c47e8 --- /dev/null +++ b/src/firmware/motor/mcsdk/mp_one_touch_tuning.h @@ -0,0 +1,335 @@ +/** + ****************************************************************************** + * @file mp_one_touch_tuning.h + * @author STMicroelectronics - System Lab - MC Team + * @version 4.3.0 + * @date 22-Sep-2016 15:29 + * @brief This file contains interface of OneTouchTuning class + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2016 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + * @ingroup OneTouchTuning + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MP_ONE_TOUCH_TUNING_H +#define MP_ONE_TOUCH_TUNING_H + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" +#include "pid_regulator.h" +#include "ramp_ext_mngr.h" +#include "speed_torq_ctrl.h" +#include "sto_pll_speed_pos_fdbk.h" + +/** @addtogroup STM32_PMSM_MC_Library + * @{ + */ + +/** @addtogroup OneTouchTuning + * @{ + */ + +/** @defgroup OneTouchTuning_class_exported_types OneTouchTuning class exported types + * @{ + */ + +/** + * @brief Public OneTouchTuning class definition + */ + + +/** + * @brief OneTouchTuning class parameters definition + */ +typedef const struct +{ + RampExtMngr_Handle_t rampExtMngrParams; /*!< Ramp manager used by SCC.*/ + float fBWdef; /*!< Default bandwidth of speed regulator.*/ + float fMeasWin; /*!< Duration of measurement window for speed and + current Iq, expressed in seconds.*/ + uint8_t bPolesPairs; /*!< Number of motor poles pairs.*/ + uint16_t hMaxPositiveTorque; /*!< Maximum positive value of motor + torque. This value represents + actually the maximum Iq current + expressed in digit.*/ + float fCurrtRegStabTimeSec; /*!< Current regulation stabilization time in seconds.*/ + float fOttLowSpeedPerc; /*!< OTT lower speed percentage.*/ + float fOttHighSpeedPerc; /*!< OTT higher speed percentage.*/ + float fSpeedStabTimeSec; /*!< Speed stabilization time in seconds.*/ + float fTimeOutSec; /*!< Timeout for speed stabilization.*/ + float fSpeedMargin; /*!< Speed margin percentage to validate speed ctrl.*/ + int32_t wNominalSpeed; /*!< Nominal speed set by the user expressed in RPM.*/ + float spdKp; /*!< Initial KP factor of the speed regulator to be tuned.*/ + float spdKi; /*!< Initial KI factor of the speed regulator to be tuned.*/ + float spdKs; /*!< Initial antiwindup factor of the speed regulator to be tuned.*/ + float fRshunt; /*!< Value of shunt resistor.*/ + float fAmplificationGain; /*!< Current sensing amplification gain.*/ +} OTT_Params_t, *pOTT_Params_t; + +/** + * @brief OTT_State_t enum type definition, it lists all the possible OTT state + machine states. + */ +typedef enum +{ + OTT_IDLE, + OTT_NOMINAL_SPEED_DET, + OTT_DYNAMICS_DET_RAMP_DOWN, + OTT_DYNAMICS_DET_SET_TORQUE, + OTT_DYNAMICS_DETECTION, + OTT_RAMP_DOWN_H_SPEED, + OTT_H_SPEED_TEST, + OTT_RAMP_DOWN_L_SPEED, + OTT_L_SPEED_TEST, + OTT_TORQUE_STEP, + OTT_END +} OTT_State_t; + +/** + * @brief OneTouchTuning class members definition + */ +typedef struct +{ + SpeednPosFdbk_Handle_t *pSpeedSensor; /*!< Related speed sensor used. */ + pFOCVars_t pFOCVars; /*!< Related structure of FOC vars.*/ + PID_Handle_t *pPIDSpeed; /*!< Related speed controller used. */ + SpeednTorqCtrl_Handle_t *pSTC; /*!< Speed and torque controller used.*/ + + RampExtMngr_Handle_t *pREMng; /*!< Ramp manager used.*/ + int16_t + hFDetIq[2]; /*!< Array used to store Iq measurements done during F estimation.*/ + float fFDetOmega[2]; /*!< Array used to store Omega values during F estimation.*/ + float fF; /*!< Stores the last F estimation.*/ + float fOmegaTh; /*!< Stores the last omega threshold.*/ + float fTau; /*!< Stores the last computed mechanical time constant.*/ + float fJ; /*!< Stores the last J estimation.*/ + float fBW; /*!< Bandwidth of speed regulator.*/ + OTT_State_t bState; /*!< State macchine state.*/ + int32_t wIqsum; /*!< Sum of measured Iq.*/ + int32_t wSpeed01Hzsum; /*!< Sum of average mechanical speed.*/ + uint16_t hIqCnt; /*!< Counter for Iq acquisitions.*/ + int32_t wCnt; /*!< 32bit counter.*/ + int16_t hSpeed01HzMean; /*!< Mean value of mechanical speed.*/ + int16_t hSpeed01HzDelta; /*!< Delta speed between mechanical speed.*/ + uint16_t hCurRegStabCnt; /*!< Stabilization counter.*/ + uint16_t hJdetCnt; /*!< Counter to measure the mechanical time constant.*/ + float fEstNominalSpdRPM; /*!< Estimated nominal speed.*/ + int16_t hIqNominal; /*!< Current measured at nominal speed steady state.*/ + int16_t hIqAcc; /*!< Current used to accelerate the motor.*/ + int16_t hTargetLRPM; /*!< Lower speed used for OTT.*/ + int16_t hTargetHRPM; /*!< Higher speed used for OTT.*/ + uint16_t hMeasWinTicks; /*!< Number of ticks of the measurement window.*/ + uint16_t + hCurRegStabTks; /*!< Number of ticks for current regulation stabilization time.*/ + uint16_t hSpeedStabTks; /*!< Number of ticks for speed stabilization time.*/ + bool bPI_Tuned; /*!< True is PI is tuned, false otherwise.*/ + float fKp; /*!< Computed Kp.*/ + float fKi; /*!< Computed Ki.*/ + int8_t stabCnt; /*!< Stabilization counter.*/ + float fSpeed; /*!< Internal target reference.*/ + uint16_t hTimeOutTks; /*!< Number of tick for timeout.*/ + uint8_t bPolesPairs; /*!< Motor poles pairs.*/ + uint16_t hMaxPositiveTorque; /*!< Maximum positive value of motor + torque. This value represents + actually the maximum Iq current + expressed in digit.*/ + float fRPMTh; /*!< Speed threshold for mecchanical constant + time estimation.*/ + int32_t wNominalSpeed; /*!< Nominal speed set by the user expressed in RPM.*/ + float spdKp; /*!< KP factor of the speed regulator to be tuned.*/ + float spdKi; /*!< KI factor of the speed regulator to be tuned.*/ + float spdKs; /*!< Antiwindup factor of the speed regulator to be tuned.*/ + float spdIntTerm; /*!< Integral term of the speed regulator to be tuned.*/ + float spdAntiWindTerm; /*!< Antiwindup term of the speed regulator to be tuned.*/ + float fKe; /*!< Stores the last Ke estimation.*/ + + pOTT_Params_t pOTT_Params_str; /**< OTT parameters */ + +} OTT_Handle_t; + + +/** + * @} + */ + + +/** + * @brief Initializes all the object variables, usually it has to be called + * once right after object creation. + * @param this related object of class COTT. + * @param pOTT_Init pointer to the OTT init structure. + * @retval none. + */ +void OTT_Init(OTT_Handle_t *pHandle); + +/** + * @brief It should be called before each motor restart. It initialize + * internal state of OTT. + * @param this related object of class COTT. + * @retval none. + */ +void OTT_Clear(OTT_Handle_t *pHandle); + +/** + * @brief It should be called at MF and execute the OTT algorithm. + * @param this related object of class COTT. + * @retval none. + */ +void OTT_MF(OTT_Handle_t *pHandle); + +/** + * @brief It should be called in START_RUN state. It begins the OTT procedure. + * @param this related object of class COTT. + * @retval none. + */ +void OTT_SR(OTT_Handle_t *pHandle); + +/** + * @brief Call this method before start motor to force new OTT procedure. + * @param this related object of class COTT. + * @retval none. + */ +void OTT_ForceTuning(OTT_Handle_t *pHandle); + +/** + * @brief It returns the nominal speed estimated by OTT. + * @param this related object of class COTT. + * @retval uint32_t It returns the nominal speed estimated by OTT, it is a + * floating point number codified into a 32bit integer. + */ +uint32_t OTT_GetNominalSpeed(OTT_Handle_t *pHandle); + +/** + * @brief It returns the number of states of OTT. + * @param this related object of class COTT. + * @retval uint8_t It returns the number of states of Selfcommissioning procedure. + */ +uint8_t OTT_GetSteps(OTT_Handle_t *pHandle); + +/** + * @brief It returns the state of OTT. + * @param this related object of class COTT. + * @retval uint8_t It returns the state of OTT. + */ +uint8_t OTT_GetState(OTT_Handle_t *pHandle); + +/** + * @brief It returns true if OTT procedure has been completed, false otherwise. + * @param this related object of class COTT. + * @retval bool It returns true if OTT procedure has been completed, false otherwise. + */ +bool OTT_IsSpeedPITuned(OTT_Handle_t *pHandle); + +/** + * @brief It returns the nominal speed estimated by OTT in RPM. + * @param this related object of class COTT. + * @retval float It returns the nominal speed in RPM estimated by OTT. + */ +float OTT_fGetNominalSpeedRPM(OTT_Handle_t *pHandle); + +/** + * @brief Sets the number of motor poles pairs. + * @param this related object of class COTT. + * @param bPP Number of motor poles pairs to be set. + * @retval none + */ +void OTT_SetPolesPairs(OTT_Handle_t *pHandle, uint8_t bPP); + +/** + * @brief Change the nominal current. + * @param this related object of class COTT. + * @param hNominalCurrent This value represents actually the maximum Iq current + expressed in digit. + * @retval none + */ +void OTT_SetNominalCurrent(OTT_Handle_t *pHandle, uint16_t hNominalCurrent); + +/** + * @brief Change the speed regulator bandwidth. + * @param this related object of class COTT. + * @param fBW Current regulator bandwidth espressed in rad/s. + * @retval none + */ +void OTT_SetSpeedRegulatorBandwidth(OTT_Handle_t *pHandle, float fBW); + +/** + * @brief Get the speed regulator bandwidth. + * @param this related object of class COTT. + * @retval float Current regulator bandwidth espressed in rad/s. + */ +float OTT_GetSpeedRegulatorBandwidth(OTT_Handle_t *pHandle); + +/** + * @brief Get the measured inertia of the motor. + * @param this related object of class COTT. + * @retval float Measured inertia of the motor expressed in Kgm^2. + */ +float OTT_GetJ(OTT_Handle_t *pHandle); + +/** + * @brief Get the measured friction of the motor. + * @param this related object of class COTT. + * @retval float Measured friction of the motor expressed in Nms. + */ +float OTT_GetF(OTT_Handle_t *pHandle); + +/** + * @brief Set the nominal speed according motor datasheet. + * This function shall be called before the start + * of the MP procedure. + * @param this related object of class COTT. + * @param wNominalSpeed Nominal speed expressed in RPM. + * @retval none + */ +void OTT_SetNominalSpeed(OTT_Handle_t *pHandle, int32_t wNominalSpeed); + +/** + * @brief Store the Ke measured by the SCC for the OTT purpouses. + * @param this related object of class COTT. + * @param fKe Last measured Ke. + * @retval none + */ +void OTT_SetKe(OTT_Handle_t *pHandle, float fKe); + +/** + * @brief It should be called before each motor stop. + * @param this related object of class COTT. + * @retval none. + */ +void OTT_Stop(OTT_Handle_t *pHandle); + +/** + * @brief Return true if the motor has been already profiled. + * @param this related object of class COTT. + * @retval bool true if the if the motor has been already profiled, + * false otherwise. + */ +bool OTT_IsMotorAlreadyProfiled(OTT_Handle_t *pHandle); + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* MP_ONE_TOUCH_TUNING_H */ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/mp_self_com_ctrl.h b/src/firmware/motor/mcsdk/mp_self_com_ctrl.h new file mode 100644 index 0000000000..776e516258 --- /dev/null +++ b/src/firmware/motor/mcsdk/mp_self_com_ctrl.h @@ -0,0 +1,347 @@ +/** + ****************************************************************************** + * @file mp_self_com_ctrl.h + * @author STMicroelectronics - System Lab - MC Team + * @version 4.2.0 + * @date 20-Aug-2015 18:06 + * @brief This file contains private definition of SelfComCtrl component + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2015 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MP_SELF_COM_CTRL_H +#define MP_SELF_COM_CTRL_H + +/* Includes ------------------------------------------------------------------*/ +#include "bus_voltage_sensor.h" +#include "circle_limitation.h" +#include "mc_type.h" +#include "mp_hall_tuning.h" +#include "mp_one_touch_tuning.h" +#include "open_loop.h" +#include "pid_regulator.h" +#include "pwm_curr_fdbk.h" +#include "r_divider_bus_voltage_sensor.h" +#include "ramp_ext_mngr.h" +#include "revup_ctrl.h" +#include "speed_pos_fdbk.h" +#include "speed_torq_ctrl.h" +#include "sto_pll_speed_pos_fdbk.h" +#include "virtual_speed_sensor.h" + +/** @addtogroup STM32_PMSM_MC_Library + * @{ + */ + +/** @addtogroup SelfComCtrl + * @{ + */ + +#define RSCURRLEVELNUM 4u +#define EMF_BUFF_VAL 5u +#define CMD_SC_STOP 0u +#define CMD_SC_START 1u +#define CMD_HT_START 2u +#define CMD_HT_RESTART 3u +#define CMD_HT_ABORT 4u +#define CMD_HT_END 5u +#define CMD_PPD_START 6u + +/** @defgroup SelfComCtrl_class_private_types SelfComCtrl class private types + * @{ + */ + +/** + * @brief LS detection states + */ +typedef enum +{ + LSDET_DECAY, + LSDET_HOLD, + LSDET_RISE +} LSDetState_t; + +/** + * @brief KE detection states + */ +typedef enum +{ + KEDET_REVUP, + KEDET_DETECTION, + KEDET_SET_OBS_PARAMS, + KEDET_STABILIZEPLL, + KEDET_RUN, + KEDET_RESTART +} KEDetState_t; + +/** + * @brief SCC_State_t enum type definition, it lists all the possible SCC state + machine states. + */ +typedef enum +{ + SCC_IDLE, + SCC_DUTY_DETECTING_PHASE, + SCC_ALIGN_PHASE, + SCC_RS_DETECTING_PHASE_RAMP, + SCC_RS_DETECTING_PHASE, + SCC_LS_DETECTING_PHASE, + SCC_WAIT_RESTART, + SCC_RESTART_SCC, + SCC_KE_DETECTING_PHASE, + SCC_PHASE_STOP, + SCC_CALIBRATION_END, + SCC_PP_DETECTION_RAMP, + SCC_PP_DETECTION_PHASE_RAMP, + SCC_PP_DETECTION_PHASE +} SCC_State_t; + +/** + * @brief KE detection speed ramp status + */ +typedef enum +{ + RampIdle, /* Ramp not started yet */ + RampOngoing, /* Ramp is ongoing */ + RampSucces, /* The motor has been accelerated up to the target speed */ + MotorStill, /* Motor didn't move at all */ + LoseControl, /* Motor start to follow acceleration but didn't reach the target speed + */ +} AccResult_t; + + +/** + * @brief SelfComCtrl parameters definition + */ +typedef const struct +{ + RampExtMngr_Handle_t rampExtMngrParams; /*!< Ramp manager used by SCC.*/ + float fRshunt; /*!< Value of shunt resistor.*/ + float fAmplificationGain; /*!< Current sensing amplification gain.*/ + float fVbusConvFactor; /*!< Bus voltage conversion factor.*/ + float fVbusPartitioningFactor; /*!< Bus voltage partitioning factor. + (Vmcu / Bus voltage conversion factor).*/ + float fRVNK; /*!< Power stage calibration factor. + (Measured experimentally).*/ + float fRSMeasCurrLevelMax; /*!< Maximum level of DC current used + for RS measurement.*/ + uint16_t hDutyRampDuration; /*!< Duration of voltage ramp executed + for the duty cycle determination + stage.*/ + uint16_t hAlignmentDuration; /*!< Duration of the alignment stage.*/ + uint16_t hRSDetectionDuration; /*!< Duration of R detection stage.*/ + float fLdLqRatio; /*!< Ld vs Lq ratio.*/ + float fCurrentBW; /*!< Bandwidth of current regulator.*/ + bool bPBCharacterization; /*!< Set to true for characterization + of power board, otherwise false.*/ + int32_t wNominalSpeed; /*!< Nominal speed set by the user expressed in RPM.*/ + uint16_t hPWMFreqHz; /*!< PWM frequency used for the test.*/ + uint8_t bFOCRepRate; /*!< FOC repetition rate used for the test.*/ + float fMCUPowerSupply; /*!< MCU Power Supply */ + float IThreshold; +} SCC_Params_t, *pSCC_Params_t; + +/** + * * @brief Handle structure of the SelfComCtrl. + */ +typedef struct +{ + PWMC_Handle_t *pPWMC; /*!< Current feedback and PWM object used.*/ + RDivider_Handle_t *pVBS; /*!< Bus voltage sensor used.*/ + pFOCVars_t pFOCVars; /*!< Related structure of FOC vars.*/ + MCI_Handle_t *pMCI; /*!< State machine of related MC.*/ + VirtualSpeedSensor_Handle_t *pVSS; /*!< VSS used.*/ + CircleLimitation_Handle_t *pCLM; /*!< Circle limitation used.*/ + PID_Handle_t *pPIDIq; /*!< Iq PID used.*/ + PID_Handle_t *pPIDId; /*!< Id PID used.*/ + RevUpCtrl_Handle_t *pRevupCtrl; /*!< RUC used.*/ + STO_PLL_Handle_t *pSTO; /*!< State Observer used.*/ + SpeednTorqCtrl_Handle_t *pSTC; /*!< Speed and torque controller used.*/ + OTT_Handle_t *pOTT; + HT_Handle_t *pHT; + + SCC_State_t sm_state; /*!< SCC state machine state.*/ + RampExtMngr_Handle_t *pREMng; /*!< Ramp manager used.*/ + uint16_t hDutyMax; /*!< Duty cycle to be applied to reach the target current.*/ + LSDetState_t LSDetState; /*!< Internal state during LS detection. */ + KEDetState_t KEDetState; /*!< Internal state during KE detection. */ + + float fTPWM; /*!< PWM period in second. */ + float fFocRate; /*!< FOC execution rate. */ + float fPP; /*!< Motor poles pairs. */ + int16_t hMax_voltage; /*!< Maximum readable voltage. */ + float fMax_current; /*!< Maximum readable current. */ + float fTargetCurr; /*!< Instantaneous value of target current used for R + estimation.*/ + float fLastTargetCurr; /*!< Last value of set nominal current used for R + estimation.*/ + float fRSCurrLevelStep; /*!< Step of current used for R estimation.*/ + float fBusV; /*!< Stores the last Vbus measurement.*/ + float fRS; /*!< Stores the last R estimation.*/ + float fLS; /*!< Stores the last L estimation.*/ + float fKe; /*!< Stores the last Ke estimation.*/ + float fImaxArray[RSCURRLEVELNUM]; /*!< Array to store current measurement + values for R estimation.*/ + float fVmaxArray[RSCURRLEVELNUM]; /*!< Array to store voltage measurement + values for R estimation.*/ + uint8_t bRSCurrLevelTests; /*!< Counter to store I and V values for R + estimation.*/ + float fImax; /*!< Stores the last current measurement done, it + will be used to compute the 63% for electrical + time constant measurement.*/ + float fItau; /*!< Stores the last computed electrical time constant.*/ + uint8_t bDutyDetTest; /*!< Number of test done in duty determination phase.*/ + uint32_t wLSTimeCnt; /*!< Time counter for LS determination.*/ + uint32_t wLSTestCnt; /*!< Counter for LS tests. */ + float fLSsum; /*!< Sum of estimated LS for mean.*/ + float fIsum; /*!< Sum of measured current for mean.*/ + float fVsum; /*!< Sum of estimated voltage for mean.*/ + uint32_t wICnt; /*!< Counter of I and V acquired.*/ + uint32_t index; /*!< Counter of I and V acquired.*/ + float fIqsum; /*!< Sum of measured Iq for mean.*/ + float fVqsum; /*!< Sum of measured Vq for mean.*/ + float fVdsum; /*!< Sum of measured Vd for mean.*/ + float fFesum; /*!< Sum of electrical frequency for mean.*/ + uint32_t wKeAcqCnt; /*!< Counter of Iq, Vq and Vd acquired.*/ + float fEstNominalSpdRPM; /*!< Estimated nominal speed.*/ + float k1, k2; /*!< Coefficient computed for state observer tuning.*/ + int8_t stabCnt; /*!< Stabilization counter.*/ + float fLdLqRatio; /*!< Ld vs Lq ratio.*/ + int32_t wNominalSpeed; /*!< Nominal speed set by the user expressed in RPM.*/ + int32_t wMaxOLSpeed; /*!< Maximum speed that can be sustained in the startup.*/ + uint32_t wAccRPMs; /*!< Acceleration ramp for the motor expressed in + RMP/s.*/ + bool accRampLock; /*!< It become true if the motor follow the acceleration. */ + float + fEm_val[EMF_BUFF_VAL]; /*!< Buffer used for linear regression (BEMF amplitude).*/ + float + fw_val[EMF_BUFF_VAL]; /*!< Buffer used for linear regression (Angular velocity).*/ + uint16_t hVal_ctn; /*!< Counter for the buffer used for linear regression.*/ + bool startComputation; /*!< It becomes true if the buffer used for linear + regression has been filled.*/ + uint16_t hTimeOutCnt; /*!< Time out counter to assert the motor still + condition during acceleration ramp.*/ + uint32_t wLoseControlAtRPM; /*!< Last speed forced before loosing control during + acceleration ramp.*/ + AccResult_t res; /*!< Result state of the last acceleration ramp.*/ + float fLastValidI; /*!< Last valid current measurement during SCC_DUTY_DETECTING_PHASE + */ + uint16_t hMFCount; /*!< Counter of MF to be wait after OC or loose control.*/ + uint16_t hMFTimeout; /*!< Counter of MF to be wait after OC or loose control.*/ + float fCurrentBW; /*!< Bandwidth of speed regulator.*/ + uint8_t bMPOngoing; /*!< It is 1 if MP is ongoing, 0 otherwise.*/ + uint32_t wSpeedThToValidateStartupRPM; /*!< Speed threshold to validate the startup.*/ + float IaBuff[256]; + bool detectBemfState; + + bool polePairDetection; // profiler ppDetection + uint32_t ppDtcCnt; /*!< Counter of pole pairs detection time.*/ + + pSCC_Params_t pSCC_Params_str; /**< SelfComCtrl parameters */ + +} SCC_Handle_t; + + +/** + * @brief Initializes all the object variables, usually it has to be called + * once right after object creation. + * @param this related object of class CSCC. + * @retval none. + */ +void SCC_Init(SCC_Handle_t *pHandle); +/** + * @brief It should be called before each motor restart. + * @param this related object of class CSCC. + * @retval bool It return false if function fails to start the SCC. + */ +bool SCC_Start(SCC_Handle_t *pHandle); + +/** + * @brief It should be called before each motor stop. + * @param this related object of class CSCC. + * @retval none. + */ +void SCC_Stop(SCC_Handle_t *pHandle); + +/** + * @brief It feed the required phase voltage to the inverter. + * @param this related object of class CSCC. + * @retval It returns the code error 'MC_DURATION' if any, 'MC_NO_ERROR' + * otherwise. These error codes are defined in mc_type.h + */ +uint16_t SCC_SetPhaseVoltage(SCC_Handle_t *pHandle); + +/** + * @brief Medium frequency task. + * @param this related object of class CSCC. + * @retval none + */ +void SCC_MF(SCC_Handle_t *pHandle); + +/** + * @brief Check overcurrent during RL detetction and restart the procedure + * with less current. + * @param this related object of class CSCC. + * @retval none. + */ +void SCC_CheckOC_RL(SCC_Handle_t *pHandle); + +uint8_t SCC_CMD(SCC_Handle_t *pHandle, uint16_t rxLength, uint8_t *rxBuffer, + int16_t txSyncFreeSpace, uint16_t *txLength, uint8_t *txBuffer); +void SCC_SetNominalCurrent(SCC_Handle_t *pHandle, float fCurrent); +void SCC_SetLdLqRatio(SCC_Handle_t *pHandle, float fLdLqRatio); +void SCC_SetNominalSpeed(SCC_Handle_t *pHandle, int32_t wNominalSpeed); +void SCC_SetPolesPairs(SCC_Handle_t *pHandle, uint8_t bPP); +void SCC_SetCurrentBandwidth(SCC_Handle_t *pHandle, float fCurrentBW); +uint8_t SCC_GetState(SCC_Handle_t *pHandle); +uint8_t SCC_GetSteps(SCC_Handle_t *pHandle); +uint8_t SCC_GetFOCRepRate(SCC_Handle_t *pHandle); +uint16_t SCC_GetPWMFrequencyHz(SCC_Handle_t *pHandle); +uint32_t SCC_GetRs(SCC_Handle_t *pHandle); +uint32_t SCC_GetLs(SCC_Handle_t *pHandle); +uint32_t SCC_GetKe(SCC_Handle_t *pHandle); +uint32_t SCC_GetVbus(SCC_Handle_t *pHandle); +float SCC_GetNominalCurrent(SCC_Handle_t *pHandle); +float SCC_GetLdLqRatio(SCC_Handle_t *pHandle); +int32_t SCC_GetNominalSpeed(SCC_Handle_t *pHandle); +float SCC_GetCurrentBandwidth(SCC_Handle_t *pHandle); +float SCC_GetStartupCurrentAmp(SCC_Handle_t *pHandle); +int32_t SCC_GetEstMaxAcceleration(SCC_Handle_t *pHandle); +int32_t SCC_GetEstMaxOLSpeed(SCC_Handle_t *pHandle); + +uint16_t SCC_GetUnderVoltageThreshold(SCC_Handle_t *pHandle); +uint16_t SCC_GetOverVoltageThreshold(SCC_Handle_t *pHandle); +void SCC_SetOverVoltageThreshold(SCC_Handle_t *pHandle, uint16_t value); +void SCC_SetUnderVoltageThreshold(SCC_Handle_t *pHandle, uint16_t value); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /*MP_SELF_COM_CTRL_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/ntc_temperature_sensor.c b/src/firmware/motor/mcsdk/ntc_temperature_sensor.c new file mode 100644 index 0000000000..42c578f1b0 --- /dev/null +++ b/src/firmware/motor/mcsdk/ntc_temperature_sensor.c @@ -0,0 +1,294 @@ +/** + ****************************************************************************** + * @file ntc_temperature_sensor.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Temperature Sensor component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup TemperatureSensor + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/ntc_temperature_sensor.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup TemperatureSensor NTC Temperature Sensor + * @brief Allows to read the temperature of the heat sink + * + * This component implements both a virtual and a real temperature sensor, + * depending on the sensor availability. + * + * Access to the MCU peripherals needed to acquire the temperature (GPIO and ADC + * used for regular conversion) is managed by the PWM component used in the Motor + * Control subsystem. As a consequence, this NTC temperature sensor implementation + * is hardware-independent. + * + * If a real temperature sensor is available (Sensor Type = #REAL_SENSOR), + * this component can handle NTC sensors or, more generally, analog temperature sensors + * which output is related to the temperature by the following formula: + * + * @f[ + * V_{out} = V_0 + \frac{dV}{dT} \cdot ( T - T_0) + * @f] + * + * In case of Pull up configuration @f$\frac{dV}{dT}@f$ is positive and @f$V_0@f$ is low. + * In case of Pull down configuration @f$\frac{dV}{dT}@f$ is negative and @f$V_0@f$ is + * high. + * + * In case a real temperature sensor is not available (Sensor Type = #VIRTUAL_SENSOR), + * This component will always returns a constant, programmable, temperature. + * + * @{ + */ + +/* Private function prototypes -----------------------------------------------*/ +uint16_t NTC_SetFaultState(NTC_Handle_t *pHandle); + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief Returns fault when temperature exceeds the related temperature voltage + * protection threshold + * + * @param pHandle : Pointer on Handle structure of TemperatureSensor component + * + * @retval Fault status : Updated internal fault status + */ +__weak uint16_t NTC_SetFaultState(NTC_Handle_t *pHandle) +{ + uint16_t hFault; +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + if (MC_NULL == pHandle) + { + hFault = MC_SW_ERROR; + } + else + { +#endif + if (pHandle->hAvTemp_d > pHandle->hOverTempThreshold) + { + hFault = MC_OVER_TEMP; + } + else if (pHandle->hAvTemp_d < pHandle->hOverTempDeactThreshold) + { + hFault = MC_NO_ERROR; + } + else + { + hFault = pHandle->hFaultState; + } +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + } +#endif + return hFault; +} + +/* Functions ---------------------------------------------------- */ + +/** + * @brief Initializes temperature sensing conversions + * + * @param pHandle : Pointer on Handle structure of TemperatureSensor component + * + */ +__weak void NTC_Init(NTC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (REAL_SENSOR == pHandle->bSensorType) + { + /* Need to be register with RegularConvManager */ + pHandle->convHandle = RCM_RegisterRegConv(&pHandle->TempRegConv); + NTC_Clear(pHandle); + } + else /* case VIRTUAL_SENSOR */ + { + pHandle->hFaultState = MC_NO_ERROR; + pHandle->hAvTemp_d = pHandle->hExpectedTemp_d; + } +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + } +#endif +} + +/** + * @brief Initializes internal average temperature computed value + * + * @param pHandle : Pointer on Handle structure of TemperatureSensor component + */ +__weak void NTC_Clear(NTC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + if (MC_NULL == pHandle) + { + /* nothing to do */ + } + else + { +#endif + pHandle->hAvTemp_d = 0U; +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + } +#endif +} + +/** + * @brief Performs the temperature sensing average computation after an ADC conversion + * + * @param pHandle : Pointer on Handle structure of TemperatureSensor component + * + * @retval Fault status : Error reported in case of an over temperature detection + */ +__weak uint16_t NTC_CalcAvTemp(NTC_Handle_t *pHandle) +{ + uint16_t returnValue; +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + if (MC_NULL == pHandle) + { + returnValue = 0U; + } + else + { +#endif + if (REAL_SENSOR == pHandle->bSensorType) + { + uint16_t hAux; + hAux = RCM_ExecRegularConv(pHandle->convHandle); + + if (0xFFFFU == hAux) + { + /* Nothing to do */ + } + else + { + uint32_t wtemp; + wtemp = (uint32_t)(pHandle->hLowPassFilterBW) - 1U; + wtemp *= ((uint32_t)pHandle->hAvTemp_d); + wtemp += hAux; + wtemp /= ((uint32_t)pHandle->hLowPassFilterBW); + + pHandle->hAvTemp_d = (uint16_t)wtemp; + } + + pHandle->hFaultState = NTC_SetFaultState(pHandle); + } + else /* case VIRTUAL_SENSOR */ + { + pHandle->hFaultState = MC_NO_ERROR; + } + returnValue = pHandle->hFaultState; +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + } +#endif + return (returnValue); +} + +/** + * @brief Returns latest averaged temperature measured expressed in u16Celsius + * + * @param pHandle : Pointer on Handle structure of TemperatureSensor component + * + * @retval AverageTemperature : Current averaged temperature measured (in u16Celsius) + */ +__weak uint16_t NTC_GetAvTemp_d(const NTC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + return ((MC_NULL == pHandle) ? 0U : pHandle->hAvTemp_d); +#else + return (pHandle->hAvTemp_d); +#endif +} + +/** + * @brief Returns latest averaged temperature expressed in Celsius degrees + * + * @param pHandle : Pointer on Handle structure of TemperatureSensor component + * + * @retval AverageTemperature : Latest averaged temperature measured (in Celsius degrees) + */ +__weak int16_t NTC_GetAvTemp_C(NTC_Handle_t *pHandle) +{ + int16_t returnValue; +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + if (MC_NULL == pHandle) + { + returnValue = 0; + } + else + { +#endif + int32_t wTemp; + + if (REAL_SENSOR == pHandle->bSensorType) + { + wTemp = (int32_t)pHandle->hAvTemp_d; + wTemp -= ((int32_t)pHandle->wV0); + wTemp *= pHandle->hSensitivity; +#ifndef FULL_MISRA_C_COMPLIANCY_NTC_TEMP + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wTemp = (wTemp >> 16) + (int32_t)pHandle->hT0; +#else + wTemp = (wTemp / 65536) + (int32_t)pHandle->hT0; +#endif + } + else + { + wTemp = (int32_t)pHandle->hExpectedTemp_C; + } + returnValue = (int16_t)wTemp; +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + } +#endif + return (returnValue); +} + +/** + * @brief Returns Temperature measurement fault status + * + * Fault status can be either MC_OVER_TEMP when measure exceeds the protection threshold + * values or MC_NO_ERROR if it is inside authorized range. + * + * @param pHandle: Pointer on Handle structure of TemperatureSensor component. + * + * @retval Fault status : read internal fault state + */ +__weak uint16_t NTC_CheckTemp(const NTC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_NTC_TEMP_SENS + return ((MC_NULL == pHandle) ? 0U : pHandle->hFaultState); +#else + return (pHandle->hFaultState); +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/ntc_temperature_sensor.h b/src/firmware/motor/mcsdk/ntc_temperature_sensor.h new file mode 100644 index 0000000000..fb5882fb43 --- /dev/null +++ b/src/firmware/motor/mcsdk/ntc_temperature_sensor.h @@ -0,0 +1,129 @@ +/** + ****************************************************************************** + * @file ntc_temperature_sensor.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Temperature Sensor component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup TemperatureSensor + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef TEMPERATURESENSOR_H +#define TEMPERATURESENSOR_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/regular_conversion_manager.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup TemperatureSensor + * @{ + */ + + + /** + * @brief Structure used for temperature monitoring + * + */ + typedef struct + { + SensorType_t + bSensorType; /**< Type of instanced temperature. + This parameter can be REAL_SENSOR or VIRTUAL_SENSOR */ + + RegConv_t TempRegConv; /**< It contains all the parameters required to execute + a regular conversion for temperature monitoring*/ + uint16_t hAvTemp_d; /**< It contains latest available average Vbus. + This parameter is expressed in u16Celsius */ + + uint16_t hExpectedTemp_d; /**< Default set when no sensor available (ie virtual + sensor) */ + + uint16_t hExpectedTemp_C; /**< Default value when no sensor available (ie virtual + sensor). This parameter is expressed in Celsius */ + + uint16_t hFaultState; /**< Contains latest Fault code. + This parameter is set to MC_OVER_TEMP or MC_NO_ERROR */ + + uint16_t hLowPassFilterBW; /**< used to configure the first order software filter + bandwidth. hLowPassFilterBW = NTC_CalcBusReading + call rate [Hz]/ FilterBandwidth[Hz] */ + uint16_t + hOverTempThreshold; /**< Represents the over voltage protection intervention + threshold. This parameter is expressed in u16Celsius + through formula: hOverTempThreshold = + (V0[V]+dV/dT[V/°C]*(OverTempThreshold[°C] - T0[°C]))* + 65536 / MCU supply voltage */ + uint16_t hOverTempDeactThreshold; /**< Temperature threshold below which an active + over temperature fault is cleared. This + parameter is expressed in u16Celsius through + formula: hOverTempDeactThreshold = + (V0[V]+dV/dT[V/°C]*(OverTempDeactThresh[°C] + - T0[°C]))* 65536 / MCU supply voltage*/ + int16_t hSensitivity; /**< NTC sensitivity + This parameter is equal to MCU supply voltage [V] / + dV/dT [V/°C] */ + uint32_t wV0; /**< V0 voltage constant value used to convert the temperature into + Volts. This parameter is equal V0*65536/MCU supply Used in + through formula: V[V]=V0+dV/dT[V/°C]*(T-T0)[°C] */ + uint16_t + hT0; /**< T0 temperature constant value used to convert the temperature into + Volts Used in through formula: V[V]=V0+dV/dT[V/°C]*(T-T0)[°C] */ + uint8_t convHandle; /*!< handle to the regular conversion */ + + } NTC_Handle_t; + + /* Initialize temperature sensing parameters */ + void NTC_Init(NTC_Handle_t *pHandle); + + /* Clear static average temperature value */ + void NTC_Clear(NTC_Handle_t *pHandle); + + /* Temperature sensing computation */ + uint16_t NTC_CalcAvTemp(NTC_Handle_t *pHandle); + + /* Get averaged temperature measurement expressed in u16Celsius */ + uint16_t NTC_GetAvTemp_d(const NTC_Handle_t *pHandle); + + /* Get averaged temperature measurement expressed in Celsius degrees */ + int16_t NTC_GetAvTemp_C(NTC_Handle_t *pHandle); + + + /* Get the temperature measurement fault status */ + uint16_t NTC_CheckTemp(const NTC_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* TEMPERATURESENSOR_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/open_loop.c b/src/firmware/motor/mcsdk/open_loop.c new file mode 100644 index 0000000000..47e3321179 --- /dev/null +++ b/src/firmware/motor/mcsdk/open_loop.c @@ -0,0 +1,189 @@ +/** + ****************************************************************************** + * @file open_loop.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Open Loop component. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup OpenLoop + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/open_loop.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup OpenLoop Open Loop Control + * @brief Open Loop component of the Motor Control SDK + * + * Open Loop component allows to run the motor in open loop voltage mode. In that mode, + * the phase voltages are forced independently from the measured currents. To do so, the + * routine OL_VqdConditioning() overwrites the voltage command Vdq in the FOC current + * controller task. The voltage level to apply can be set directly by the user, with + * OL_UpdateVoltage(), or computed by OL_Calc() if the V/F mode is selected. In that mode, + * the voltage level depends on the speed, the slope and the offset selected by the user. + * + * @{ + */ + +/* Private defines -----------------------------------------------------------*/ + +/** + * @brief Initializes OpenLoop variables.it should be called + * once during Motor Control initialization. + * @param pHandle: Pointer on Handle structure of OpenLoop feature. + * @param pVSS: Pointer on virtual speed sensor structure. + */ +__weak void OL_Init(OpenLoop_Handle_t *pHandle, VirtualSpeedSensor_Handle_t *pVSS) +{ +#ifdef NULL_PTR_CHECK_OPEN_LOOP + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hVoltage = pHandle->hDefaultVoltage; + pHandle->pVSS = pVSS; +#ifdef NULL_PTR_CHECK_OPEN_LOOP + } +#endif +} + +/** + * @brief Sets Vqd according to open loop phase voltage. It should be + * called during current controller task. + * @param pHandle: Pointer on Handle structure of OpenLoop feature. + * @retval qd_t Vqd conditioned values. + */ +__weak qd_t OL_VqdConditioning(const OpenLoop_Handle_t *pHandle) +{ + qd_t Vqd; + Vqd.d = 0; +#ifdef NULL_PTR_CHECK_OPEN_LOOP + Vqd.q = ((MC_NULL == pHandle) ? 0 : pHandle->hVoltage); +#else + Vqd.q = (pHandle->hVoltage); +#endif + return (Vqd); +} + +/** + * @brief Sets new open loop phase voltage. + * @param pHandle: Pointer on Handle structure of OpenLoop feature. + * @param hNewVoltage: New voltage value to apply. + */ +__weak void OL_UpdateVoltage(OpenLoop_Handle_t *pHandle, int16_t hNewVoltage) +{ +#ifdef NULL_PTR_CHECK_OPEN_LOOP + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hVoltage = hNewVoltage; +#ifdef NULL_PTR_CHECK_OPEN_LOOP + } +#endif +} + +/** + * @brief Gets open loop phase voltage. + * @param pHandle: Pointer on Handle structure of OpenLoop feature. + */ +__weak int16_t OL_GetVoltage(OpenLoop_Handle_t *pHandle) +{ + int16_t hVoltage; +#ifdef NULL_PTR_CHECK_OPEN_LOOP + hVoltage = ((MC_NULL == pHandle) ? 0 : pHandle->hVoltage); +#else + hVoltage = pHandle->hVoltage; +#endif + return (hVoltage); +} + +/** + * @brief Computes phase voltage to apply according to average mechanical speed (V/F + * Mode). It should be called during background task. + * @param pHandle: Pointer on Handle structure of OpenLoop feature. + */ +__weak void OL_Calc(OpenLoop_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_OPEN_LOOP + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (true == pHandle->VFMode) + { + /* V/F mode true means enabled */ + if (pHandle->pVSS->_Super.hAvrMecSpeedUnit >= 0) + { + pHandle->hVoltage = + pHandle->hVFOffset + + (pHandle->hVFSlope * pHandle->pVSS->_Super.hAvrMecSpeedUnit); + } + else + { + pHandle->hVoltage = + pHandle->hVFOffset - + (pHandle->hVFSlope * pHandle->pVSS->_Super.hAvrMecSpeedUnit); + } + } +#ifdef NULL_PTR_CHECK_OPEN_LOOP + } +#endif +} + +/** + * @brief Activates of the Voltage versus Frequency mode (V/F mode). + * @param pHandle: Pointer on Handle structure of OpenLoop feature. + * @param VFEnabling: Flag to enable the V/F mode. + */ +__weak void OL_VF(OpenLoop_Handle_t *pHandle, bool VFEnabling) +{ +#ifdef NULL_PTR_CHECK_OPEN_LOOP + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->VFMode = VFEnabling; +#ifdef NULL_PTR_CHECK_OPEN_LOOP + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/open_loop.h b/src/firmware/motor/mcsdk/open_loop.h new file mode 100644 index 0000000000..f4956ec8cd --- /dev/null +++ b/src/firmware/motor/mcsdk/open_loop.h @@ -0,0 +1,101 @@ +/** + ****************************************************************************** + * @file open_loop.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Open Loop component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup OpenLoop + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef OPENLOOPCLASS_H +#define OPENLOOPCLASS_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" +#include "virtual_speed_sensor.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup OpenLoop + * @{ + */ + + /** + * @brief OpenLoop_Handle_t structure used for phases definition + */ + typedef struct + { + int16_t hDefaultVoltage; /**< @brief Default Open loop phase voltage. */ + + bool VFMode; /**< @brief Flag to enable Voltage versus Frequency mode (V/F mode). + */ + + int16_t hVFOffset; /**< @brief Minimum Voltage to apply when frequency is equal to + zero. */ + + int16_t hVFSlope; /**< @brief Slope of V/F curve: Voltage = (hVFSlope)*Frequency + + hVFOffset. */ + + int16_t hVoltage; /**< @brief Current Open loop phase voltage. */ + + VirtualSpeedSensor_Handle_t + *pVSS; /**< @brief Allow access on mechanical speed measured. */ + + } OpenLoop_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /* Initializes OpenLoop variables. */ + void OL_Init(OpenLoop_Handle_t *pHandle, VirtualSpeedSensor_Handle_t *pVSS); + + /* Sets Vqd according to open loop phase voltage. */ + qd_t OL_VqdConditioning(const OpenLoop_Handle_t *pHandle); + + /* Sets new open loop phase voltage */ + void OL_UpdateVoltage(OpenLoop_Handle_t *pHandle, int16_t hNewVoltage); + + /* Gets open loop phase voltage. */ + int16_t OL_GetVoltage(OpenLoop_Handle_t *pHandle); + + /* Computes phase voltage to apply according to average mechanical speed (V/F Mode). + */ + void OL_Calc(OpenLoop_Handle_t *pHandle); + + /* Activates of the Voltage versus Frequency mode (V/F mode) */ + void OL_VF(OpenLoop_Handle_t *pHandle, bool VFEnabling); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* OPENLOOPCLASS_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pid_regulator.c b/src/firmware/motor/mcsdk/pid_regulator.c new file mode 100644 index 0000000000..59e2bd3c7f --- /dev/null +++ b/src/firmware/motor/mcsdk/pid_regulator.c @@ -0,0 +1,884 @@ +/** + ****************************************************************************** + * @file pid_regulator.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the PID regulator component of the Motor Control SDK. + * + * The PID regulator component provides the functions needed to implement + * a proportional–integral–derivative controller. + * + * See @link PIDRegulator @endlink for more details. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup PIDRegulator + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/pid_regulator.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** + * @defgroup PIDRegulator PID Regulator + * @brief PID Regulator component of the Motor Control SDK + * + * The PID regulator component implements the following two control functions: + * + * * A simple proportional-integral controller, implemented by the PI_Controller() + * function: + * @f[ + * r(t_k) = K_p \times \epsilon(t_k) + K_i \times \sum_{j=0}^k\epsilon(t_j) + * @f] + * * A complete proportional–integral–derivative controller, implemented by the + * PID_Controller() function: + * @f[ + * r(t_k) = K_p \times \epsilon(t_k) + K_i \times \sum_{j=0}^k\epsilon(t_j) + K_d \times + * (\epsilon(t_k) - \epsilon(t_{k-1})) + * @f] + * + * The proportional, integral and derivative gains are expressed as rational numbers, with + * a gain (numerator) and a divisor (denominator) parameters: + * + * * Proportional gain: @f$ K_{p} = K_{pg} / K_{pd} @f$ + * * Integral gain: @f$ K_{i} = K_{ig} / K_{id} @f$ + * * Derivative gain: @f$ K_{d} = K_{dg} / K_{dd} @f$ + * + * Each of the gain numerator and divisor parameters, @f$K_{{p}g}@f$, @f$K_{{i}g}@f$, + * @f$K_{{d}g}@f$, @f$K_{{p}d}@f$, + * @f$K_{id}@f$, @f$K_{dd}@f$, can be set, at run time and independently, via the + * PID_SetKP(), PID_SetKI(), PID_SetKD(), PID_SetKPDivisorPOW2(), PID_SetKIDivisorPOW2() + * and PID_SetKDDivisorPOW2() functions, respectively. + * + * A PID Regulator component needs to be initialized before it can be used. This is done + * with the PID_HandleInit() function that sets the intergral term and the derivative term + * base (the previous value of the process error input) to 0 and that also resets the + * numerators of the proportional, integral and derivative gains to their default values. + * These default values are literally written in the code of the application, so they are + * set at compile time. They can be retrieved with the PID_GetDefaultKP(), + * PID_GetDefaultKI() and PID_GetDefaultKD() functions. + * + * The controller functions implemented by the PI_Controller() and the PID_Controller() + * functions are based on 16-bit integer arithmetics: the gains are expressed as + * fractional numbers, with 16-bit numerators and denominators. And the controller output + * values returned by these functions are also 16-bit integers. This makes it possible to + * use this component efficiently on all STM2 MCUs. + * + * To keep the computed values within limits, the component features the possibility to + * constrain the integral term within a range of values bounded by the + * PID_SetLowerIntegralTermLimit() and PID_SetUpperIntegralTermLimit() functions. + * + * The output valud of the controller can also be bounded between a high and a low limit + * thanks to the PID_SetLowerOutputLimit() and PID_SetUpperOutputLimit() functions. + * + * Hanlding a process with a PID Controller may require some adjustment to cope with + * specific situations. To that end, the PID regulator component provides functions to set + * the integral term (PID_SetIntegralTerm()) or to set the value of the previous process + * error (PID_SetPrevError()). + * + * See the [PID chapter of the User Manual](PID_regulator_theoretical_background.md) for + * more details on the theoretical background of this regulator. + * @{ + */ + +/** + * @brief Initializes the handle of a PID component + * @param pHandle A Handle on the PID component to initialize + * + * The integral term and the derivative base of the PID component are + * set to zero. + * + * The numerators of the proportional, integral and derivative gains + * are set to their default values. These default values are the ones + * set to the PID_Handle_t::hDefKpGain, PID_Handle_t::hDefKiGain and + * PID_Handle_t::hDefKdGain fields of the PID_Handle_t structure. + */ +__weak void PID_HandleInit(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hKpGain = pHandle->hDefKpGain; + pHandle->hKiGain = pHandle->hDefKiGain; + pHandle->hKdGain = pHandle->hDefKdGain; + pHandle->wIntegralTerm = 0; + pHandle->wPrevProcessVarError = 0; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Sets @f$K_{pg}@f$, the numerator of the proportional gain of a PID component + * @param pHandle Handle on the PID component + * @param hKpGain New @f$K_{pg}@f$ value + */ +__weak void PID_SetKP(PID_Handle_t *pHandle, int16_t hKpGain) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hKpGain = hKpGain; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Sets the @f$K_{ig}@f$, the numrerator of the integral gain of a PID component + * @param pHandle Handle on the PID component + * @param hKiGain new @f$K_{ig}@f$ value + */ +__weak void PID_SetKI(PID_Handle_t *pHandle, int16_t hKiGain) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hKiGain = hKiGain; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Returns @f$K_{pg}@f$, the numerator of the proportional gain of a PID component + * @param pHandle Handle on the PID component + */ +__weak int16_t PID_GetKP(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0 : pHandle->hKpGain); +#else + return (pHandle->hKpGain); +#endif +} + +/** + * @brief Returns @f$K_{ig}@f$, the numrerator of the integral gain of a PID component + * @param pHandle Handle on the PID component + */ +__weak int16_t PID_GetKI(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0 : pHandle->hKiGain); +#else + return (pHandle->hKiGain); +#endif +} + +/** + * @brief Returns the default @f$K_{pg}@f$ value, the numerator of the proportional + * gain of a PID component + * @param pHandle Handle on the PID component + * + * The default @f$K_{pg}@f$ value is the one that is being used at startup time, + * when the MCU is reset or when the PID_HandleInit() function gets called. When + * any of the last two event occurs, any proportional gain numerator that may + * have been previously set with the PID_SetKP() function is replaced by this + * default value. + */ +__weak int16_t PID_GetDefaultKP(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0 : pHandle->hDefKpGain); +#else + return (pHandle->hDefKpGain); +#endif +} + +/** + * @brief Returns the default @f$K_{ig}@f$ value, the numerator of the integral + * gain of a PID component + * @param pHandle Handle on the PID component + * + * The default @f$K_{ig}@f$ value is the one that is being used at startup time, + * when the MCU is reset or when the PID_HandleInit() function gets called. When + * any of the last two event occurs, any gain that may have been previously set + * with the PID_SetKI() function is replaced by this default value. + */ +__weak int16_t PID_GetDefaultKI(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0 : pHandle->hDefKiGain); +#else + return (pHandle->hDefKiGain); +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Sets the value of the integral term of a PID component + * @param pHandle Handle on the PID component + * @param wIntegralTermValue new integral term value multiplied by the divisor + * of the integral gain + * + * If @f$T_{i}@f$ is the target integral term, the @p wIntegralTermValue term is stored + * before the division by @f$K_{id}@f$ to maximize the available dynamics. + * + * @attention @p wIntegralTermValue divided by @f$K_{id}@f$ must fit in a 16-bit signed + * integer value. + */ +__weak void PID_SetIntegralTerm(PID_Handle_t *pHandle, int32_t wIntegralTermValue) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->wIntegralTerm = wIntegralTermValue; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif + return; +} + +/** + * @brief Returns @f$K_{pd}@f$, the divisor of the proportional gain of a PID component + * @param pHandle Handle on the PID component + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * @sa PID_GetKPDivisorPOW2() + */ +__weak uint16_t PID_GetKPDivisor(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0U : pHandle->hKpDivisor); +#else + return (pHandle->hKpDivisor); +#endif +} + +/** + * @brief Returns the power of two that makes @f$K_{pd}@f$, the divisor of the + * proportional gain of a PID component + * @param pHandle Handle on the PID component + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * @sa PID_GetKPDivisor() + */ +__weak uint16_t PID_GetKPDivisorPOW2(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0U : pHandle->hKpDivisorPOW2); +#else + return (pHandle->hKpDivisorPOW2); +#endif +} + +/** + * @brief Sets the power of two that makes @f$K_{pd}@f$, the divisor of the proportional + * gain of a PID component + * @param pHandle Handle on the PID component + * @param hKpDivisorPOW2 new @f$K_{pd}@f$ divisor value, expressed as power of 2 + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * This function sets @f$K_{pd}@f$ to 2 to the power of @p hKpDivisorPOW2. + */ +__weak void PID_SetKPDivisorPOW2(PID_Handle_t *pHandle, uint16_t hKpDivisorPOW2) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hKpDivisorPOW2 = hKpDivisorPOW2; + pHandle->hKpDivisor = (((uint16_t)1) << hKpDivisorPOW2); +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Returns @f$K_{id}@f$, the divisor of the integral gain of a PID component + * @param pHandle Handle on the PID component + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * @sa PID_GetKIDivisorPOW2() + */ +__weak uint16_t PID_GetKIDivisor(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0U : pHandle->hKiDivisor); +#else + return (pHandle->hKiDivisor); +#endif +} + +/** + * @brief Returns the power of two that makes @f$K_{id}@f$, the divisor of the integral + * gain of a PID component + * @param pHandle Handle on the PID component + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * @sa PID_GetKIDivisor() + */ +__weak uint16_t PID_GetKIDivisorPOW2(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0U : pHandle->hKiDivisorPOW2); +#else + return (pHandle->hKiDivisorPOW2); +#endif +} + +/** + * @brief Sets the power of two that makes @f$K_{id}@f$, the divisor of the integral gain + * of a PID component + * @param pHandle Handle on the PID component + * @param hKiDivisorPOW2 new @f$K_{id}@f$ divisor value, expressed as power of 2 + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * This function sets @f$K_{id}@f$ to 2 to the power of @p hKiDivisorPOW2. + * + * Note that the upper and lower limits of the integral term are also updated to + * accept any 16-bit value. If the limits of the integral term need to be different + * use the PID_SetUpperIntegralTermLimit() and PID_SetLowerIntegralTermLimit() functions + * after this one. + */ +__weak void PID_SetKIDivisorPOW2(PID_Handle_t *pHandle, uint16_t hKiDivisorPOW2) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + uint32_t wKiDiv = (((uint32_t)1) << hKiDivisorPOW2); + pHandle->hKiDivisorPOW2 = hKiDivisorPOW2; + pHandle->hKiDivisor = (uint16_t)wKiDiv; + PID_SetUpperIntegralTermLimit(pHandle, (int32_t)INT16_MAX * (int32_t)wKiDiv); + PID_SetLowerIntegralTermLimit(pHandle, (int32_t)(-INT16_MAX) * (int32_t)wKiDiv); +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Sets the lower limit of the integral term of a PID component + * + * @param pHandle Handle on the PID component + * @param wLowerLimit new lower integral term limit multiplied by the divisor + * of the integral gain + * + * If @f$T_{iL}@f$ is the target lower limit, the @p wLowerLimit parameter must + * be set to @f$T_{iL}\times K_{id}@f$. This is because the limit is checked before + * applying the divisor in the PI_Controller() and PID_Controller() controller + * functions. + * + * When the PI or PID controller is executed, the value of the integral term is floored + * to this value. + * + * @attention @p wLowerLimit divided by @f$K_{id}@f$ must fit in a 16-bit signed + * integer value. + */ +__weak void PID_SetLowerIntegralTermLimit(PID_Handle_t *pHandle, int32_t wLowerLimit) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->wLowerIntegralLimit = wLowerLimit; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Sets the upper limit of the integral term of a PID component + * + * @param pHandle Handle on the PID component + * @param wUpperLimit new upper integral term limit multiplied by the divisor + * of the integral gain + * + * If @f$T_{iU}@f$ is the target upper limit, the @p wUpperLimit parameter must + * be set to @f$T_{iU}\times K_{id}@f$. This is because the limit is checked before + * applying the divisor in the PI_Controller() and PID_Controller() controller + * functions. + * + * When the controller is executed, the value of the integral term is capped to + * this value. + * + * @attention @p wUpperLimit divided by @f$K_{id}@f$ must fit in a 16-bit signed + * integer value. + */ +__weak void PID_SetUpperIntegralTermLimit(PID_Handle_t *pHandle, int32_t wUpperLimit) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->wUpperIntegralLimit = wUpperLimit; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Sets the lower output limit of a PID component + * + * @param pHandle Handle on the PID component + * @param hLowerLimit new lower limit of the output value + * + * When the controller is executed, the value of its output is floored to this value. + */ +__weak void PID_SetLowerOutputLimit(PID_Handle_t *pHandle, int16_t hLowerLimit) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hLowerOutputLimit = hLowerLimit; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Sets the upper output limit of a PID component + * + * @param pHandle Handle on the PID component + * @param hUpperLimit: new upper limit of the output value + * + * When the controller is executed, the value of its output is capped to this value. + */ +__weak void PID_SetUpperOutputLimit(PID_Handle_t *pHandle, int16_t hUpperLimit) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hUpperOutputLimit = hUpperLimit; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Sets the value of the previous process error of a PID component + * + * @param pHandle Handle on the PID component + * @param wPrevProcessVarError new value of the previous error variable + */ +__weak void PID_SetPrevError(PID_Handle_t *pHandle, int32_t wPrevProcessVarError) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->wPrevProcessVarError = wPrevProcessVarError; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif + return; +} + +/** + * @brief Sets @f$K_{dg}@f$, the numerator of the derivative gain of a PID component + * @param pHandle Handle on the PID component + * @param hKpGain New @f$K_{dg}@f$ value + */ +__weak void PID_SetKD(PID_Handle_t *pHandle, int16_t hKdGain) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hKdGain = hKdGain; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +/** + * @brief Returns @f$K_{dg}@f$, the numerator of the derivative gain of a PID component + * @param pHandle Handle on the PID component + */ +__weak int16_t PID_GetKD(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0 : pHandle->hKdGain); +#else + return (pHandle->hKdGain); +#endif +} + +/** + * @brief Returns @f$K_{dd}@f$, the divisor of the derivative gain of a PID component + * @param pHandle Handle on the PID component + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * @sa PID_GetKDDivisorPOW2() + */ +__weak uint16_t PID_GetKDDivisor(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0U : pHandle->hKdDivisor); +#else + return (pHandle->hKdDivisor); +#endif +} + +/** + * @brief Returns the power of two that makes @f$K_{dd}@f$, the divisor of the derivative + * gain of a PID component + * @param pHandle Handle on the PID component + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * @sa PID_GetKDDivisor() + */ +__weak uint16_t PID_GetKDDivisorPOW2(PID_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PID_REG + return ((MC_NULL == pHandle) ? 0U : pHandle->hKdDivisorPOW2); +#else + return (pHandle->hKdDivisorPOW2); +#endif +} + +/** + * @brief Sets the power of two that makes @f$K_{dd}@f$, the divisor of the derivative + * gain of a PID component + * @param pHandle Handle on the PID component + * @param hKdDivisorPOW2 new @f$K_{dd}@f$ divisor value, expressed as power of 2 + * + * The divisors that make the gains of the @ref PIDRegulator "PID regulator component" are + * powers of two. + * + * This function sets @f$K_{dd}@f$ to 2 to the power of @p hKdDivisorPOW2. + */ +__weak void PID_SetKDDivisorPOW2(PID_Handle_t *pHandle, uint16_t hKdDivisorPOW2) +{ +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hKdDivisorPOW2 = hKdDivisorPOW2; + pHandle->hKdDivisor = (((uint16_t)1) << hKdDivisorPOW2); +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Computes the output of a PI Regulator component, sum of its proportional and + * integral terms + * + * @param pHandle Handle on the PID component + * @param wProcessVarError current process variable error (the reference value minus the + * present process variable value) + * @retval computed PI controller output + * + * This function implements the proportional-integral controller function described by the + * @ref PIDRegulator "PID regulator component". The integral term is saturated by the + * upper and lower intergral term limit values before it is added to the proportional + * term. + * + * The resulting value is then saturated by the upper and lower output limit values before + * being returned. + */ +__weak int16_t PI_Controller(PID_Handle_t *pHandle, int32_t wProcessVarError) +{ + int16_t returnValue; +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + returnValue = 0; + } + else + { +#endif + int32_t wProportional_Term; + int32_t wIntegral_Term; + int32_t wOutput_32; + int32_t wIntegral_sum_temp; + int32_t wDischarge = 0; + int16_t hUpperOutputLimit = pHandle->hUpperOutputLimit; + int16_t hLowerOutputLimit = pHandle->hLowerOutputLimit; + + /* Proportional term computation*/ + wProportional_Term = pHandle->hKpGain * wProcessVarError; + + /* Integral term computation */ + if (0 == pHandle->hKiGain) + { + pHandle->wIntegralTerm = 0; + } + else + { + wIntegral_Term = pHandle->hKiGain * wProcessVarError; + wIntegral_sum_temp = pHandle->wIntegralTerm + wIntegral_Term; + + if (wIntegral_sum_temp < 0) + { + if (pHandle->wIntegralTerm > 0) + { + if (wIntegral_Term > 0) + { + wIntegral_sum_temp = INT32_MAX; + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do */ + } + } + else + { + if (pHandle->wIntegralTerm < 0) + { + if (wIntegral_Term < 0) + { + wIntegral_sum_temp = -INT32_MAX; + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do */ + } + } + + if (wIntegral_sum_temp > pHandle->wUpperIntegralLimit) + { + pHandle->wIntegralTerm = pHandle->wUpperIntegralLimit; + } + else if (wIntegral_sum_temp < pHandle->wLowerIntegralLimit) + { + pHandle->wIntegralTerm = pHandle->wLowerIntegralLimit; + } + else + { + pHandle->wIntegralTerm = wIntegral_sum_temp; + } + } + +#ifndef FULL_MISRA_C_COMPLIANCY_PID_REGULATOR + /* WARNING: the below instruction is not MISRA compliant, user should verify + that Cortex-M3 assembly instruction ASR (arithmetic shift right) + is used by the compiler to perform the shifts (instead of LSR + logical shift right)*/ + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wOutput_32 = (wProportional_Term >> pHandle->hKpDivisorPOW2) + + (pHandle->wIntegralTerm >> pHandle->hKiDivisorPOW2); +#else + wOutput_32 = (wProportional_Term / (int32_t)pHandle->hKpDivisor) + + (pHandle->wIntegralTerm / (int32_t)pHandle->hKiDivisor); +#endif + + if (wOutput_32 > hUpperOutputLimit) + { + wDischarge = hUpperOutputLimit - wOutput_32; + wOutput_32 = hUpperOutputLimit; + } + else if (wOutput_32 < hLowerOutputLimit) + { + wDischarge = hLowerOutputLimit - wOutput_32; + wOutput_32 = hLowerOutputLimit; + } + else + { + /* Nothing to do here */ + } + + pHandle->wIntegralTerm += wDischarge; + returnValue = (int16_t)wOutput_32; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif + return (returnValue); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Computes the output of a PID Regulator component, sum of its proportional, + * integral and derivative terms + * + * @param pHandle Handle on the PID component + * @param wProcessVarError current process variable error (the reference value minus the + * present process variable value) + * @retval computed PID controller output + * + * This function implements the proportional-integral-derivative controller function + * described by the @ref PIDRegulator "PID regulator component". The integral term is + * saturated by the upper and lower intergral term limit values before it is added to the + * proportional term and derivative terms. + * + * The resulting value is then saturated by the upper and lower output limit values before + * being returned. + */ +__weak int16_t PID_Controller(PID_Handle_t *pHandle, int32_t wProcessVarError) +{ + int16_t returnValue; +#ifdef NULL_PTR_CHECK_PID_REG + if (MC_NULL == pHandle) + { + returnValue = 0; + } + else + { +#endif + int32_t wDifferential_Term; + int32_t wDeltaError; + int32_t wTemp_output; + + if (0 == pHandle->hKdGain) /* derivative terms not used */ + { + wTemp_output = PI_Controller(pHandle, wProcessVarError); + } + else + { + wDeltaError = wProcessVarError - pHandle->wPrevProcessVarError; + wDifferential_Term = pHandle->hKdGain * wDeltaError; + +#ifndef FULL_MISRA_C_COMPLIANCY_PID_REGULATOR + /* WARNING: the below instruction is not MISRA compliant, user should verify + that Cortex-M3 assembly instruction ASR (arithmetic shift right) + is used by the compiler to perform the shifts (instead of LSR + logical shift right)*/ + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wDifferential_Term >>= pHandle->hKdDivisorPOW2; +#else + wDifferential_Term /= ((int32_t)pHandle->hKdDivisor); +#endif + + pHandle->wPrevProcessVarError = wProcessVarError; + + wTemp_output = PI_Controller(pHandle, wProcessVarError) + wDifferential_Term; + + if (wTemp_output > pHandle->hUpperOutputLimit) + { + wTemp_output = pHandle->hUpperOutputLimit; + } + else if (wTemp_output < pHandle->hLowerOutputLimit) + { + wTemp_output = pHandle->hLowerOutputLimit; + } + else + { + /* Nothing to do */ + } + } + returnValue = (int16_t)wTemp_output; +#ifdef NULL_PTR_CHECK_PID_REG + } +#endif + return (returnValue); +} +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pid_regulator.h b/src/firmware/motor/mcsdk/pid_regulator.h new file mode 100644 index 0000000000..2ea08ed0b8 --- /dev/null +++ b/src/firmware/motor/mcsdk/pid_regulator.h @@ -0,0 +1,290 @@ +/** + ****************************************************************************** + * @file pid_regulator.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * PID reulator component of the Motor Control SDK. + * + * The PID regulator component provides the functions needed to implement + * a proportional–integral–derivative controller. + * + * See @link PIDRegulator @endlink for more details. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup PIDRegulator + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef PIDREGULATOR_H +#define PIDREGULATOR_H + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup PIDRegulator + * @{ + */ + +/** + * @brief Handle of a PID component + * + * This structure holds all the parameters needed to implement + * a proportional-integral-derivative controller function. + * It also stores upper and lower limits used to saturate the + * integral term and the output values of the controller. + * + * A pointer on a structure of this type is passed to each + * function of the @ref PIDRegulator "PID Regulator component". + */ +typedef struct +{ + int16_t hDefKpGain; /**< @brief Default value of @f$K_{pg}@f$, the numerator of the + * proportional gain. + * + * The value of this field is copied into #hKpGain when the + * component is initialized. + * @see PID_HandleInit(). + */ + int16_t hDefKiGain; /**< @brief Default value of @f$K_{ig}@f$, the numerator if the + * integral gain + * + * The value of this field is copied into #hKiGain when the + * component is initialized. + * @see PID_HandleInit(). + */ + int16_t hKpGain; /**< @brief @f$K_{pg}@f$, numerator of the proportional gain of the + PID Regulator component */ + int16_t hKiGain; /**< @brief @f$K_{ig}@f$, numerator of the integral gain of the PID + Regulator component */ + int32_t wIntegralTerm; /**< @brief integral term of the PID Regulator + * + * This value is updated on each call to the PI_Controller() or + * PID_Controller() functions. It contains the + * integral term before being divided by @f$K_{id}@f$, + * the divisor of the integral gain: + * + * @f[ + * K_{ig}\times\sum_{k=0}^t{\epsilon_k} + * @f] + * + * This field is reset to 0 when the component is initialized. + * @see PID_HandleInit(). + */ + int32_t wUpperIntegralLimit; /**< @brief Upper limit used to saturate the integral + * term of the PID Regulator + * + * The integral term, #wIntegralTerm is capped to the + * value of this field. + */ + int32_t wLowerIntegralLimit; /**< @brief Lower limit used to saturate the integral + * term of the PID Regulator + * + * The integral term, #wIntegralTerm is floored to the + * value of this field. + */ + int16_t hUpperOutputLimit; /**< @brief Upper limit used to saturate the output of the + * PID Regulator + * + * The output of the PI or PID regulator function is capped + * to the valud of this field. + * @see PI_Controller() and PID_Controller() + */ + int16_t hLowerOutputLimit; /**< @brief Lower limit used to saturate the output of the + * PID Regulator + * + * The output of the PI or PID regulator function is + * floored to the valud of this field. + * @see PI_Controller() and PID_Controller() + */ + uint16_t + hKpDivisor; /**< @brief @f$K_{pd}@f$, divisor of the proportional gain + * + * Used in conjuction with @f$K_{pg}@f$, the proportional gain + * numerator to allow for obtaining fractional gain values. + * + * If #FULL_MISRA_C_COMPLIANCY is not defined the divisor is + * implemented through algebrical right shifts to speed up the + * execution of the controller functions. Only in this case does this + * parameter specify the number of right shifts to be executed. + */ + uint16_t + hKiDivisor; /**< @brief @f$K_{id}@f$, divisor of the integral gain gain + * + * Used in conjuction with @f$K_{ig}@f$, the integral gain numerator + * to allow for obtaining fractional gain values. + * + * If #FULL_MISRA_C_COMPLIANCY is not defined the divisor is + * implemented through algebrical right shifts to speed up + * the execution of the controller functions. Only in this + * case does this parameter specify the number of + * right shifts to be executed. + */ + uint16_t hKpDivisorPOW2; /**< @brief @f$K_{pd}@f$, divisor of the proportional gain, + * expressed as power of 2. + * + * E.g. if the divisor of the proportional gain is 512, the + * value of this field is 9 as @f$2^9 = 512@f$ + */ + uint16_t hKiDivisorPOW2; /**< @brief @f$K_{id}@f$, divisor of the integral gain, + * expressed as power of 2. + * + * E.g. if the divisor of the integral gain is 512, the value + * of this field is 9 as @f$2^9 = 512@f$ + */ + int16_t hDefKdGain; /**< @brief Default value of @f$K_{dg}@f$, the numerator of the + * derivative gain. + * + * The value of this field is copied into #hKdGain when the + * component is initialized. + * @see PID_HandleInit(). + */ + int16_t hKdGain; /**< @brief @f$K_{dg}@f$, numerator of the derivative gain of the PID + Regulator component */ + uint16_t + hKdDivisor; /**< @brief @f$K_{dd}@f$, divisor of the derivative gain gain + * + * Used in conjuction with @f$K_{dg}@f$, the derivative gain numerator + * to allow for obtaining fractional gain values. + * + * If #FULL_MISRA_C_COMPLIANCY is not defined the divisor is + * implemented through algebrical right shifts to speed up + * the execution of the controller functions. Only in this + * case does this parameter specify the number of + * right shifts to be executed. + */ + uint16_t hKdDivisorPOW2; /**< @brief @f$K_{dd}@f$, divisor of the derivative gain, + * expressed as power of 2. + * + * E.g. if the divisor of the integral gain is 512, the value + * of this field is 9 as @f$2^9 = 512@f$ + */ + int32_t wPrevProcessVarError; /**< @brief previous process variable used by the + * derivative part of the PID component + * + * This value is updated on each call to the + * PI_Controller() or PID_Controller() functions. + * + * This field is reset to 0 when the component is + * initialized. + * @see PID_HandleInit(). + */ +} PID_Handle_t; + +/* Initializes the handle of a PID component */ +void PID_HandleInit(PID_Handle_t *pHandle); + +/* Sets the numerator of Kp, the proportional gain of a PID component */ +void PID_SetKP(PID_Handle_t *pHandle, int16_t hKpGain); + +/* Updates the numerator of Ki, the integral gain of a PID component */ +void PID_SetKI(PID_Handle_t *pHandle, int16_t hKiGain); + +/* Returns the numerator of Kp, the proportional gain of a PID component */ +int16_t PID_GetKP(PID_Handle_t *pHandle); + +/* Returns the numerator of Ki, the integral gain of a PID component */ +int16_t PID_GetKI(PID_Handle_t *pHandle); + +/* Returns the default value of the numerator of Kp, the proportional gain of a PID + * component */ +int16_t PID_GetDefaultKP(PID_Handle_t *pHandle); + +/* Returns the default value of the numerator of Ki, the integral gain of a PID component + */ +int16_t PID_GetDefaultKI(PID_Handle_t *pHandle); + +/* Sets the value of the integral term of a PID component */ +void PID_SetIntegralTerm(PID_Handle_t *pHandle, int32_t wIntegralTermValue); + +/* Returns the divisor of Kp, the proportional gain of a PID component */ +uint16_t PID_GetKPDivisor(PID_Handle_t *pHandle); + +/* Returns the power of two that makes the divisor of Kp, the proportional gain of a PID + * component */ +uint16_t PID_GetKPDivisorPOW2(PID_Handle_t *pHandle); + +/* Sets the power of two that makes the divisor of Kp, the proportional gain of a PID + * component */ +void PID_SetKPDivisorPOW2(PID_Handle_t *pHandle, uint16_t hKpDivisorPOW2); + +/* Returns the divisor of Ki, the integral gain of a PID component */ +uint16_t PID_GetKIDivisor(PID_Handle_t *pHandle); + +/* Returns the power of two that makes the divisor of Ki, the inegral gain of a PID + * component */ +uint16_t PID_GetKIDivisorPOW2(PID_Handle_t *pHandle); + +/* Sets the power of two that makes the divisor of Ki, the integral gain of a PID + * component */ +void PID_SetKIDivisorPOW2(PID_Handle_t *pHandle, uint16_t hKiDivisorPOW2); + +/* Sets the lower limit of the integral term of a PID component */ +void PID_SetLowerIntegralTermLimit(PID_Handle_t *pHandle, int32_t wLowerLimit); + +/* Sets the upper limit of the integral term of a PID component */ +void PID_SetUpperIntegralTermLimit(PID_Handle_t *pHandle, int32_t wUpperLimit); + +/* Sets the lower output limit of a PID component */ +void PID_SetLowerOutputLimit(PID_Handle_t *pHandle, int16_t hLowerLimit); + +/* Sets the upper output limit of a PID component */ +void PID_SetUpperOutputLimit(PID_Handle_t *pHandle, int16_t hUpperLimit); + +/* Sets the value of the previous process error of a PID component */ +void PID_SetPrevError(PID_Handle_t *pHandle, int32_t wPrevProcessVarError); + +/* Sets the numerator of Kd, the derivative gain of a PID component */ +void PID_SetKD(PID_Handle_t *pHandle, int16_t hKdGain); + +/* Returns the numerator of Kd, the derivativz gain of a PID component */ +int16_t PID_GetKD(PID_Handle_t *pHandle); + +/* Returns the divisor of Kd, the derivative gain of a PID component */ +uint16_t PID_GetKDDivisor(PID_Handle_t *pHandle); + +/* Returns the power of two that makes the divisor of Kd, the derivative gain of a PID + * component */ +uint16_t PID_GetKDDivisorPOW2(PID_Handle_t *pHandle); + +/* Sets the power of two that makes the divisor of Kd, the derivative gain of a PID + * component */ +void PID_SetKDDivisorPOW2(PID_Handle_t *pHandle, uint16_t hKdDivisorPOW2); + +/* + * Computes the output of a PI Regulator component, sum of its proportional + * and integral terms + */ +int16_t PI_Controller(PID_Handle_t *pHandle, int32_t wProcessVarError); + +/* + * Computes the output of a PID Regulator component, sum of its proportional, + * integral and derivative terms + */ +int16_t PID_Controller(PID_Handle_t *pHandle, int32_t wProcessVarError); + +/** + * @} + */ + +/** + * @} + */ + +#endif /*PIDREGULATOR_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/potentiometer.c b/src/firmware/motor/mcsdk/potentiometer.c new file mode 100644 index 0000000000..56b092df80 --- /dev/null +++ b/src/firmware/motor/mcsdk/potentiometer.c @@ -0,0 +1,224 @@ +/** + ****************************************************************************** + * @file potentiometer.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides the functions that implement the potentiometer + * component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup Potentiometer + */ + +/* Includes ------------------------------------------------------------------*/ +#include "potentiometer.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup Potentiometer Linear Potentiometer + * @brief Linear Potentiometer reading component of the Motor Control SDK + * + * The Potentiometer component aims at measuring the voltage set on a linear + * potentiometer. It uses the services of the @ref RCM component to get measures + * from an ADC channel connected to the potentiometer. + * + * The component is designed to take potentiometer measures periodically. It + * computes a moving average on a number of these measures in order to reduce + * the reading noise. This moving average is the potentiometer value produced + * by the component. It is retrieved by calling the POT_GetValue() function. + * + * The measures are taken by the POT_TakeMeasurement() function. This + * function must then be called periodically. + * + * At startup or after a call to the POT_Clear() function, a valid average + * potentiometer value is not immediately available. Enough measures need to be + * taken so that the moving average can be computed. The POT_ValidValueAvailable() + * function can be used to check whether a valid potentiometer value is returned + * when calling the POT_GetValue() function. + * + * The state of a Potentiometer component is maintained in a Potentiometer_Handle_t + * structure. To use the Potentiometer component, a Potentiometer_Handle_t structure + * needs to be instanciated and initialized. The initialization is performed thanks + * to the POT_Init() function. Prior to calling this function, some of the fields of + * this structure need to be given a value. See the Potentiometer_Handle_t and below + * for more details on this. + * + * The Potentiometer component accumulates a number of measures on which it + * computes a moving average. For performance reasons, this number must be a + * power of two. This is set in the Potentiometer_Handle_t::LPFilterBandwidthPOW2 + * field of the potentiometer handle structure. + * + * @note In the current version of the Potentiometer component, the periodic ADC + * measures **must** be performed on the Medium Frequency Task. This can be done by using + * the MC_APP_PostMediumFrequencyHook_M1() function of the @ref MCAppHooks service + * for instance. + * + * @{ + */ + +/* Public functions ----------------------------------------------------------*/ +/** + * @brief Initializes a Potentiometer component + * + * This function must be called once before starting to use the component. + * + * @param pHandle Handle on the Potentiometer component to initialize + */ +void POT_Init(Potentiometer_Handle_t* pHandle) +{ +#ifdef NULL_PTR_POT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif /* NULL_PTR_POT */ + /* RCM component initialization */ + pHandle->PotRegConvHandle = RCM_RegisterRegConv(&pHandle->PotRegConv); + + /* Potentiometer component init */ + pHandle->LPFilterBandwidth = (uint16_t)(1 << pHandle->LPFilterBandwidthPOW2); + POT_Clear(pHandle); +#ifdef NULL_PTR_POT + } +#endif /* NULL_PTR_POT */ +} + +/** + * @brief Clears the state of a Potentiometer component + * + * After this function has been called, the potentiometer value + * becomes invalid. See the @ref Potentiometer documentation for more + * details. + * + * @param pHandle Handle on the Potentiometer component + */ +void POT_Clear(Potentiometer_Handle_t* pHandle) +{ +#ifdef NULL_PTR_POT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif /* NULL_PTR_POT */ + for (uint8_t i = 0; i < pHandle->LPFilterBandwidth; i++) + { + pHandle->PotMeasArray[i] = (uint16_t)0; + } + + pHandle->PotValueAccumulator = (uint32_t)0; + pHandle->Index = (uint16_t)0; + pHandle->Valid = (bool)false; +#ifdef NULL_PTR_POT + } +#endif /* NULL_PTR_POT */ +} + +/** + * @brief Measures the voltage of the potentiometer of a Potentiometer component + * + * This function needs to be called periodically. See the @ref Potentiometer + * documentation for more details. + * + * @param pHandle Handle on the Potentiometer component + */ +void POT_TakeMeasurement(Potentiometer_Handle_t* pHandle) +{ +#ifdef NULL_PTR_POT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif /* NULL_PTR_POT */ + /* Read potentiometer measurement from ADC */ + uint16_t rawValue = RCM_ExecRegularConv(pHandle->PotRegConvHandle); + + /* Update the Accumulator */ + pHandle->PotValueAccumulator -= (uint32_t)pHandle->PotMeasArray[pHandle->Index]; + pHandle->PotMeasArray[pHandle->Index] = rawValue; + pHandle->PotValueAccumulator += (uint32_t)pHandle->PotMeasArray[pHandle->Index]; + + /* Update the Index */ + pHandle->Index++; + if (pHandle->Index == pHandle->LPFilterBandwidth) + { + pHandle->Index = 0; + /* The Index has reached the end of the measurement array. + * So, the accumulator is only made of actual measure. + * Hence, its value is considered valid. */ + pHandle->Valid = true; + } +#ifdef NULL_PTR_POT + } +#endif /* NULL_PTR_POT */ +} + +/** + * @brief Returns the current value of a Potentiometer component + * + * @param pHandle Handle on the Potentiometer component + */ +uint16_t POT_GetValue(Potentiometer_Handle_t* pHandle) +{ +#ifdef NULL_PTR_POT + if (MC_NULL == pHandle) + { + return (uint16_t)0; + } + else + { +#endif /* NULL_PTR_POT */ + return (uint16_t)(pHandle->PotValueAccumulator >> pHandle->LPFilterBandwidthPOW2); +#ifdef NULL_PTR_POT + } +#endif /* NULL_PTR_POT */ +} + +/** + * @brief Returns true if the current value of a Potentiometer component is valid + * and false otherwise + * + * @param pHandle Handle on the Potentiometer component + */ +bool POT_ValidValueAvailable(Potentiometer_Handle_t* pHandle) +{ +#ifdef NULL_PTR_POT + if (MC_NULL == pHandle) + { + return (uint16_t) false; + } + else + { +#endif /* NULL_PTR_POT */ + return pHandle->Valid; +#ifdef NULL_PTR_POT + } +#endif /* NULL_PTR_POT */ +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/potentiometer.h b/src/firmware/motor/mcsdk/potentiometer.h new file mode 100644 index 0000000000..bccc2284cd --- /dev/null +++ b/src/firmware/motor/mcsdk/potentiometer.h @@ -0,0 +1,130 @@ +/** + ****************************************************************************** + * @file potentiometer.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains the definitions and functions prototypes for the + * Potentiometer component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup Potentiometer + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef POTENTIOMETER_H +#define POTENTIOMETER_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/regular_conversion_manager.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup Potentiometer + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief Handle structure of a Potentiometer component. + * + * A potentiometer component aims at measuring the voltage + * across a potentiometer thanks to an ADC. + * + * This structure contains all the information needed for a Potentiometer + * component instance to work. + * + * See the @ref Potentiometer component documentation for more details. + */ + typedef struct + { + RegConv_t PotRegConv; /**< @brief Structure configuring the + * [Regular Conversion Manager](#RCM) to + * measure of the level of the potentiometer + * + * The fields of this structure must be set prior + * to calling the POT_Init() function + */ + uint16_t* PotMeasArray; /**< @brief Array for storing raw potentiometer measures + * + * This field must point to a reserved array of uint16_t + * prior to calling the POT_Init() function. The size of + * this array must be @f$2^{LPFilterBandwidthPOW2}@f$. + * + * See #LPFilterBandwidthPOW2. + */ + uint32_t PotValueAccumulator; /**< @brief accumulated potentiometer measures */ + uint8_t + LPFilterBandwidthPOW2; /**< @brief Number of measures used to compute the + * average value, expressed as a power of 2 + * + * For instance, if the number of measures is 16, the + * value of this field must be 4 since @f$16 = 2^4@f$. + * + * This field must be set prior to calling POT_Init() + */ + uint8_t LPFilterBandwidth; /**< @brief Number of measures used to compute the + * average value + * + * This value is set to @f$2^{LPFilterBandwidthPOW2}@f$ + * by the POT_Init() function. + * + * See #LPFilterBandwidthPOW2. + */ + uint8_t Index; /**< @brief position where the next measure will be put in + #PotMeqsArray */ + uint8_t + PotRegConvHandle; /**< @brief Handle on the [Regular Conversion Manager](#RCM) + * to manage the measures of the potentiometer */ + bool Valid; /**< @brief Indicates the validity of #PotValueAccumulator + * + * See the @ref Potentiometer documentation for more details. + */ + } Potentiometer_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /* Potentiometer component initialization */ + void POT_Init(Potentiometer_Handle_t* pHandle); + /* Clears the state of a Potentiometer component */ + void POT_Clear(Potentiometer_Handle_t* pHandle); + /* Measures the voltage of the potentiometer */ + void POT_TakeMeasurement(Potentiometer_Handle_t* pHandle); + + /* Returns the current potentiometer value */ + uint16_t POT_GetValue(Potentiometer_Handle_t* pHandle); + /* Returns true if the current potentiometer value is valid */ + bool POT_ValidValueAvailable(Potentiometer_Handle_t* pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* POTENTIOMETER_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pqd_motor_power_measurement.c b/src/firmware/motor/mcsdk/pqd_motor_power_measurement.c new file mode 100644 index 0000000000..35268259fd --- /dev/null +++ b/src/firmware/motor/mcsdk/pqd_motor_power_measurement.c @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * @file pqd_motor_power_measurement.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides the functions that implement the features of the + * PQD Motor Power Measurement component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pqd_motorpowermeasurement + */ + +/* Includes ------------------------------------------------------------------*/ + +#include "pqd_motor_power_measurement.h" + +#include "mc_type.h" + + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup pqd_motorpowermeasurement PQD Motor Power Measurement + * @brief Motor Power Measurement component using DQ-frame current and voltage values + * + * The PQD Motor Power Measurement component uses @f$I_d@f$, @f$I_q@f$, @f$V_d@f$ and + * @f$V_q@f$ to compute the electrical power flowing through the motor. + * + * These values are periodically sampled from the current regulation loop and used to + * compute instantaneous power values. The instantaneous values are then used to compute + * an average power value that is stored. These computations are done with integer + * operations and the average value is store as an integer, in s16 digit format (s16A x + * s16V unit). + * + * The PQD Motor Power Measurement component provides an interface, + * PQD_GetAvrgElMotorPowerW() that converts the int16_t digit average power into a + * floating point value expressed in Watts. + * + * @{ + */ + +/** + * @brief Updates the average electrical motor power measure with the latest values + * of the DQ currents and voltages. + * + * This method should be called with Medium Frequency Task periodicity. It computes an + * instantaneous power value using the latest @f$I_{qd}@f$ and @f$V_{qd}@f$ data available + * and uses it to update the average motor power value. + * + * Computations are done on s16A and s16V integer values defined in + * [Current measurement unit](measurement_units.md). The average motor power value is + * computed as an int16_t value. + * + * @param pHandle Handle on the related PQD Motor Power Measurement component instance. + */ +__weak void PQD_CalcElMotorPower(PQD_MotorPowMeas_Handle_t *pHandle) +{ +#ifdef NULL_PTR_MOT_POW_MEAS + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int32_t wAux; + qd_t Iqd = pHandle->pFOCVars->Iqd; + qd_t Vqd = pHandle->pFOCVars->Vqd; + + wAux = ((int32_t)Iqd.q * (int32_t)Vqd.q) + ((int32_t)Iqd.d * (int32_t)Vqd.d); + wAux /= 65536; + + pHandle->hAvrgElMotorPower += (wAux - pHandle->hAvrgElMotorPower) >> 4; + +#ifdef NULL_PTR_MOT_POW_MEAS + } +#endif +} + +/** + * @brief Clears the int16_t digit average motor power value stored in the handle. + * + * This function should be called before each motor start. + * + * @param pHandle Handle on the related PQD Motor Power Measurement component instance. + */ +__weak void PQD_Clear(PQD_MotorPowMeas_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_MOT_POW_MES + if (MC_NULL == pHandle) + { + /* nothing to do */ + } + else + { +#endif + pHandle->hAvrgElMotorPower = 0; +#ifdef NULL_PTR_CHECK_MOT_POW_MES + } +#endif +} + +/** + * @brief Returns an average value of the measured motor power expressed in Watts + * + * This function converts the int16_t digit average motor power value stored in the handle + * in a floating point value in Watts. + * + * @param pHandle pointer on the related component instance. + * @retval float The average measured motor power expressed in Watts. + */ +__weak float PQD_GetAvrgElMotorPowerW(const PQD_MotorPowMeas_Handle_t *pHandle) +{ + float PowerW = 0.0; + +#ifdef NULL_PTR_MOT_POW_MEAS + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + + /* First perform an integer multiplication, then a float one. */ + PowerW = (pHandle->hAvrgElMotorPower * VBS_GetAvBusVoltage_V(pHandle->pVBS)) * + pHandle->ConvFact; + +#ifdef NULL_PTR_MOT_POW_MEAS + } +#endif + return (PowerW); +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pqd_motor_power_measurement.h b/src/firmware/motor/mcsdk/pqd_motor_power_measurement.h new file mode 100644 index 0000000000..b853249484 --- /dev/null +++ b/src/firmware/motor/mcsdk/pqd_motor_power_measurement.h @@ -0,0 +1,90 @@ +/** + ****************************************************************************** + * @file pqd_motor_power_measurement.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * PQD Motor Power Measurement component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pqd_motorpowermeasurement + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef PQD_MOTORPOWERMEASUREMENT_H +#define PQD_MOTORPOWERMEASUREMENT_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/bus_voltage_sensor.h" + + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup pqd_motorpowermeasurement + * @{ + */ + + /** + * @brief Handle of a PQD Motor Power Measurement component + * + * PQD Motor Power Measurement components compute a value of the average electrical + * power flowing into a motor from the QD-frame @f$I_{qd}@f$ and @f$V_{qd}@f$ values. + * + */ + typedef struct + { + int16_t hAvrgElMotorPower; /**< @brief Average measured motor power expressed in + s16 digit (s16A x s16V). */ + + float ConvFact; /**< @brief Factor used to convert s16 digit average motor power + values into Watts. Set to @f[\sqrt{3} \frac{V_{dd}}{R_{shunt} + \times A_{op} \times 65536}@f] */ + + pFOCVars_t pFOCVars; /**< @brief Pointer to FOC vars. */ + BusVoltageSensor_Handle_t + *pVBS; /**< @brief Bus voltage sensor component handle. */ + } PQD_MotorPowMeas_Handle_t; + + + /* Updates the average electrical motor power measure with the latest values of the DQ + * currents and voltages. */ + void PQD_CalcElMotorPower(PQD_MotorPowMeas_Handle_t *pHandle); + + /* Clears the the int16_t digit average motor power value stored in the handle */ + void PQD_Clear(PQD_MotorPowMeas_Handle_t *pHandle); + + /* Returns an average value of the measured motor power expressed in Watts */ + float PQD_GetAvrgElMotorPowerW(const PQD_MotorPowMeas_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* PQD_MOTORPOWERMEASUREMENT_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pwm_common.c b/src/firmware/motor/mcsdk/pwm_common.c new file mode 100644 index 0000000000..786e9eba57 --- /dev/null +++ b/src/firmware/motor/mcsdk/pwm_common.c @@ -0,0 +1,129 @@ +/** + ****************************************************************************** + * @file pwm_common.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement common features + * of the PWM & Current Feedback component of the Motor Control SDK: + * + * * start timers (main and auxiliary) synchronously + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pwm_curr_fdbk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/pwm_common.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup pwm_curr_fdbk + * @{ + */ + +#ifdef TIM2 +/** + * @brief Performs the start of all the timers required by the control. + * + * Uses TIM2 as a temporary timer to achieve synchronization between PWM signals. + * When this function is called, TIM1 and/or TIM8 must be in a frozen state + * with CNT, ARR, REP RATE and trigger correctly set (these settings are + * usually performed in the Init method accordingly with the configuration) + */ +__weak void startTimers(void) +{ + uint32_t isTIM2ClockOn; + uint32_t trigOut; + + isTIM2ClockOn = LL_APB1_GRP1_IsEnabledClock(LL_APB1_GRP1_PERIPH_TIM2); + if ((uint32_t)0 == isTIM2ClockOn) + { + /* Temporary Enable TIM2 clock if not already on */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + LL_TIM_GenerateEvent_UPDATE(TIM2); + LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); + } + else + { + trigOut = LL_TIM_ReadReg(TIM2, CR2) & TIM_CR2_MMS; + LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_UPDATE); + LL_TIM_GenerateEvent_UPDATE(TIM2); + LL_TIM_SetTriggerOutput(TIM2, trigOut); + } +} +#endif + +/** + * @brief Waits for the end of the polarization. + * + * If the polarization exceeds the number of needed PWM cycles, it reports an error. + * + * @param TIMx Timer used to generate PWM. + * @param SWerror Variable used to report a SW error. + * @param repCnt Repetition counter value. + * @param cnt Polarization counter value. + */ +__weak void waitForPolarizationEnd(TIM_TypeDef *TIMx, uint16_t *SWerror, uint8_t repCnt, + volatile uint8_t *cnt) +{ +#ifdef NULL_POW_COM + if ((MC_NULL == cnt) || (MC_NULL == SWerror)) + { + /* Nothing to do */ + } + else + { +#endif + uint16_t hCalibrationPeriodCounter; + uint16_t hMaxPeriodsNumber; + + hMaxPeriodsNumber = + ((uint16_t)2 * NB_CONVERSIONS) * (((uint16_t)repCnt + 1U) >> 1); + + /* Wait for NB_CONVERSIONS to be executed */ + LL_TIM_ClearFlag_CC1(TIMx); + hCalibrationPeriodCounter = 0u; + while (*cnt < NB_CONVERSIONS) + { + if ((uint32_t)ERROR == LL_TIM_IsActiveFlag_CC1(TIMx)) + { + LL_TIM_ClearFlag_CC1(TIMx); + hCalibrationPeriodCounter++; + if (hCalibrationPeriodCounter >= hMaxPeriodsNumber) + { + if (*cnt < NB_CONVERSIONS) + { + *SWerror = 1u; + break; + } + } + } + } +#ifdef NULL_POW_COM + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pwm_common.h b/src/firmware/motor/mcsdk/pwm_common.h new file mode 100644 index 0000000000..39d3a5fbab --- /dev/null +++ b/src/firmware/motor/mcsdk/pwm_common.h @@ -0,0 +1,84 @@ +/** + ****************************************************************************** + * @file pwm_common.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * PWM & Current Feedback component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pwm_curr_fdbk + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef PWMNCOMMON_H +#define PWMNCOMMON_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" + + +/** + * @brief The maximum number of needed PWM cycles. verif? + */ +#define NB_CONVERSIONS 16u + + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup pwm_curr_fdbk + * @{ + */ + +/* Exported defines ----------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +#ifdef TIM2 + /* + * Performs the start of all the timers required by the control. + * It uses TIM2 as a temporary timer to achieve synchronization between PWM signals. + * When this function is called, TIM1 and/or TIM8 must be in a frozen state + * with CNT, ARR, REP RATE and trigger correctly set (these settings are + * usually performed in the Init method accordingly with the configuration) + */ + void startTimers(void); +#endif + /* + * Waits for the end of the polarization. If the polarization exceeds + * the number of needed PWM cycles, it reports an error. + */ + void waitForPolarizationEnd(TIM_TypeDef *TIMx, uint16_t *SWerror, uint8_t repCnt, + volatile uint8_t *cnt); + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* PWMNCOMMON_H */ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pwm_common_sixstep.c b/src/firmware/motor/mcsdk/pwm_common_sixstep.c new file mode 100644 index 0000000000..c5ad4ac80a --- /dev/null +++ b/src/firmware/motor/mcsdk/pwm_common_sixstep.c @@ -0,0 +1,304 @@ +/** + ****************************************************************************** + * @file pwm_common_sixstep.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the following features + * of the six-step PWM component of the Motor Control SDK: + * + * * ADC triggering for sensorless bemf acquisition + * * translation of the electrical angle in step sequence + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pwm_curr_fdbk_6s + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/pwm_common_sixstep.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup pwm_curr_fdbk + * @{ + */ + +/** @defgroup pwm_curr_fdbk_6s Six-Step PWM generation + * + * @brief PWM components for Six Step drive + * + * @todo Complete documentation for the pwm_curr_fdbk_6s module + * + * @{ + */ + +/** + * @brief It is used to clear the variable in CPWMC. + * @param this related object of class CPWMC + * @retval none + */ +void PWMC_Clear(PWMC_Handle_t *pHandle) {} + +/** + * @brief Switches PWM generation off, inactivating the outputs. + * @param pHandle Handle on the target instance of the PWMC component + */ +__weak void PWMC_SwitchOffPWM(PWMC_Handle_t *pHandle) +{ + pHandle->pFctSwitchOffPwm(pHandle); +} + +/** + * @brief Switches PWM generation on + * @param pHandle Handle on the target instance of the PWMC component + */ +__weak void PWMC_SwitchOnPWM(PWMC_Handle_t *pHandle) +{ + pHandle->pFctSwitchOnPwm(pHandle); +} + +/** + * @brief Set the ADC trigger point for bemf acquisition. + * @param pHandle Handle on the target instance of the PWMC component + * @param SamplingPoint pulse value of the timer channel used for ADC triggering + */ +__weak void PWMC_SetADCTriggerChannel(PWMC_Handle_t *pHandle, uint16_t SamplingPoint) +{ + pHandle->pFctSetADCTriggerChannel(pHandle, SamplingPoint); +} + +/** + * @brief Switches power stage Low Sides transistors on. + * + * This function is meant for charging boot capacitors of the driving + * section. It has to be called on each motor start-up when using high + * voltage drivers. + * + * @param pHandle: handle on the target instance of the PWMC component + */ +__weak void PWMC_TurnOnLowSides(PWMC_Handle_t *pHandle, uint32_t ticks) +{ + pHandle->pFctTurnOnLowSides(pHandle, ticks); +} + +/** @brief Returns #MC_BREAK_IN if an over current condition was detected on the power + * stage controlled by the PWMC component pointed by @p pHandle, since the last call to + * this function; returns #MC_NO_FAULTS otherwise. */ +__weak uint16_t PWMC_CheckOverCurrent(PWMC_Handle_t *pHandle) +{ + return pHandle->pFctIsOverCurrentOccurred(pHandle); +} + +/** + * @brief It is used to retrieve the satus of TurnOnLowSides action. + * @param pHandle: handler of the current instance of the PWMC component + * @retval bool It returns the state of TurnOnLowSides action: + * true if TurnOnLowSides action is active, false otherwise. + */ +/** @brief Returns the status of the "TurnOnLowSide" action on the power stage + * controlled by the @p pHandle PWMC component: true if it + * is active, false otherwise*/ +__weak bool PWMC_GetTurnOnLowSidesAction(PWMC_Handle_t *pHandle) +{ + return pHandle->TurnOnLowSidesAction; +} + +/** + * @brief It is used to set the align motor flag. + * @param this related object of class CPWMC + * @param flag to be applied in uint8_t, 1: motor is in align stage, 2: motor is not in + * align stage + * @retval none + */ +void PWMC_SetAlignFlag(PWMC_Handle_t *pHandle, int16_t flag) +{ + pHandle->AlignFlag = flag; +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to switch PWM + * generation off. + * @param pCallBack pointer on the callback + * @param pHandle pointer on the handle structure of the PWMC instance + * + */ +__weak void PWMC_RegisterSwitchOffPwmCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ + pHandle->pFctSwitchOffPwm = pCallBack; +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to switch PWM + * generation on. + * @param pCallBack pointer on the callback + * @param pHandle pointer on the handle structure of the PWMC instance + * + */ +__weak void PWMC_RegisterSwitchonPwmCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ + pHandle->pFctSwitchOnPwm = pCallBack; +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to turn low sides on. + * @param pCallBack pointer on the callback + * @param pHandle pointer on the handle structure of the PWMC instance + * + */ +__weak void PWMC_RegisterTurnOnLowSidesCallBack(PWMC_TurnOnLowSides_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ + pHandle->pFctTurnOnLowSides = pCallBack; +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to the overcurrent status + * @param pCallBack pointer on the callback + * @param pHandle pointer on the handle structure of the PWMC instance + * + */ +__weak void PWMC_RegisterIsOverCurrentOccurredCallBack(PWMC_OverCurr_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ + pHandle->pFctIsOverCurrentOccurred = pCallBack; +} + +/** + * @brief It forces the Fast Demag interval to the passed value + * @param pHandle: handler of the current instance of the PWM component + * @param uint16_t: period where the fast demagnetization is applied + * @retval none + */ +void PWMC_ForceFastDemagTime(PWMC_Handle_t *pHandle, uint16_t constFastDemagTime) +{ + pHandle->DemagCounterThreshold = constFastDemagTime; +} + +/** + * @brief It enables/disables the Fast Demag feature at next step change + * @param pHandle: handler of the current instance of the PWM component + * @param uint8_t: 0=disable, 1=enable + * @retval none + */ +void PWMC_SetFastDemagState(PWMC_Handle_t *pHandle, uint8_t State) +{ + if (State == 1) + { + pHandle->ModUpdateReq = ENABLE_FAST_DEMAG; + } + else + { + pHandle->ModUpdateReq = DISABLE_FAST_DEMAG; + } +} + +/** + * @brief It enables/disables the Qusi Synch feature at next step change + * @param pHandle: handler of the current instance of the PWM component + * @param uint8_t: 0=disable, 1=enable + * @retval none + */ +void PWMC_SetQuasiSynchState(PWMC_Handle_t *pHandle, uint8_t State) +{ + if (State == 1) + { + pHandle->ModUpdateReq = ENABLE_QUASI_SYNCH; + } + else + { + pHandle->ModUpdateReq = DISABLE_QUASI_SYNCH; + } +} + +/** + * @brief It returns the Fast Demag feature status + * @param pHandle: handler of the current instance of the PWM component + * @retval uint8_t: 0=disabled, 1=enabled + */ +uint8_t PWMC_GetFastDemagState(PWMC_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle->pGetFastDemagFlag) + ? 0 + : pHandle->pGetFastDemagFlag(pHandle)); +} + +/** + * @brief It returns the Quasi Synch feature status + * @param pHandle: handler of the current instance of the PWM component + * @retval uint8_t: 0=disabled, 1=enabled + */ +uint8_t PWMC_GetQuasiSynchState(PWMC_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle->pGetQuasiSynchFlag) + ? 0 + : pHandle->pGetQuasiSynchFlag(pHandle)); +} + +/** + * @brief Converts the motor electrical angle to the corresponding step in the six-step + * sequence + * @param pHandle pointer on the handle structure of the PWMC instance + * @retval calculated step + */ +__weak uint8_t PWMC_ElAngleToStep(PWMC_Handle_t *pHandle) +{ + uint8_t Step; + if ((pHandle->hElAngle >= (int16_t)(S16_60_PHASE_SHIFT / 2)) && + (pHandle->hElAngle < (int16_t)(S16_60_PHASE_SHIFT + S16_60_PHASE_SHIFT / 2))) + Step = STEP_1; + else if ((pHandle->hElAngle >= + (int16_t)(S16_60_PHASE_SHIFT + S16_60_PHASE_SHIFT / 2)) && + (pHandle->hElAngle < + (int16_t)(S16_120_PHASE_SHIFT + S16_60_PHASE_SHIFT / 2))) + Step = STEP_2; + else if ((pHandle->hElAngle >= + (int16_t)(S16_120_PHASE_SHIFT + S16_60_PHASE_SHIFT / 2)) || + (pHandle->hElAngle < + (int16_t)(-S16_120_PHASE_SHIFT - S16_60_PHASE_SHIFT / 2))) + Step = STEP_3; + else if ((pHandle->hElAngle >= + (int16_t)(-S16_120_PHASE_SHIFT - S16_60_PHASE_SHIFT / 2)) && + (pHandle->hElAngle < + (int16_t)(-S16_60_PHASE_SHIFT - S16_60_PHASE_SHIFT / 2))) + Step = STEP_4; + else if ((pHandle->hElAngle >= + (int16_t)(-S16_60_PHASE_SHIFT - S16_60_PHASE_SHIFT / 2)) && + (pHandle->hElAngle < (int16_t)(-S16_60_PHASE_SHIFT / 2))) + Step = STEP_5; + else if ((pHandle->hElAngle >= (int16_t)(-S16_60_PHASE_SHIFT / 2)) && + (pHandle->hElAngle < (int16_t)(S16_60_PHASE_SHIFT / 2))) + Step = STEP_6; + else + { + } + return Step; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pwm_common_sixstep.h b/src/firmware/motor/mcsdk/pwm_common_sixstep.h new file mode 100644 index 0000000000..63b4e5571c --- /dev/null +++ b/src/firmware/motor/mcsdk/pwm_common_sixstep.h @@ -0,0 +1,268 @@ +/** + ****************************************************************************** + * @file pwm_common_sixstep.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * six-step PWM component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pwm_curr_fdbk_6s + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef PWMNCOMMON_SIXSTEP_H +#define PWMNCOMMON_SIXSTEP_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" +#define NB_CONVERSIONS 16u + +#define S16_120_PHASE_SHIFT (int16_t)(65536 / 3) +#define S16_60_PHASE_SHIFT (int16_t)(65536 / 6) + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup pwm_curr_fdbk + * @{ + */ + + /** @addtogroup pwm_curr_fdbk_6s + * @{ + */ + /* Exported defines ------------------------------------------------------------*/ + +#define STEP_1 0U +#define STEP_2 1U +#define STEP_3 2U +#define STEP_4 3U +#define STEP_5 4U +#define STEP_6 5U + + /* Exported defines ----------------------------------------------------------*/ + + /* Exported types ------------------------------------------------------------*/ + + /** @brief PWMC component handle type */ + typedef struct PWMC_Handle PWMC_Handle_t; + + /** + * @brief Pointer on callback functions used by PWMC components + * + * This type is needed because the actual functions to use can change at run-time. + * + * See the following items: + * - PWMC_Handle::pFctSwitchOffPwm + * - PWMC_Handle::pFctSwitchOnPwm + + * + * + */ + typedef void (*PWMC_Generic_Cb_t)(PWMC_Handle_t *pHandle); + + /** + * @brief Pointer on the function provided by the PMWC component instance to set low + * sides ON. + * + * This type is needed because the actual function to use can change at run-time + * (See PWMC_Handle::pFctTurnOnLowSides). + * + */ + typedef void (*PWMC_TurnOnLowSides_Cb_t)(PWMC_Handle_t *pHandle, + const uint32_t ticks); + + + /** + * @brief Pointer on the function provided by the PMWC component instance to set the + * trigger point of the ADC. + * + * This type is needed because the actual function to use can change at run-time + * (See PWMC_Handle::pFctOCPSetReferenceVoltage). + * + */ + typedef void (*PWMC_SetADCTriggerChannel_Cb_t)(PWMC_Handle_t *pHandle, + uint16_t hDACVref); + + + /** + * @brief Pointer on the function provided by the PMWC component instance to check if + * an over current condition has occured. + * + * This type is needed because the actual function to use can change at run-time + * (See PWMC_Handle::pFctIsOverCurrentOccurred). + * + */ + typedef uint16_t (*PWMC_OverCurr_Cb_t)(PWMC_Handle_t *pHandle); + + /** + * @brief Pointer on the function provided by the PMWC component instance to check + * optional modulation features flag (fast demagnetization and quasi-synchronous + * rectification) + * + */ + typedef uint8_t (*PWMC_ModFlag_Cb_t)(PWMC_Handle_t *pHandle); + + /** + * @brief This structure is used to handle the status change of optional modulation + * features + * + */ + typedef enum + { + NO_REQUEST, + ENABLE_FAST_DEMAG, + DISABLE_FAST_DEMAG, + ENABLE_QUASI_SYNCH, + DISABLE_QUASI_SYNCH + } PWMTableUpdate_t; + + /** + * @brief This structure is used to handle the data of an instance of the PWM + * component + * + */ + struct PWMC_Handle + { + /** @{ */ + PWMC_Generic_Cb_t pFctSwitchOffPwm; /**< pointer on the function the component + instance used to switch PWM off */ + PWMC_Generic_Cb_t pFctSwitchOnPwm; /**< pointer on the function the component + instance used to switch PWM on */ + PWMC_SetADCTriggerChannel_Cb_t /**< pointer on the function the component instance + used to set the trigger point of the ADC */ + pFctSetADCTriggerChannel; + PWMC_TurnOnLowSides_Cb_t + pFctTurnOnLowSides; /**< pointer on the function the component instance used + to turn low sides on */ + PWMC_OverCurr_Cb_t + pFctIsOverCurrentOccurred; /**< pointer on the fct the component instance used + to return the over current status */ + PWMC_ModFlag_Cb_t + pGetFastDemagFlag; /**< pointer on the fct the component instance used to + return the fast demag status */ + PWMC_ModFlag_Cb_t + pGetQuasiSynchFlag; /**< pointer on the fct the component instance used to + return the quasi-Synch rectification status */ + /** @} */ + uint16_t CntPh; /**< PWM Duty cycle phase*/ + uint16_t StartCntPh; /**< Start-up PWM Duty cycle phase*/ + uint16_t ADCTriggerCnt; /**< Timer output trigger point used for ADC triggering */ + uint16_t SWerror; /**< Contains status about SW error */ + uint16_t PWMperiod; /**< PWM period expressed in timer clock cycles unit: + * @f$hPWMPeriod = TimerFreq_{CLK} / F_{PWM}@f$ */ + uint16_t DTCompCnt; /**< Half of Dead time expressed + * in timer clock cycles unit: + * @f$hDTCompCnt = (DT_s \cdot TimerFreq_{CLK})/2@f$ */ + + uint8_t Motor; /**< Motor reference number */ + int16_t AlignFlag; /*!< phase current 0 is reliable, 1 is bad */ + uint8_t NextStep; /**< Step number to be applied the step number */ + uint8_t Step; /**< Step number */ + uint16_t DemagCounterThreshold; + int16_t hElAngle; + bool TurnOnLowSidesAction; /**< true if TurnOnLowSides action is active, + false otherwise. */ + PWMTableUpdate_t + ModUpdateReq; /**< Request flag of optional modulation features status */ + }; + + /* Exported functions --------------------------------------------------------*/ + + /* Switches the PWM generation off, setting the outputs to inactive */ + void PWMC_SwitchOffPWM(PWMC_Handle_t *pHandle); + + /* Switches the PWM generation on */ + void PWMC_SwitchOnPWM(PWMC_Handle_t *pHandle); + + /* Set the trigger instant of the ADC for Bemf acquisition*/ + void PWMC_SetADCTriggerChannel(PWMC_Handle_t *pHdl, uint16_t SamplingPoint); + + /* Turns low sides on. This function is intended to be used for + * charging boot capacitors of driving section. It has to be called on each + * motor start-up when using high voltage drivers. */ + void PWMC_TurnOnLowSides(PWMC_Handle_t *pHandle, uint32_t ticks); + + /* Checks if an over current occurred since last call. */ + uint16_t PWMC_CheckOverCurrent(PWMC_Handle_t *pHandle); + + /* Retrieves the status of the "TurnOnLowSides" action. */ + bool PWMC_GetTurnOnLowSidesAction(PWMC_Handle_t *pHandle); + + /* It is used to set the align motor flag.*/ + void PWMC_SetAlignFlag(PWMC_Handle_t *pHandle, int16_t flag); + + /* Sets the Callback that the PWMC component shall invoke to switch off PWM + * generation. */ + void PWMC_RegisterSwitchOffPwmCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to switch on PWM + * generation. */ + void PWMC_RegisterSwitchonPwmCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to turn on low sides. */ + void PWMC_RegisterTurnOnLowSidesCallBack(PWMC_TurnOnLowSides_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to the over current status. + */ + void PWMC_RegisterIsOverCurrentOccurredCallBack(PWMC_OverCurr_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* It is used to clear the variable in CPWMC. */ + void PWMC_Clear(PWMC_Handle_t *pHandle); + + /* It forces the Fast Demag interval to the passed value */ + void PWMC_ForceFastDemagTime(PWMC_Handle_t *pHdl, uint16_t constFastDemagTime); + + /* It enables/disables the Fast Demag feature */ + void PWMC_SetFastDemagState(PWMC_Handle_t *pHandle, uint8_t State); + + /* It enables/disables the Qusi Synch feature */ + void PWMC_SetQuasiSynchState(PWMC_Handle_t *pHandle, uint8_t State); + + /* It returns the Fast Demag feature status */ + uint8_t PWMC_GetFastDemagState(PWMC_Handle_t *pHandle); + + /* It returns the Quasi Synch feature status */ + uint8_t PWMC_GetQuasiSynchState(PWMC_Handle_t *pHandle); + + /* It converts the motor electrical angle to the corresponding step in the six-step + * sequence */ + uint8_t PWMC_ElAngleToStep(PWMC_Handle_t *pHandle); + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* PWMNCOMMON_SIXSTEP_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pwm_curr_fdbk.c b/src/firmware/motor/mcsdk/pwm_curr_fdbk.c new file mode 100644 index 0000000000..2cbd89415e --- /dev/null +++ b/src/firmware/motor/mcsdk/pwm_curr_fdbk.c @@ -0,0 +1,1161 @@ +/** + ****************************************************************************** + * @file pwm_curr_fdbk.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the following features + * of the PWM & Current Feedback component of the Motor Control SDK: + * + * * current sensing + * * regular ADC conversion execution + * * space vector modulation + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pwm_curr_fdbk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/pwm_curr_fdbk.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup pwm_curr_fdbk PWM & Current Feedback + * + * @brief PWM & Current Feedback components of the Motor Control SDK. + * + * These components fulfill two functions in a Motor Control subsystem: + * + * - The generation of the Space Vector Pulse Width Modulation on the motor's phases + * - The sampling of the actual motor's phases current + * + * Both these features are closely related as the instants when the values of the phase + * currents should be sampled by the ADC channels are basically triggered by the timers + * used to generate the duty cycles for the PWM. + * + * Several implementation of PWM and Current Feedback components are provided by the Motor + * Control SDK to account for the specificities of the application: + * + * - The selected MCU: the number of ADCs available on a given MCU, the presence of + * internal comparators or OpAmps, for instance, lead to different implementation of this + * feature + * - The Current sensing topology also has an impact on the firmware: implementations are + * provided for Insulated Current Sensors, Single Shunt and Three Shunt resistors current + * sensing topologies + * + * The choice of the implementation mostly depend on these two factors and is performed by + * the Motor Control Workbench tool. + * + * All these implementations are built on a base PWM & Current Feedback component that + * they extend and that provides the functions and data that are common to all of them. + * This base component is never used directly as it does not provide a complete + * implementation of the features. Rather, its handle structure (PWMC_Handle) is reused by + * all the PWM & Current Feedback specific implementations and the functions it provides + * form the API of the PWM and Current feedback feature. Calling them results in calling + * functions of the component that actually implement the feature. See PWMC_Handle for + * more details on this mechanism. + * @{ + */ + +/** + * @brief Used to clear variables in CPWMC. + * + * @param pHandle: Handler of the current instance of the PWM component. + */ +void PWMC_Clear(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->IaEst = 0; + pHandle->IbEst = 0; + pHandle->IcEst = 0; + pHandle->LPFIdBuf = 0; + pHandle->LPFIqBuf = 0; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the calibrated @p offsets for each of the phases in the @p pHandle + * handler. In case of single shunt only phase A is relevant. + * + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_SetOffsetCalib(PWMC_Handle_t *pHandle, PolarizationOffsets_t *offsets) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->pFctSetOffsetCalib(pHandle, offsets); + } +} + +/** + * @brief Gets the calibrated @p offsets for each of the phases in the @p pHandle + * handler. In case of single shunt only phase A is relevant. + * + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_GetOffsetCalib(PWMC_Handle_t *pHandle, PolarizationOffsets_t *offsets) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->pFctGetOffsetCalib(pHandle, offsets); + } +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif + +/** + * @brief Converts input voltages @f$ V_{\alpha} @f$ and @f$ V_{\beta} @f$ into PWM duty + * cycles and feed them to the inverter. + * + * This function computes the time during which the transistors of each phase are to be + * switched on in a PWM cycle in order to achieve the reference phase voltage set by @p + * Valfa_beta. The function then programs the resulting duty cycles in the related timer + * channels. It also sets the phase current sampling point for the next PWM cycle + * accordingly. + * + * This function is used in the FOC frequency loop and needs to complete itself before the + * next PWM cycle starts in order for the duty cycles it computes to be taken into + * account. Failing to do so (for instance because the PWM Frequency is too high) results + * in the function returning #MC_DURATION which entails a Motor Control Fault that stops + * the motor. + * + * @param pHandle: Handler of the current instance of the PWM component. + * @param Valfa_beta: Voltage Components expressed in the @f$(\alpha, \beta)@f$ reference + * frame. + * @retval #MC_NO_ERROR if no error occurred or #MC_DURATION if the duty cycles were + * set too late for being taken into account in the next PWM cycle. + */ +__weak uint16_t PWMC_SetPhaseVoltage(PWMC_Handle_t *pHandle, alphabeta_t Valfa_beta) +{ + uint16_t returnValue; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + returnValue = 0U; + } + else + { +#endif + int32_t wX; + int32_t wY; + int32_t wZ; + int32_t wUAlpha; + int32_t wUBeta; + int32_t wTimePhA; + int32_t wTimePhB; + int32_t wTimePhC; + + wUAlpha = Valfa_beta.alpha * (int32_t)pHandle->hT_Sqrt3; + wUBeta = -(Valfa_beta.beta * ((int32_t)pHandle->PWMperiod)) * 2; + + wX = wUBeta; + wY = (wUBeta + wUAlpha) / 2; + wZ = (wUBeta - wUAlpha) / 2; + + /* Sector calculation from wX, wY, wZ */ + if (wY < 0) + { + if (wZ < 0) + { + pHandle->Sector = SECTOR_5; + wTimePhA = + (((int32_t)pHandle->PWMperiod) / 4) + ((wY - wZ) / (int32_t)262144); + wTimePhB = wTimePhA + (wZ / 131072); + wTimePhC = wTimePhA - (wY / 131072); + + if (true == pHandle->SingleShuntTopology) + { + pHandle->lowDuty = 1U; + pHandle->midDuty = 0U; + pHandle->highDuty = 2U; + } + else + { + pHandle->lowDuty = (uint16_t)wTimePhC; + pHandle->midDuty = (uint16_t)wTimePhA; + pHandle->highDuty = (uint16_t)wTimePhB; + } + } + else /* wZ >= 0 */ + if (wX <= 0) + { + pHandle->Sector = SECTOR_4; + wTimePhA = (((int32_t)pHandle->PWMperiod) / 4) + + ((wX - wZ) / (int32_t)262144); + wTimePhB = wTimePhA + (wZ / 131072); + wTimePhC = wTimePhB - (wX / 131072); + + if (true == pHandle->SingleShuntTopology) + { + pHandle->lowDuty = 0U; + pHandle->midDuty = 1U; + pHandle->highDuty = 2U; + } + else + { + pHandle->lowDuty = (uint16_t)wTimePhC; + pHandle->midDuty = (uint16_t)wTimePhB; + pHandle->highDuty = (uint16_t)wTimePhA; + } + } + else /* wX > 0 */ + { + pHandle->Sector = SECTOR_3; + wTimePhA = (((int32_t)pHandle->PWMperiod) / 4) + + ((wY - wX) / (int32_t)262144); + wTimePhC = wTimePhA - (wY / 131072); + wTimePhB = wTimePhC + (wX / 131072); + + if (true == pHandle->SingleShuntTopology) + { + pHandle->lowDuty = 0U; + pHandle->midDuty = 2U; + pHandle->highDuty = 1U; + } + else + { + pHandle->lowDuty = (uint16_t)wTimePhB; + pHandle->midDuty = (uint16_t)wTimePhC; + pHandle->highDuty = (uint16_t)wTimePhA; + } + } + } + else /* wY > 0 */ + { + if (wZ >= 0) + { + pHandle->Sector = SECTOR_2; + wTimePhA = + (((int32_t)pHandle->PWMperiod) / 4) + ((wY - wZ) / (int32_t)262144); + wTimePhB = wTimePhA + (wZ / 131072); + wTimePhC = wTimePhA - (wY / 131072); + + if (true == pHandle->SingleShuntTopology) + { + pHandle->lowDuty = 2U; + pHandle->midDuty = 0U; + pHandle->highDuty = 1U; + } + else + { + pHandle->lowDuty = (uint16_t)wTimePhB; + pHandle->midDuty = (uint16_t)wTimePhA; + pHandle->highDuty = (uint16_t)wTimePhC; + } + } + else /* wZ < 0 */ + if (wX <= 0) + { + pHandle->Sector = SECTOR_6; + wTimePhA = (((int32_t)pHandle->PWMperiod) / 4) + + ((wY - wX) / (int32_t)262144); + wTimePhC = wTimePhA - (wY / 131072); + wTimePhB = wTimePhC + (wX / 131072); + + if (true == pHandle->SingleShuntTopology) + { + pHandle->lowDuty = 1U; + pHandle->midDuty = 2U; + pHandle->highDuty = 0U; + } + else + { + pHandle->lowDuty = (uint16_t)wTimePhA; + pHandle->midDuty = (uint16_t)wTimePhC; + pHandle->highDuty = (uint16_t)wTimePhB; + } + } + else /* wX > 0 */ + { + pHandle->Sector = SECTOR_1; + wTimePhA = (((int32_t)pHandle->PWMperiod) / 4) + + ((wX - wZ) / (int32_t)262144); + wTimePhB = wTimePhA + (wZ / 131072); + wTimePhC = wTimePhB - (wX / 131072); + + if ((pHandle->DPWM_Mode == true) || + (pHandle->SingleShuntTopology == true)) + { + pHandle->lowDuty = 2U; + pHandle->midDuty = 1U; + pHandle->highDuty = 0U; + } + else + { + pHandle->lowDuty = (uint16_t)wTimePhA; + pHandle->midDuty = (uint16_t)wTimePhB; + pHandle->highDuty = (uint16_t)wTimePhC; + } + } + } + + pHandle->CntPhA = (uint16_t)(MAX(wTimePhA, 0)); + pHandle->CntPhB = (uint16_t)(MAX(wTimePhB, 0)); + pHandle->CntPhC = (uint16_t)(MAX(wTimePhC, 0)); + + returnValue = pHandle->pFctSetADCSampPointSectX(pHandle); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif + return (returnValue); +} + +/** + * @brief Switches PWM generation off, inactivating the outputs. + * + * @param pHandle: Handler of the current instance of the PWM component. + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_SwitchOffPWM(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctSwitchOffPwm(pHandle); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Enables PWM generation on the proper Timer peripheral. + * + * @param pHandle: Handler of the current instance of the PWM component. + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_SwitchOnPWM(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctSwitchOnPwm(pHandle); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Calibrates ADC current conversions by reading the offset voltage + * present on ADC pins when no motor current is flowing in. + * + * This function should be called before each motor start-up. + * + * @param pHandle: Handler of the current instance of the PWM component. + * @param action: Can be #CRC_START to initialize the offset calibration or + * #CRC_EXEC to execute the offset calibration. + * @retval true if the current calibration has been completed, **false** if it is + * still ongoing. + */ +__weak bool PWMC_CurrentReadingCalibr(PWMC_Handle_t *pHandle, CRCAction_t action) +{ + bool retVal = false; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (CRC_START == action) + { + PWMC_SwitchOffPWM(pHandle); + pHandle->pFctCurrReadingCalib(pHandle); + retVal = true; + } + else if (CRC_EXEC == action) + { + if (pHandle->OffCalibrWaitTimeCounter > 0u) + { + pHandle->OffCalibrWaitTimeCounter--; + if (0U == pHandle->OffCalibrWaitTimeCounter) + { + pHandle->pFctCurrReadingCalib(pHandle); + retVal = true; + } + } + else + { + retVal = true; + } + } + else + { + /* Nothing to do */ + } +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif + return (retVal); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief Sets a low pass filter. + * + * This function is called for setting low pass filter on Iq and Id, before getting + * transformed in Ia and Ib by the Reverse Park function. + * + * @param in: Value needing to be passed through the filter (Iq and Id). + * @param out_buf: LPF buffer. + * @param t: Low pass filter constant. + * @retval New value after the low pass filter. + */ +static inline int32_t PWMC_LowPassFilter(int32_t in, int32_t *out_buf, int32_t t) +{ + int32_t x; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == out_buf) + { + x = 0; + } + else + { +#endif +#ifndef FULL_MISRA_C_COMPLIANCY_PWM_CURR + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + *out_buf = (*out_buf) + ((in - ((*out_buf) >> 15)) * t); + x = (*out_buf) >> + 15; // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 +#else + *out_buf = (*out_buf) + ((in - ((*out_buf) / 32768)) * t); + x = (*out_buf) / 32768; + +#endif +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif + return (x); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief Converts input currents components Iqd into estimated + * currents Ia, Ib and Ic. + * + * @param pHandle: Handler of the current instance of the PWM component. + * @param Iqd: Structure that will receive Iq and Id currents. + * @param hElAngledpp: Electrical angle. + */ +void PWMC_CalcPhaseCurrentsEst(PWMC_Handle_t *pHandle, qd_t Iqd, int16_t hElAngledpp) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + qd_t idq_ave; + alphabeta_t ialpha_beta; + int32_t temp1, temp2; + + idq_ave.q = (int16_t)PWMC_LowPassFilter(Iqd.q, &(pHandle->LPFIqBuf), + pHandle->LPFIqd_const); + idq_ave.d = (int16_t)PWMC_LowPassFilter(Iqd.d, &(pHandle->LPFIdBuf), + pHandle->LPFIqd_const); + + ialpha_beta = MCM_Rev_Park(idq_ave, hElAngledpp); + + /* Reverse Clarke */ + + /*Ia*/ + pHandle->IaEst = ialpha_beta.alpha; + + temp1 = -ialpha_beta.alpha; +#ifndef FULL_MISRA_C_COMPLIANCY_PWM_CURR + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + temp2 = (int32_t)(ialpha_beta.beta) * ((int32_t)SQRT3FACTOR >> 15); +#else + temp2 = (int32_t)(ialpha_beta.beta) * (int32_t)SQRT3FACTOR / 32768; +#endif + + /* Ib */ + pHandle->IbEst = (int16_t)(temp1 - temp2) / 2; + + /* Ic */ + pHandle->IcEst = (int16_t)(temp1 + temp2) / 2; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Switches power stage Low Sides transistors on. + * + * This function is meant for charging boot capacitors of the driving + * section. It has to be called on each motor start-up when using high + * voltage drivers. + * + * @param pHandle: Handler of the current instance of the PWM component. + * @param ticks: Timer ticks value to be applied. + * Min value: 0 (low sides ON) + * Max value: PWM_PERIOD_CYCLES/2 (low sides OFF) + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_TurnOnLowSides(PWMC_Handle_t *pHandle, uint32_t ticks) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctTurnOnLowSides(pHandle, ticks); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/* + * @brief Manages HW overcurrent protection. + * + * @param pHandle: Handler of the current instance of the PWM component. + */ +__weak void *PWMC_OCP_Handler(PWMC_Handle_t *pHandle) +{ + void *tempPointer; // cstat !MISRAC2012-Rule-8.13 +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + tempPointer = MC_NULL; + } + else + { +#endif + if (false == pHandle->BrakeActionLock) + { + if (ES_GPIO == pHandle->LowSideOutputs) + { + LL_GPIO_ResetOutputPin(pHandle->pwm_en_u_port, pHandle->pwm_en_u_pin); + LL_GPIO_ResetOutputPin(pHandle->pwm_en_v_port, pHandle->pwm_en_v_pin); + LL_GPIO_ResetOutputPin(pHandle->pwm_en_w_port, pHandle->pwm_en_w_pin); + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do */ + } + pHandle->OverCurrentFlag = true; + tempPointer = &(pHandle->Motor); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif + return (tempPointer); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/* + * @brief manages driver protection. + * + * @param pHandle: Handler of the current instance of the PWM component. + */ +__weak void *PWMC_DP_Handler(PWMC_Handle_t *pHandle) +{ + void *tempPointer; // cstat !MISRAC2012-Rule-8.13 +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + tempPointer = MC_NULL; + } + else + { +#endif + if (false == pHandle->BrakeActionLock) + { + if (ES_GPIO == pHandle->LowSideOutputs) + { + LL_GPIO_ResetOutputPin(pHandle->pwm_en_u_port, pHandle->pwm_en_u_pin); + LL_GPIO_ResetOutputPin(pHandle->pwm_en_v_port, pHandle->pwm_en_v_pin); + LL_GPIO_ResetOutputPin(pHandle->pwm_en_w_port, pHandle->pwm_en_w_pin); + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do */ + } + pHandle->driverProtectionFlag = true; + tempPointer = &(pHandle->Motor); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif + return (tempPointer); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/* + * @brief Manages HW overvoltage protection. + * + * @param pHandle: Handler of the current instance of the PWM component. + * TIMx: timer used for PWM generation + */ +__weak void *PWMC_OVP_Handler(PWMC_Handle_t *pHandle, TIM_TypeDef *TIMx) +{ + void *tempPointer; // cstat !MISRAC2012-Rule-8.13 +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + tempPointer = MC_NULL; + } + else + { +#endif + TIMx->BDTR |= LL_TIM_OSSI_ENABLE; + pHandle->OverVoltageFlag = true; + pHandle->BrakeActionLock = true; + tempPointer = &(pHandle->Motor); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif + return (tempPointer); +} + +/* + * @brief Checks if an overcurrent occurred since last call. + * + * @param pHdl: Handler of the current instance of the PWM component. + * @retval uint16_t Returns #MC_OVER_CURR if an overcurrent has been + * detected since last method call, #MC_NO_FAULTS otherwise. + */ +__weak uint16_t PWMC_IsFaultOccurred(PWMC_Handle_t *pHandle) +{ + uint16_t retVal = MC_NO_FAULTS; + + if (true == pHandle->OverVoltageFlag) + { + retVal = MC_OVER_VOLT; + pHandle->OverVoltageFlag = false; + } + else + { + /* Nothing to do */ + } + + if (true == pHandle->OverCurrentFlag) + { + retVal |= MC_OVER_CURR; + pHandle->OverCurrentFlag = false; + } + else + { + /* Nothing to do */ + } + + if (true == pHandle->driverProtectionFlag) + { + retVal |= MC_DP_FAULT; + pHandle->driverProtectionFlag = false; + } + else + { + /* Nothing to do */ + } + + return (retVal); +} + +/** + * @brief Sets the over current threshold through the DAC reference voltage. + * + * @param pHandle: Handler of the current instance of the PWM component. + * @param hDACVref: Value of DAC reference voltage to be applied expressed as a 16bit + *unsigned integer. Min value: 0 (0 V) Max value: 65536 (VDD_DAC) + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_OCPSetReferenceVoltage(PWMC_Handle_t *pHandle, uint16_t hDACVref) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if ((MC_NULL == pHandle) || (MC_NULL == pHandle->pFctOCPSetReferenceVoltage)) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctOCPSetReferenceVoltage(pHandle, hDACVref); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** @brief Enables Discontinuous PWM mode using the @p pHandle PWMC component. + * + */ +__weak void PWMC_DPWM_ModeEnable(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->DPWM_Mode = true; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** @brief Disables Discontinuous PWM mode using the @p pHandle PWMC component. + * + */ +__weak void PWMC_DPWM_ModeDisable(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->DPWM_Mode = false; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** @brief Returns the status of the Discontinuous PWM Mode stored in the @p pHandle PWMC + * component. + * + * @retval true if DPWM Mode is enabled, **false** otherwise. + */ +// cstat !MISRAC2012-Rule-8.13 +__weak bool PWMC_GetDPWM_Mode(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + return ((MC_NULL == pHandle) ? false : pHandle->DPWM_Mode); +#else + return (pHandle->DPWM_Mode); +#endif +} + +/** @brief Enables the RL detection mode by calling the function in @p pHandle PWMC + * component. + * + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_RLDetectionModeEnable(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if ((MC_NULL == pHandle) || (MC_NULL == pHandle->pFctRLDetectionModeEnable)) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctRLDetectionModeEnable(pHandle); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** @brief Disables the RL detection mode by calling the function in @p pHandle PWMC + * component. + * + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_RLDetectionModeDisable(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if ((MC_NULL == pHandle) || (MC_NULL == pHandle->pFctRLDetectionModeDisable)) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctRLDetectionModeDisable(pHandle); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the PWM duty cycle to apply in the RL Detection mode. + * + * @param pHandle: Handler of the current instance of the PWMC component. + * @param hDuty: Duty cycle to apply, written in uint16_t. + * @retval #MC_NO_ERROR if the Duty Cycle could be applied on time for the next PWM + * period. Returns #MC_DURATION otherwise. + */ +__weak uint16_t PWMC_RLDetectionModeSetDuty( + PWMC_Handle_t *pHandle, uint16_t hDuty) // cstat !MISRAC2012-Rule-8.13 +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + uint16_t retVal = MC_DURATION; + + if ((MC_NULL == pHandle) || (MC_NULL == pHandle->pFctRLDetectionModeSetDuty)) + { + /* Nothing to do */ + } + else + { + retVal = pHandle->pFctRLDetectionModeSetDuty(pHandle, hDuty); + } + return (retVal); +#else + return (pHandle->pFctRLDetectionModeSetDuty(pHandle, hDuty)); +#endif +} + +/** @brief Turns on low sides switches and starts ADC triggerin. + * + */ +// cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect +__weak void PWMC_RLTurnOnLowSidesAndStart(PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if ((MC_NULL == pHandle) || (MC_NULL == pHandle->pFctRLTurnOnLowSidesAndStart)) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctRLTurnOnLowSidesAndStart(pHandle); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to get phases current. + * + * @param pCallBack: Pointer on the callback to get the phase current. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterGetPhaseCurrentsCallBack(PWMC_GetPhaseCurr_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctGetPhaseCurrents = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to switch PWM + * generation off. + * + * @param pCallBack: Pointer on the generic callback. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterSwitchOffPwmCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctSwitchOffPwm = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to switch PWM + * generation on. + * + * @param pCallBack: Pointer on the generic callback. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterSwitchonPwmCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctSwitchOnPwm = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to execute a calibration + * of the current sensing system. + * + * @param pCallBack: Pointer on the generic callback. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterReadingCalibrationCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctCurrReadingCalib = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to turn low sides on. + * + * @param pCallBack: Pointer on the callback which turns low sides on. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterTurnOnLowSidesCallBack(PWMC_TurnOnLowSides_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctTurnOnLowSides = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to compute ADC sampling + * point. + * + * @param pCallBack: Pointer on the callback which sets the sampling point depending on + * the sector. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterSampPointSectXCallBack(PWMC_SetSampPointSectX_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctSetADCSampPointSectX = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to set the reference + * voltage for the overcurrent protection. + * + * @param pCallBack: Pointer on the callback which sets the reference voltage. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterOCPSetRefVoltageCallBack(PWMC_SetOcpRefVolt_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctOCPSetReferenceVoltage = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to enable the R/L + * detection mode. + * + * @param pCallBack: Pointer on the generic callback. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterRLDetectionModeEnableCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctRLDetectionModeEnable = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to disable the R/L + * detection mode. + * + * @param pCallBack: Pointer on the generic callback. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterRLDetectionModeDisableCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctRLDetectionModeDisable = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @brief Sets the Callback that the PWMC component shall invoke to set the duty cycle + * for the R/L detection mode. + * + * @param pCallBack: Pointer on the callback which sets the duty cycle. + * @param pHandle: Handler of the current instance of the PWMC component. + */ +__weak void PWMC_RegisterRLDetectionModeSetDutyCallBack( + PWMC_RLDetectSetDuty_Cb_t pCallBack, PWMC_Handle_t *pHandle) +{ +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctRLDetectionModeSetDuty = pCallBack; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pwm_curr_fdbk.h b/src/firmware/motor/mcsdk/pwm_curr_fdbk.h new file mode 100644 index 0000000000..12ad4fed8d --- /dev/null +++ b/src/firmware/motor/mcsdk/pwm_curr_fdbk.h @@ -0,0 +1,480 @@ +/** + ****************************************************************************** + * @file pwm_curr_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * PWM & Current Feedback component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pwm_curr_fdbk + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef PWMNCURRFDBK_H +#define PWMNCURRFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/mc_type.h" + + /* Exported defines ------------------------------------------------------------*/ + +#define SECTOR_1 0U +#define SECTOR_2 1U +#define SECTOR_3 2U +#define SECTOR_4 3U +#define SECTOR_5 4U +#define SECTOR_6 5U +/* @brief Used in calculation of Ia, Ib and Ic + * + * See function PWMC_CalcPhaseCurrentsEst + */ +#define SQRT3FACTOR ((uint16_t)0xDDB4) /* = (16384 * 1.732051 * 2)*/ + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup pwm_curr_fdbk + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** @brief PWM & Current Sensing component handle type */ + typedef struct PWMC_Handle PWMC_Handle_t; + + /** + * @brief Pointer on callback functions used by PWMC components + * + * This type is needed because the actual functions to use can change at run-time. + * + * See the following items: + * - PWMC_Handle::pFctSwitchOffPwm + * - PWMC_Handle::pFctSwitchOnPwm + * - PWMC_Handle::pFctCurrReadingCalib + * - PWMC_Handle::pFctRLDetectionModeEnable + * - PWMC_Handle::pFctRLDetectionModeDisable + * + * + */ + typedef void (*PWMC_Generic_Cb_t)(PWMC_Handle_t *pHandle); + + /** + * @brief Pointer on the function provided by the PMWC component instance to get the + * phase current. + * + * This type is needed because the actual function to use can change at run-time + * (See PWMC_Handle::pFctGetPhaseCurrents). + * + */ + typedef void (*PWMC_GetPhaseCurr_Cb_t)(PWMC_Handle_t *pHandle, ab_t *Iab); + + /** + * @brief Pointer on the function provided by the PMWC component instance to set low + * sides ON. + * + * This type is needed because the actual function to use can change at run-time + * (See PWMC_Handle::pFctTurnOnLowSides). + * + */ + typedef void (*PWMC_TurnOnLowSides_Cb_t)(PWMC_Handle_t *pHandle, + const uint32_t ticks); + + /** + * @brief Pointer on the function provided by the PMWC component instance to set the + * reference voltage for the over current protection. + * + * This type is needed because the actual function to use can change at run-time + * (See PWMC_Handle::pFctOCPSetReferenceVoltage). + * + */ + typedef void (*PWMC_SetOcpRefVolt_Cb_t)(PWMC_Handle_t *pHandle, uint16_t hDACVref); + + /** + * @brief Pointer on the functions provided by the PMWC component instance to set the + * ADC sampling point for each sectors. + * + * This type is needed because the actual function to use can change at run-time. See: + * - PWMC_Handle::pFctSetADCSampPointSect1 + * - PWMC_Handle::pFctSetADCSampPointSect2 + * - PWMC_Handle::pFctSetADCSampPointSect3 + * - PWMC_Handle::pFctSetADCSampPointSect4 + * - PWMC_Handle::pFctSetADCSampPointSect5 + * - PWMC_Handle::pFctSetADCSampPointSect6 + * + */ + typedef uint16_t (*PWMC_SetSampPointSectX_Cb_t)(PWMC_Handle_t *pHandle); + + /** + * @brief Pointer on the function provided by the PMWC component instance to set the + * PWM duty cycle in RL detection mode. + * + * This type is needed because the actual function to use can change at run-time + * (See PWMC_Handle::pFctRLDetectionModeSetDuty). + * + */ + typedef uint16_t (*PWMC_RLDetectSetDuty_Cb_t)(PWMC_Handle_t *pHandle, uint16_t hDuty); + + /** + * @brief Pointer on the function provided by the PMWC component instance to set the + * calibrated offsets in RL detection mode. + * + * This type is needed because the actual function to use can change at run-time + * (See PWMC_Handle::pFctSetOffsetCalib). + * + */ + typedef void (*PWMC_SetOffsetCalib_Cb_t)(PWMC_Handle_t *pHandle, + PolarizationOffsets_t *offsets); + + /** + * @brief Pointer on the function provided by the PMWC component instance to get the + * calibrated offsets in RL detection mode. + * + * This type is needed because the actual function to use can change at run-time + */ + typedef void (*PWMC_GetOffsetCalib_Cb_t)(PWMC_Handle_t *pHandle, + PolarizationOffsets_t *offsets); + + /** + * @brief This structure is used to handle the data of an instance of the PWM & + * Current Feedback component + * + */ + struct PWMC_Handle + { + /** @{ */ + PWMC_GetPhaseCurr_Cb_t + pFctGetPhaseCurrents; /**< Pointer on the function the component instance uses + to retrieve phase currents. */ + PWMC_Generic_Cb_t pFctSwitchOffPwm; /**< Pointer on the function the component + instance uses to switch PWM off. */ + PWMC_Generic_Cb_t pFctSwitchOnPwm; /**< Pointer on the function the component + instance uses to switch PWM on. */ + PWMC_Generic_Cb_t + pFctCurrReadingCalib; /**< Pointer on the fct the component instance uses to + calibrate the current reading ADC(s). */ + PWMC_TurnOnLowSides_Cb_t + pFctTurnOnLowSides; /**< Pointer on the function the component instance uses + to turn low sides on. */ + PWMC_SetSampPointSectX_Cb_t + pFctSetADCSampPointSectX; /**< Pointer on the function the component instance + uses to set the ADC sampling point. */ + PWMC_SetOcpRefVolt_Cb_t + pFctOCPSetReferenceVoltage; /**< Pointer on the fct the component instance + uses to set the over current ref voltage. */ + PWMC_Generic_Cb_t + pFctRLDetectionModeEnable; /**< Pointer on the function the component instance + uses to enable RL detection mode. */ + PWMC_Generic_Cb_t + pFctRLDetectionModeDisable; /**< Pointer on the function the component + instance uses to disable RL detection mode. */ + PWMC_RLDetectSetDuty_Cb_t + pFctRLDetectionModeSetDuty; /**< Pointer on the fct the component instance + uses to set the PWM duty cycle in RL detection + mode. */ + PWMC_Generic_Cb_t pFctRLTurnOnLowSidesAndStart; /**< Pointer on the function the + component instance uses to turn + on low side and start. */ + PWMC_SetOffsetCalib_Cb_t + pFctSetOffsetCalib; /**< Pointer on the fct the component instance uses to set + the calibrated offsets. */ + PWMC_GetOffsetCalib_Cb_t + pFctGetOffsetCalib; /**< Pointer on the fct the component instance uses to get + the calibrated offsets. */ + /** @} */ + int32_t LPFIqBuf; /**< Low Pass Filter buffer used for averaged @f$ I_q @f$ value + computation. */ + int32_t LPFIdBuf; /**< Low Pass Filter Buffer used for averaged @f$ I_d @f$ value + computation. */ + GPIO_TypeDef *pwm_en_u_port; /*!< Channel 1N (low side) GPIO output */ + GPIO_TypeDef *pwm_en_v_port; /*!< Channel 2N (low side) GPIO output*/ + GPIO_TypeDef *pwm_en_w_port; /*!< Channel 3N (low side) GPIO output */ + uint16_t pwm_en_u_pin; /*!< Channel 1N (low side) GPIO output pin. */ + uint16_t pwm_en_v_pin; /*!< Channel 2N (low side) GPIO output pin. */ + uint16_t pwm_en_w_pin; /*!< Channel 3N (low side) GPIO output pin. */ + uint16_t hT_Sqrt3; /**< Constant used by PWM algorithm (@f$\sqrt{3}@f$). */ + uint16_t CntPhA; /**< PWM Duty cycle for phase A. */ + uint16_t CntPhB; /**< PWM Duty cycle for phase B. */ + uint16_t CntPhC; /**< PWM Duty cycle for phase C. */ + uint16_t SWerror; /**< Contains status about SW error. */ + uint16_t lowDuty; + uint16_t midDuty; + uint16_t highDuty; + uint16_t HighDutyStored; /**< Discontinuous PWM Store current Highest Duty for + recovering. */ + uint16_t OffCalibrWaitTimeCounter; /**< Counter to wait fixed time before motor + current measurement offset calibration. */ + int16_t Ia; /**< Last @f$I_{a}@f$ measurement. */ + int16_t Ib; /**< Last @f$I_{b}@f$ measurement. */ + int16_t Ic; /**< Last @f$I_{c}@f$ measurement. */ + int16_t + IaEst; /**< Estimated @f$I_{a}@f$ based on averaged @f$ I_q @f$,@f$ I_d @f$ + values and used when @f$I_{a}@f$ current is not available. */ + int16_t + IbEst; /**< Estimated @f$I_{b}@f$ based on averaged @f$ I_q @f$,@f$ I_d @f$ + values and used when @f$I_{b}@f$ current is not available. */ + int16_t + IcEst; /**< Estimated @f$I_{c}@f$ based on averaged @f$ I_q @f$,@f$ I_d @f$ + values and used when @f$I_{c}@f$ current is not available. */ + int16_t LPFIqd_const; /**< Low pass filter constant (averaging coeficient). */ + uint16_t PWMperiod; /**< PWM period expressed in timer clock cycles unit: + * @f$hPWMPeriod = TimerFreq_{CLK} / F_{PWM}@f$ */ + uint16_t DTCompCnt; /**< Half of Dead time expressed + * in timer clock cycles unit: + * @f$hDTCompCnt = (DT_s \cdot TimerFreq_{CLK})/2@f$ */ + uint16_t Ton; /**< Reserved. */ + uint16_t Toff; /**< Reserved. */ + uint8_t Motor; /**< Motor reference number. */ + uint8_t AlignFlag; /**< Phase current 0 is reliable, 1 is not. */ + uint8_t Sector; /**< Space vector sector number. */ + LowSideOutputsFunction_t LowSideOutputs; /*!< Low side or enabling signals + generation method are defined here. */ + bool TurnOnLowSidesAction; /**< True if TurnOnLowSides action is active, + false otherwise. */ + bool DPWM_Mode; /**< Discontinuous PWM mode activation. */ + bool RLDetectionMode; /**< True if enabled, false if disabled. */ + bool offsetCalibStatus; /**< True if offset calibration completed, false + otherwise. */ + bool OverCurrentFlag; /* This flag is set when an overcurrent occurs.*/ + bool OverVoltageFlag; /* This flag is set when an overvoltage occurs.*/ + bool driverProtectionFlag; /* This flag is set when a driver protection occurs.*/ + bool BrakeActionLock; /* This flag is set to avoid that brake action is + interrupted.*/ + volatile bool useEstCurrent; /**< Estimated current flag. */ + + bool SingleShuntTopology; /*!< This flag is set when Single Shunt topology is used + */ + }; + + /** + * @brief Current reading calibration definition. + */ + typedef enum + { + CRC_START, /**< Initializes the current reading calibration. */ + CRC_EXEC /**< Executes the current reading calibration. */ + } CRCAction_t; + + /* Converts input voltages @f$ V_{\alpha} @f$ and @f$ V_{\beta} @f$ into PWM duty + * cycles and feed them to the inverter. */ + uint16_t PWMC_SetPhaseVoltage(PWMC_Handle_t *pHandle, alphabeta_t Valfa_beta); + + /* Switches PWM generation off, inactivating the outputs. */ + void PWMC_SwitchOffPWM(PWMC_Handle_t *pHandle); + + /* Enables PWM generation on the proper Timer peripheral. */ + void PWMC_SwitchOnPWM(PWMC_Handle_t *pHandle); + + /* Calibrates ADC current conversions by reading the offset voltage + * present on ADC pins when no motor current is flowing in. */ + bool PWMC_CurrentReadingCalibr(PWMC_Handle_t *pHandle, CRCAction_t action); + + /* Switches power stage Low Sides transistors on. */ + void PWMC_TurnOnLowSides(PWMC_Handle_t *pHandle, uint32_t ticks); + + /* Sets the calibrated @p offsets for each of the phases in the @p pHandle handler. In + * case of single shunt only phase A is relevant. */ + void PWMC_SetOffsetCalib(PWMC_Handle_t *pHandle, PolarizationOffsets_t *offsets); + + /* Gets the calibrated @p offsets for each of the phases in the @p pHandle handler. In + * case of single shunt only phase A is relevant. */ + void PWMC_GetOffsetCalib(PWMC_Handle_t *pHandle, PolarizationOffsets_t *offsets); + + /* Manages HW overcurrent protection. */ + void *PWMC_OCP_Handler(PWMC_Handle_t *pHandle); + + /* Manages driver protection. */ + void *PWMC_DP_Handler(PWMC_Handle_t *pHandle); + + /* Manages HW overvoltage protection. */ + void *PWMC_OVP_Handler(PWMC_Handle_t *pHandle, TIM_TypeDef *TIMx); + + /* Checks if a fault (OCP, DP or OVP) occurred since last call. */ + uint16_t PWMC_IsFaultOccurred(PWMC_Handle_t *pHandle); + + /* Sets the over current threshold through the DAC reference voltage. */ + void PWMC_OCPSetReferenceVoltage(PWMC_Handle_t *pHandle, uint16_t hDACVref); + + /* Enables Discontinuous PWM mode using the @p pHandle PWMC component. */ + void PWMC_DPWM_ModeEnable(PWMC_Handle_t *pHandle); + + /* Disables Discontinuous PWM mode using the @p pHandle PWMC component. */ + void PWMC_DPWM_ModeDisable(PWMC_Handle_t *pHandle); + + /* Returns the status of the Discontinuous PWM Mode stored in the @p pHandle PWMC + * component. */ + bool PWMC_GetDPWM_Mode(PWMC_Handle_t *pHandle); + + /* Enables the RL detection mode by calling the function in @p pHandle PWMC component. + */ + void PWMC_RLDetectionModeEnable(PWMC_Handle_t *pHandle); + + /* Disables the RL detection mode by calling the function in @p pHandle PWMC + * component. */ + void PWMC_RLDetectionModeDisable(PWMC_Handle_t *pHandle); + + /* Sets the PWM duty cycle to apply in the RL Detection mode. */ + uint16_t PWMC_RLDetectionModeSetDuty(PWMC_Handle_t *pHandle, uint16_t hDuty); + + /* Turns on low sides switches and starts ADC triggerin. */ + void PWMC_RLTurnOnLowSidesAndStart(PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to get phases current. */ + void PWMC_RegisterGetPhaseCurrentsCallBack(PWMC_GetPhaseCurr_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to switch PWM generation + * off. */ + void PWMC_RegisterSwitchOffPwmCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to switch PWM generation on. + */ + void PWMC_RegisterSwitchonPwmCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to execute a calibration of + * the current sensing system. */ + void PWMC_RegisterReadingCalibrationCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to turn low sides on. */ + void PWMC_RegisterTurnOnLowSidesCallBack(PWMC_TurnOnLowSides_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to compute ADC sampling + * point. */ + void PWMC_RegisterSampPointSectXCallBack(PWMC_SetSampPointSectX_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to set the reference voltage + * for the overcurrent protection. */ + void PWMC_RegisterOCPSetRefVoltageCallBack(PWMC_SetOcpRefVolt_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to enable the R/L detection + * mode. */ + void PWMC_RegisterRLDetectionModeEnableCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to disable the R/L detection + * mode. */ + void PWMC_RegisterRLDetectionModeDisableCallBack(PWMC_Generic_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Sets the Callback that the PWMC component shall invoke to set the duty cycle for + * the R/L detection mode */ + void PWMC_RegisterRLDetectionModeSetDutyCallBack(PWMC_RLDetectSetDuty_Cb_t pCallBack, + PWMC_Handle_t *pHandle); + + /* Used to clear variables in CPWMC. */ + void PWMC_Clear(PWMC_Handle_t *pHandle); + + /* Converts input currents components Iqd into estimated currents Ia, Ib and Ic. */ + void PWMC_CalcPhaseCurrentsEst(PWMC_Handle_t *pHandle, qd_t Iqd, int16_t hElAngledpp); + + /* Converts input voltage components @f$ V_{\alpha} @f$ and @f$ V_{\beta} @f$ into + * duty cycles and feed them to the inverter with overmodulation function. */ + uint16_t PWMC_SetPhaseVoltage_OVM(PWMC_Handle_t *pHandle, alphabeta_t Valfa_beta); + + /** + * @brief Returns the phase current of the motor as read by the ADC (in s16A unit). + * + * Returns the current values of phases A & B. Phase C current + * can be deduced thanks to the formula: + * + * @f[ + * I_{C} = -I_{A} - I_{B} + * @f] + * + * @param pHandle: Handler of the current instance of the PWM component. + * @param Iab: Pointer to the structure that will receive motor current + * of phases A & B in ElectricalValue format. + */ + // cstat !MISRAC2012-Rule-8.13 !RED-func-no-effect + static inline void PWMC_GetPhaseCurrents(PWMC_Handle_t *pHandle, ab_t *Iab) + { +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->pFctGetPhaseCurrents(pHandle, Iab); +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif + } + + /** + * @brief Retrieves the satus of TurnOnLowSides action. + * + * @param pHandle: Handler of the current instance of the PWMC component. + * @retval bool State of TurnOnLowSides action: + * **true** if TurnOnLowSides action is active, **false** otherwise. + */ + static inline bool PWMC_GetTurnOnLowSidesAction(const PWMC_Handle_t *pHandle) + { +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + return ((MC_NULL == pHandle) ? false : pHandle->TurnOnLowSidesAction); +#else + return (pHandle->TurnOnLowSidesAction); +#endif + } + + /** + * @brief Sets the aligned motor flag. + * + * @param pHandle: Handler of the current instance of the PWMC component. + * @param flag: Value to be applied as an 8 bit unsigned integer. + * 1: motor is in aligned stage. + * 2: motor is not in aligned stage. + */ + static inline void PWMC_SetAlignFlag(PWMC_Handle_t *pHandle, uint8_t flag) + { +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->AlignFlag = flag; +#ifdef NULL_PTR_CHECK_PWR_CUR_FDB + } +#endif + } + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* PWMNCURRFDBK_H */ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pwm_curr_fdbk_ovm.c b/src/firmware/motor/mcsdk/pwm_curr_fdbk_ovm.c new file mode 100644 index 0000000000..50c4860d35 --- /dev/null +++ b/src/firmware/motor/mcsdk/pwm_curr_fdbk_ovm.c @@ -0,0 +1,528 @@ +/** + ****************************************************************************** + * @file pwm_curr_fdbk_ovm.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the following features + * of the PWM & Current Feedback component of the Motor Control SDK: + * + * * current sensing + * * regular ADC conversion execution + * * space vector modulation + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pwm_curr_fdbk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/pwm_curr_fdbk.h" + + + +/* Private defines ------------------------------------------------------------*/ + +/* @brief The float number 1.0 equal to 32768 ; represents the vector from center to an + * angle of the hexagon*/ +#define OVM_ONE_POINT_ZERO ((int32_t)32768) +#define OVM_GAIN_ARRAY_SIZE ((int32_t)192) +#define OVM_GAMMA_ARRAY_SIZE ((int32_t)100) +#define OVM_GAMMA_ARRAY_OFFSET ((int32_t)92) +#define OVM_VREF_MODE1_START ((int32_t)29717) +#define OVM_VREF_MODE2_START ((int32_t)31186) +#define OVM_VREF_MODE2_END ((int32_t)32768) +#define OVM_VREF_INDEX_STEP ((int32_t)16) +#define OVM_1_DIV_SQRT3 ((int32_t)18919) +#define OVM_1_DIV_PI ((int32_t)10430) +#define OVM_PI_DIV_6 ((int32_t)17157) +#define OVM_3_DIV_PI ((int32_t)31291) +#define OVM_SQRT3 ((int32_t)56754) + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup pwm_curr_fdbk + * + * @{ + */ + +/* Private variables ----------------------------------------------------------*/ + +/** + * @brief Vector modules T1 and T2. Specified in @ref overmodulation.md + */ +typedef struct +{ + int32_t T1; + int32_t T2; +} Vector_Time_t; + +/** + * @brief Overmodulation modes. Specified in @ref overmodulation.md + */ +typedef enum +{ + OVM_LINEAR = 0, /**< Linear mode. */ + OVM_1 = 1, /**< Overmodulation mode 1. */ + OVM_2 = 2, /**< Overmodulation mode 2. */ + OVM_ERROR = 3 /**< Error output. */ +} OVM_Mode_t; + +/** + * @} + */ + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +static Vector_Time_t PWMC_RecalcT1T2_OVM(Vector_Time_t time, OVM_Mode_t mode, + int16_t gamma); + + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/* + * @brief Recalculates vectors T1 and T2 stored in @p time structure, + * depending on the overmodulation @p mode and @p gamma gain. + * + * @retval New values of T1 & T2. + */ +static Vector_Time_t PWMC_RecalcT1T2_OVM(Vector_Time_t time, OVM_Mode_t mode, + int16_t gamma) +{ + int32_t sum_t1_t2, offset, gain, t1_temp; + Vector_Time_t time_prime; + + time_prime.T1 = 0; + time_prime.T2 = 0; + + if ((OVM_LINEAR == mode) || (OVM_1 == mode)) + { + sum_t1_t2 = time.T1 + time.T2; + + if (sum_t1_t2 > OVM_ONE_POINT_ZERO) + { + time_prime.T1 = ((time.T1 * OVM_ONE_POINT_ZERO) / sum_t1_t2); + time_prime.T2 = OVM_ONE_POINT_ZERO - time_prime.T1; + } + else + { + time_prime.T1 = time.T1; + time_prime.T2 = time.T2; + } + } + else if (OVM_2 == mode) + { + if (time.T1 > OVM_ONE_POINT_ZERO) + { + time_prime.T1 = OVM_ONE_POINT_ZERO; + time_prime.T2 = 0; + } + else if (time.T2 > OVM_ONE_POINT_ZERO) + { + time_prime.T1 = 0; + time_prime.T2 = OVM_ONE_POINT_ZERO; + } + else + { + offset = (OVM_3_DIV_PI * gamma) / OVM_ONE_POINT_ZERO; + gain = (OVM_PI_DIV_6 * OVM_ONE_POINT_ZERO) / (OVM_PI_DIV_6 - gamma); + + sum_t1_t2 = time.T1 + time.T2; + sum_t1_t2 = ((0 == sum_t1_t2) ? 1 : sum_t1_t2); + t1_temp = (time.T1 * OVM_ONE_POINT_ZERO) / sum_t1_t2; + t1_temp = t1_temp - offset; + if (t1_temp < 0) + { + t1_temp = 0; + } + else + { + /* Nothing to do */ + } + if (gain > OVM_ONE_POINT_ZERO) + { + gain = gain / OVM_ONE_POINT_ZERO; + time_prime.T1 = t1_temp * gain; + } + else + { + time_prime.T1 = (t1_temp * gain) / OVM_ONE_POINT_ZERO; + } + if (time_prime.T1 > OVM_ONE_POINT_ZERO) + { + time_prime.T1 = OVM_ONE_POINT_ZERO; + } + else + { + /* Nothing to do */ + } + time_prime.T2 = OVM_ONE_POINT_ZERO - time_prime.T1; + } + } + else /* error mode output 0 to protect */ + { + time_prime.T1 = 0; + time_prime.T2 = 0; + } + return (time_prime); +} + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup pwm_curr_fdbk + * + * @{ + */ + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Converts input voltage components @f$ V_{\alpha} @f$ and @f$ V_{\beta} @f$ into + * duty cycles and feeds them to the inverter with overmodulation function. + * + * @param pHandle: Handler of the current instance of the PWM component. + * @param Valfa_beta: Voltage Components expressed in the @f$(\alpha, \beta)@f$ reference + * frame. + * @retval #MC_NO_ERROR if no error occurred or #MC_DURATION if the duty cycles were + * set too late for being taken into account in the next PWM cycle. + */ +uint16_t PWMC_SetPhaseVoltage_OVM(PWMC_Handle_t *pHandle, alphabeta_t Valfa_beta) +{ + /* Private variables ----------------------------------------------------------*/ + /* overmodulation gain array */ + static const uint16_t aOVMGain[OVM_GAIN_ARRAY_SIZE] = { + 31291, 31291, 31293, 31295, 31298, 31300, 31302, 31306, 31309, 31314, 31319, + 31322, 31328, 31334, 31338, 31344, 31350, 31357, 31364, 31371, 31379, 31386, + 31394, 31402, 31410, 31419, 31427, 31439, 31448, 31457, 31470, 31479, 31492, + 31502, 31515, 31526, 31539, 31554, 31568, 31579, 31594, 31609, 31624, 31639, + 31655, 31675, 31691, 31707, 31728, 31745, 31766, 31783, 31805, 31827, 31845, + 31868, 31891, 31914, 31942, 31966, 31990, 32019, 32044, 32074, 32104, 32134, + 32165, 32202, 32233, 32271, 32303, 32341, 32386, 32425, 32470, 32516, 32562, + 32609, 32662, 32716, 32777, 32838, 32907, 32982, 33059, 33144, 33236, 33343, + 33466, 33612, 33797, 34106, 34463, 34507, 34551, 34596, 34640, 34684, 34729, + 34779, 34824, 34869, 34920, 34971, 35017, 35068, 35120, 35178, 35230, 35282, + 35340, 35392, 35451, 35509, 35568, 35627, 35686, 35752, 35811, 35877, 35943, + 36009, 36075, 36148, 36214, 36287, 36360, 36434, 36507, 36581, 36661, 36742, + 36822, 36903, 36990, 37078, 37159, 37253, 37342, 37436, 37531, 37627, 37729, + 37831, 37933, 38042, 38152, 38261, 38378, 38495, 38612, 38736, 38860, 38991, + 39122, 39261, 39399, 39545, 39691, 39844, 40004, 40165, 40332, 40507, 40682, + 40871, 41061, 41264, 41469, 41680, 41906, 42139, 42387, 42649, 42911, 43188, + 43488, 43801, 44137, 44487, 44866, 45275, 45713, 46195, 46715, 47300, 47958, + 48720, 49629, 50759, 52346, 56660, + }; + + /* overmodulation gamma array */ + static const int16_t aOVMGamma[OVM_GAMMA_ARRAY_SIZE] = { + 52, 154, 255, 354, 453, 551, 648, 757, 852, 947, + 1052, 1157, 1249, 1352, 1454, 1566, 1666, 1765, 1875, 1972, + 2079, 2186, 2291, 2395, 2499, 2612, 2713, 2824, 2934, 3042, + 3150, 3266, 3372, 3486, 3599, 3711, 3821, 3931, 4049, 4166, + 4281, 4395, 4517, 4637, 4748, 4875, 4992, 5115, 5238, 5359, + 5487, 5614, 5739, 5870, 6000, 6129, 6263, 6396, 6528, 6665, + 6800, 6941, 7080, 7224, 7367, 7514, 7659, 7809, 7963, 8115, + 8272, 8432, 8590, 8757, 8922, 9096, 9268, 9442, 9624, 9809, + 10001, 10200, 10395, 10597, 10810, 11028, 11255, 11487, 11731, 11987, + 12254, 12539, 12835, 13158, 13507, 13895, 14335, 14853, 15530, 17125, + }; + + uint16_t retvalue; +#ifdef NULL_PTR_PWM_CUR_FDB_OVM + if (NULL == pHandle) + { + retvalue = 0U; + } + else + { +#endif + int16_t index; + int32_t wX, wY, wZ, wUAlpha, wUBeta; + int32_t vref, gain, neg_beta_cmd_div_sqrt3, duty_a, duty_b, duty_c; + int32_t gama = 0; + + OVM_Mode_t ovm_mode_flag; + Vector_Time_t vector_time; + + /*transfer vref to vcmd*/ + vref = (int32_t)MCM_Modulus(Valfa_beta.alpha, Valfa_beta.beta); + + if (vref < OVM_VREF_MODE1_START) /*linear range*/ + { + wUAlpha = Valfa_beta.alpha; + wUBeta = Valfa_beta.beta; + ovm_mode_flag = OVM_LINEAR; + } + else if (vref < OVM_VREF_MODE2_START) /*OVM mode 1 range*/ + { + index = (int16_t)((vref - OVM_VREF_MODE1_START) / OVM_VREF_INDEX_STEP); + gain = (int32_t)aOVMGain[index]; + wUAlpha = (Valfa_beta.alpha * gain) / OVM_ONE_POINT_ZERO; + wUBeta = (Valfa_beta.beta * gain) / OVM_ONE_POINT_ZERO; + ovm_mode_flag = OVM_1; + } + else if (vref < OVM_VREF_MODE2_END) /*OVM mode 2 range*/ + { + index = (int16_t)((vref - OVM_VREF_MODE1_START) / OVM_VREF_INDEX_STEP); + gain = (int32_t)aOVMGain[index]; + wUAlpha = (Valfa_beta.alpha * gain) / OVM_ONE_POINT_ZERO; + wUBeta = (Valfa_beta.beta * gain) / OVM_ONE_POINT_ZERO; + if (index > OVM_GAMMA_ARRAY_OFFSET) + { + gama = aOVMGamma[index - OVM_GAMMA_ARRAY_OFFSET]; + } + else + { + gama = aOVMGamma[0]; + } + ovm_mode_flag = OVM_2; + } + else /*out of OVM mode 2 range only a protection to prevent the code to a + undefined branch*/ + { + wUAlpha = 0; + wUBeta = 0; + ovm_mode_flag = OVM_ERROR; + } + + /*Vcmd to X, Y, Z*/ + neg_beta_cmd_div_sqrt3 = ((-wUBeta) * OVM_1_DIV_SQRT3) / OVM_ONE_POINT_ZERO; + wX = neg_beta_cmd_div_sqrt3 * 2; /* x=-(2/sqrt(3))*beta */ + wY = wUAlpha + neg_beta_cmd_div_sqrt3; /* x=alpha-(1/sqrt(3))*beta */ + wZ = -wUAlpha + neg_beta_cmd_div_sqrt3; + ; /* x=-alpha-(1/sqrt(3))*beta */ + + /* Sector calculation from wX, wY, wZ */ + if (wY < 0) + { + if (wZ < 0) + { + pHandle->Sector = SECTOR_5; + vector_time.T1 = -wY; + vector_time.T2 = -wZ; + vector_time = + PWMC_RecalcT1T2_OVM(vector_time, ovm_mode_flag, (int16_t)gama); + duty_a = 16384 + ((-vector_time.T1 + vector_time.T2) / 2); +#ifndef FULL_MISRA_C_COMPLIANCY_PW_CURR_FDB_OVM + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) >> 16; + duty_b = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) >> 16; + duty_c = 16384 + ((vector_time.T1 + vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) >> 16; +#else + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) / 65536; + duty_b = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) / 65536; + duty_c = 16384 + ((vector_time.T1 + vector_time.T2) / 2); + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) / 65536; +#endif + pHandle->lowDuty = (uint16_t)duty_c; + pHandle->midDuty = (uint16_t)duty_a; + pHandle->highDuty = (uint16_t)duty_b; + } + else /* wZ >= 0 */ + if (wX <= 0) + { + pHandle->Sector = SECTOR_4; + vector_time.T1 = wZ; + vector_time.T2 = -wX; + vector_time = + PWMC_RecalcT1T2_OVM(vector_time, ovm_mode_flag, (int16_t)gama); + duty_a = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); +#ifndef FULL_MISRA_C_COMPLIANCY_PW_CURR_FDB_OVM + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) >> 16; + duty_b = 16384 + ((vector_time.T1 - vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) >> 16; + duty_c = 16384 + ((vector_time.T1 + vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) >> 16; +#else + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) / 65536; + duty_b = 16384 + ((vector_time.T1 - vector_time.T2) / 2); + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) / 65536; + duty_c = 16384 + ((vector_time.T1 + vector_time.T2) / 2); + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) / 65536; +#endif + pHandle->lowDuty = (uint16_t)duty_c; + pHandle->midDuty = (uint16_t)duty_b; + pHandle->highDuty = (uint16_t)duty_a; + } + else /* wX > 0 */ + { + pHandle->Sector = SECTOR_3; + vector_time.T1 = wX; + vector_time.T2 = -wY; + vector_time = + PWMC_RecalcT1T2_OVM(vector_time, ovm_mode_flag, (int16_t)gama); + duty_a = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); +#ifndef FULL_MISRA_C_COMPLIANCY_PW_CURR_FDB_OVM + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) >> 16; + duty_b = 16384 + ((vector_time.T1 + vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) >> 16; + duty_c = 16384 + ((-vector_time.T1 + vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) >> 16; +#else + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) / 65536; + duty_b = 16384 + ((vector_time.T1 + vector_time.T2) / 2); + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) / 65536; + duty_c = 16384 + ((-vector_time.T1 + vector_time.T2) / 2); + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) / 65536; +#endif + pHandle->lowDuty = (uint16_t)duty_b; + pHandle->midDuty = (uint16_t)duty_c; + pHandle->highDuty = (uint16_t)duty_a; + } + } + else /* wY > 0 */ + { + if (wZ >= 0) + { + pHandle->Sector = SECTOR_2; + vector_time.T1 = wY; + vector_time.T2 = wZ; + vector_time = + PWMC_RecalcT1T2_OVM(vector_time, ovm_mode_flag, (int16_t)gama); + duty_a = 16384 + ((vector_time.T1 - vector_time.T2) / 2); +#ifndef FULL_MISRA_C_COMPLIANCY_PW_CURR_FDB_OVM + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) >> 16; + duty_b = 16384 + ((vector_time.T1 + vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) >> 16; + duty_c = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) >> 16; +#else + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) / 65536; + duty_b = 16384 + ((vector_time.T1 + vector_time.T2) / 2); + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) / 65536; + duty_c = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) / 65536; +#endif + pHandle->lowDuty = (uint16_t)duty_b; + pHandle->midDuty = (uint16_t)duty_a; + pHandle->highDuty = (uint16_t)duty_c; + } + else /* wZ < 0 */ + if (wX <= 0) + { + pHandle->Sector = SECTOR_6; + vector_time.T1 = -wX; + vector_time.T2 = wY; + vector_time = + PWMC_RecalcT1T2_OVM(vector_time, ovm_mode_flag, (int16_t)gama); + duty_a = 16384 + ((vector_time.T1 + vector_time.T2) / 2); +#ifndef FULL_MISRA_C_COMPLIANCY_PW_CURR_FDB_OVM + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) >> 16; + duty_b = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) >> 16; + duty_c = 16384 + ((vector_time.T1 - vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) >> 16; +#else + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) / 65536; + duty_b = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) / 65536; + duty_c = 16384 + ((vector_time.T1 - vector_time.T2) / 2); + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) / 65536; +#endif + pHandle->lowDuty = (uint16_t)duty_a; + pHandle->midDuty = (uint16_t)duty_c; + pHandle->highDuty = (uint16_t)duty_b; + } + else /* wX > 0 */ + { + pHandle->Sector = SECTOR_1; + vector_time.T1 = -wZ; + vector_time.T2 = wX; + vector_time = + PWMC_RecalcT1T2_OVM(vector_time, ovm_mode_flag, (int16_t)gama); + duty_a = 16384 + ((vector_time.T1 + vector_time.T2) / 2); +#ifndef FULL_MISRA_C_COMPLIANCY_PW_CURR_FDB_OVM + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) >> 16; + duty_b = 16384 + ((-vector_time.T1 + vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) >> 16; + duty_c = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) >> 16; +#else + duty_a = (((int32_t)pHandle->PWMperiod) * duty_a) / 65536; + duty_b = 16384 + ((-vector_time.T1 + vector_time.T2) / 2); + duty_b = (((int32_t)pHandle->PWMperiod) * duty_b) / 65536; + duty_c = 16384 + ((-vector_time.T1 - vector_time.T2) / 2); + duty_c = (((int32_t)pHandle->PWMperiod) * duty_c) / 65536; +#endif + pHandle->lowDuty = (uint16_t)duty_a; + pHandle->midDuty = (uint16_t)duty_b; + pHandle->highDuty = (uint16_t)duty_c; + } + } + + pHandle->CntPhA = (uint16_t)duty_a; + pHandle->CntPhB = (uint16_t)duty_b; + pHandle->CntPhC = (uint16_t)duty_c; + retvalue = pHandle->pFctSetADCSampPointSectX(pHandle); +#ifdef NULL_PTR_PWM_CUR_FDB_OVM + } +#endif + return (retvalue); +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/pwmc_3pwm.h b/src/firmware/motor/mcsdk/pwmc_3pwm.h new file mode 100644 index 0000000000..bb3d61bc6f --- /dev/null +++ b/src/firmware/motor/mcsdk/pwmc_3pwm.h @@ -0,0 +1,173 @@ +/** + ****************************************************************************** + * @file pwmc_3pwm.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * pwmc_3pwm component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup pwmc_3pwm + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __PWMC_3PWM_H +#define __PWMC_3PWM_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "pwm_common_sixstep.h" + + /** + * @addtogroup MCSDK + * @{ + */ + + /** + * @addtogroup pwm_curr_fdbk_6s + * @{ + */ + + /** + * @addtogroup pwmc_3pwm + * @{ + */ + + /* Exported constants --------------------------------------------------------*/ + + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief ThreePwm parameters definition + */ + typedef struct + { + TIM_TypeDef* TIMx; /*!< It contains the pointer to the timer + used for PWM generation. */ + uint8_t RepetitionCounter; /*!< It expresses the number of PWM + periods to be elapsed before compare + registers are updated again. In + particular: + RepetitionCounter= (2* #PWM periods)-1*/ + uint32_t OCPolarity; /*!< timer channel output polarity.*/ + GPIO_TypeDef* pwm_en_u_port; /*!< phase u enable driver signal GPIO port */ + uint16_t pwm_en_u_pin; /*!< phase u enable driver signal pin */ + GPIO_TypeDef* pwm_en_v_port; /*!< phase v enable driver signal GPIO port */ + uint16_t pwm_en_v_pin; /*!< phase v enable driver signal pin */ + GPIO_TypeDef* pwm_en_w_port; /*!< phase w enable driver signal GPIO port */ + uint16_t pwm_en_w_pin; /*!< phase w enable driver signal pin */ + } ThreePwm_Params_t; + + /** + * @brief Handle structure of the PWMC_ThreePwm Component + */ + typedef struct + { + PWMC_Handle_t _Super; /*!< */ + bool OverCurrentFlag; /*!< This flag is set when an overcurrent occurs.*/ + bool OverVoltageFlag; /*!< This flag is set when an overvoltage occurs.*/ + bool BrakeActionLock; /*!< This flag is set to avoid that brake action is + * interrupted.*/ + bool + FastDemag; /*!< This flag is set when the fast-demagmatization is activated.*/ + uint32_t NegOCPolarity; /*!< Channel output opposite polarity.*/ + uint32_t NegOCNPolarity; /*!< Complementary channel output opposite polarity. */ + uint16_t DemagCounter; + ThreePwm_Params_t const* pParams_str; + } PWMC_ThreePwm_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /** + * It initializes TIMx and NVIC + */ + void ThreePwm_Init(PWMC_ThreePwm_Handle_t* pHandle); + + /** + * It updates the stored duty cycle variable. + */ + void PWMC_SetPhaseVoltage(PWMC_Handle_t* pHandle, uint16_t DutyCycle); + + /** + * It writes the duty cycle into shadow timer registers. + */ + void ThreePwm_LoadNextStep(PWMC_ThreePwm_Handle_t* pHandle, int16_t Direction); + + /** + * It uploads the duty cycle into timer registers. + */ + bool ThreePwm_ApplyNextStep(PWMC_ThreePwm_Handle_t* pHandle); + + /** + * It resets the polarity of the timer PWM channel outputs to default + */ + void ThreePwm_ResetOCPolarity(PWMC_ThreePwm_Handle_t* pHandle); + + /** + * It turns on low sides switches. This function is intended to be + * used for charging boot capacitors of driving section. It has to be + * called each motor start-up when using high voltage drivers + */ + void ThreePwm_TurnOnLowSides(PWMC_Handle_t* pHdl, uint32_t ticks); + + /** + * This function enables the PWM outputs + */ + void ThreePwm_SwitchOnPWM(PWMC_Handle_t* pHdl); + + /** + * It disables PWM generation on the proper Timer peripheral acting on + * MOE bit and reset the TIM status + */ + void ThreePwm_SwitchOffPWM(PWMC_Handle_t* pHdl); + + /** + * It sets the capcture compare of the timer channel used for ADC triggering + */ + void ThreePwm_SetADCTriggerChannel(PWMC_Handle_t* pHdl, uint16_t SamplingPoint); + + /** + * It is used to check if an overcurrent occurred since last call. + */ + uint16_t ThreePwm_IsOverCurrentOccurred(PWMC_Handle_t* pHdl); + + /** + * It contains the Break event interrupt + */ + void* ThreePwm_BRK_IRQHandler(PWMC_ThreePwm_Handle_t* pHandle); + + /** + * It is used to return the fast demag flag. + */ + uint8_t ThreePwm_FastDemagFlag(PWMC_Handle_t* pHdl); + +/** + * @} + */ + +/** + * @} + */ + +/** @} */ +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /*__PWMC_3PWM_H*/ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/r1_dd_pwm_curr_fdbk.h b/src/firmware/motor/mcsdk/r1_dd_pwm_curr_fdbk.h new file mode 100644 index 0000000000..ac254db3ae --- /dev/null +++ b/src/firmware/motor/mcsdk/r1_dd_pwm_curr_fdbk.h @@ -0,0 +1,129 @@ +/** + ****************************************************************************** + * @file r1_dd_pwm_curr_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains common definitions for Single Shunt, Dual Drives + * PWM and Current Feedback components. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup PWMnCurrFdbk_R1_DD + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __R1_DD_PWM_CURR_FDBK_H +#define __R1_DD_PWM_CURR_FDBK_H + +#define GPIO_NoRemap_TIM1 ((uint32_t)(0)) + +#define SAME_FREQ 0u + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup pwm_curr_fdbk + * @{ + */ + + +/** @defgroup PWMnCurrFdbk_R1_DD Single Shunt Dual Drive Parameters + * + * @brief Common definitions for Single Shunt, Dual Drives PWM and Current Feedback + * components + * + * @{ + */ + +/** + * @brief R1 DD parameters definition + */ +typedef struct +{ + TIM_TypeDef *TIMx; /*!< Timer used for PWM generation. It should be + TIM1 or TIM8*/ + TIM_TypeDef *TIMx_2; /*!< Auxiliary timer used for single shunt */ + ADC_TypeDef *ADCx_Inj; /*!< ADC Peripheral used for phase current sampling */ + ADC_TypeDef *ADCx_Reg; /*!< ADC Peripheral used for regular conversion */ + GPIO_TypeDef *pwm_en_u_port; + GPIO_TypeDef *pwm_en_v_port; + GPIO_TypeDef *pwm_en_w_port; + uint32_t pwm_en_u_pin; + uint32_t pwm_en_v_pin; + uint32_t pwm_en_w_pin; + uint16_t Tafter; /*!< It is the sum of dead time plus rise time + express in number of TIM clocks.*/ + uint16_t Tbefore; /*!< It is the value of sampling time + expressed in numbers of TIM clocks.*/ + uint16_t TMin; /*!< It is the sum of dead time plus rise time + plus sampling time express in numbers of + TIM clocks.*/ + uint16_t HTMin; /*!< It is the half of TMin value.*/ + uint16_t TSample; /*!< It is the sampling time express in + numbers of TIM clocks.*/ + uint16_t MaxTrTs; /*!< It is the maximum between twice of rise + time express in number of TIM clocks and + twice of sampling time express in numbers + of TIM clocks.*/ + uint16_t DeadTime; /*!< Dead time in number of TIM clock + cycles. If CHxN are enabled, it must + contain the dead time to be generated + by the microcontroller, otherwise it + expresses the maximum dead time + generated by driving network*/ + uint8_t FreqRatio; /*!< It is used in case of dual MC to + synchronize times. It must be equal + to the ratio between the two PWM + frequencies (higher/lower). + Supported values are 1, 2 or 3 */ + uint8_t IsHigherFreqTim; /*!< When bFreqRatio is greather than 1 + this param is used to indicate if this + instance is the one with the highest + frequency. Allowed value are: HIGHER_FREQ + or LOWER_FREQ */ + uint8_t InstanceNbr; /*!< Instance number with reference to PWMC + base class. It is necessary to properly + synchronize TIM8 with TIM1 at peripheral + initializations */ + uint8_t IChannel; /*!< ADC channel used for conversion of + current. It must be equal to + ADC_CHANNEL_x x= 0, ..., 15*/ + uint8_t RepetitionCounter; /*!< It expresses the number of PWM + periods to be elapsed before compare + registers are updated again. In + particular: + RepetitionCounter= (2* PWM periods) -1*/ + bool IsFirstR1DDInstance; /*!< Specifies whether this object is the first + R1DD instance or not.*/ + LowSideOutputsFunction_t LowSideOutputs; /*!< Low side or enabling signals + generation method are defined + here.*/ + FunctionalState EmergencyStop; /*!< It enable/disable the management of + an emergency input instantaneously + stopping PWM generation. It must be + either equal to ENABLE or DISABLE */ +} R1_DDParams_t; +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /*__R1_DD_PWM_CURR_FDBK_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/r_divider_bus_voltage_sensor.c b/src/firmware/motor/mcsdk/r_divider_bus_voltage_sensor.c new file mode 100644 index 0000000000..f14c430581 --- /dev/null +++ b/src/firmware/motor/mcsdk/r_divider_bus_voltage_sensor.c @@ -0,0 +1,362 @@ +/** + ****************************************************************************** + * @file r_divider_bus_voltage_sensor.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Resistor Divider Bus Voltage Sensor component of the Motor + * Control SDK: + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup RDividerBusVoltageSensor + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/r_divider_bus_voltage_sensor.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/regular_conversion_manager.h" + + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup BusVoltageSensor + * @{ + */ + +/** @defgroup RDividerBusVoltageSensor Resistor Divider Bus Voltage Sensor + * @brief Resistor Divider Bus Voltage Sensor implementation + * + * @{ + */ + +/** + * @brief It initializes bus voltage conversion (ADC, ADC channel, conversion time. + It must be called only after PWM_Init. + * @param pHandle related RDivider_Handle_t + */ +__weak void RVBS_Init(RDivider_Handle_t *pHandle) +{ +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + /* Need to be register with RegularConvManager */ + pHandle->convHandle = RCM_RegisterRegConv(&pHandle->VbusRegConv); + /* Check */ + RVBS_Clear(pHandle); +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + } +#endif +} + + +/** + * @brief It clears bus voltage FW variable containing average bus voltage + * value + * @param pHandle related RDivider_Handle_t + */ +__weak void RVBS_Clear(RDivider_Handle_t *pHandle) +{ +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + uint16_t aux; + uint16_t index; + + aux = (pHandle->OverVoltageThreshold + pHandle->UnderVoltageThreshold) / 2U; + for (index = 0U; index < pHandle->LowPassFilterBW; index++) + { + pHandle->aBuffer[index] = aux; + } + pHandle->_Super.LatestConv = aux; + pHandle->_Super.AvBusVoltage_d = aux; + pHandle->index = 0U; +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + } +#endif +} + +/** + * @brief It performs the Vbus mesurement over N ADC conversions in u16Volt format + * @param pHandle related RDivider_Handle_t + * @retval uint16_t Averaged value in u16Volt format + */ +static uint16_t RVBS_ConvertVbusFiltrered(RDivider_Handle_t *pHandle) +{ + uint32_t tot = 0U; + uint16_t hAux; + uint16_t max = 0U; + uint16_t min = 0U; + uint16_t tempValue; + uint8_t vindex; + + /* LowPassFilterBW number conversions are done */ + for (vindex = 0U; vindex < pHandle->LowPassFilterBW; vindex++) + { + hAux = RCM_ExecRegularConv(pHandle->convHandle); + while (0xFFFFU == hAux) + { + hAux = RCM_ExecRegularConv(pHandle->convHandle); + } + + if (0U == vindex) + { + min = hAux; + max = hAux; + } + else + { + if (hAux < min) + { + min = hAux; + } + else + { + /* Nothing to do */ + } + if (hAux > max) + { + max = hAux; + } + else + { + /* Nothing to do */ + } + } + + tot += hAux; + } + + tot -= max; + tot -= min; + /* Averaged value done over the LowPassFilterBW number excluding lowest and highest + * value */ + tempValue = (uint16_t)(tot / (uint16_t)(pHandle->LowPassFilterBW - 2U)); + return (tempValue); +} + +/** + * @brief It actually performes the Vbus ADC conversion and updates the averaged + * value for the STM32F3 family in u16Volt format + * @param pHandle related RDivider_Handle_t + * @retval uint16_t Fault code error + */ +__weak uint16_t RVBS_CalcAvVbusFilt(RDivider_Handle_t *pHandle) +{ + uint16_t tempValue; +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + if (MC_NULL == pHandle) + { + tempValue = 0U; + } + else + { +#endif + uint32_t wtemp; + uint16_t hAux; + uint8_t i; + + hAux = RVBS_ConvertVbusFiltrered(pHandle); + + if (0xFFFFU == hAux) + { + /* Nothing to do */ + } + else + { + /* Store latest value on buffer */ + pHandle->aBuffer[pHandle->index] = hAux; + wtemp = 0u; + for (i = 0U; i < pHandle->LowPassFilterBW; i++) + { + wtemp += pHandle->aBuffer[i]; + } + wtemp /= pHandle->LowPassFilterBW; + /* Averaging done over the buffer stored values */ + pHandle->_Super.AvBusVoltage_d = (uint16_t)wtemp; + pHandle->_Super.LatestConv = hAux; + + if (pHandle->index < (pHandle->LowPassFilterBW - 1U)) + { + pHandle->index++; + } + else + { + pHandle->index = 0U; + } + } + + pHandle->_Super.FaultState = RVBS_CheckFaultState(pHandle); + tempValue = pHandle->_Super.FaultState; +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + } +#endif + return (tempValue); +} + +/** + * @brief It actually performes the Vbus ADC conversion and updates averaged + * value for all STM32 families except STM32F3 in u16Volt format + * @param pHandle related RDivider_Handle_t + * @retval uint16_t Fault code error + */ +__weak uint16_t RVBS_CalcAvVbus(RDivider_Handle_t *pHandle) +{ + uint16_t tempValue; +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + if (MC_NULL == pHandle) + { + tempValue = 0U; + } + else + { +#endif + uint32_t wtemp; + uint16_t hAux; + uint8_t i; + + hAux = RCM_ExecRegularConv(pHandle->convHandle); + + if (0xFFFFU == hAux) + { + /* Nothing to do */ + } + else + { + /* Store latest value on buffer */ + pHandle->aBuffer[pHandle->index] = hAux; + wtemp = 0u; + for (i = 0U; i < (uint8_t)pHandle->LowPassFilterBW; i++) + { + wtemp += pHandle->aBuffer[i]; + } + wtemp /= pHandle->LowPassFilterBW; + /* Averaging done over the buffer stored values */ + pHandle->_Super.AvBusVoltage_d = (uint16_t)wtemp; + pHandle->_Super.LatestConv = hAux; + + if ((uint16_t)pHandle->index < (pHandle->LowPassFilterBW - 1U)) + { + pHandle->index++; + } + else + { + pHandle->index = 0U; + } + } + + pHandle->_Super.FaultState = RVBS_CheckFaultState(pHandle); + tempValue = pHandle->_Super.FaultState; +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + } +#endif + return (tempValue); +} + +/** + * @brief It returns MC_OVER_VOLT, MC_UNDER_VOLT or MC_NO_ERROR depending on + * bus voltage and protection threshold values + * @param pHandle related RDivider_Handle_t + * @retval uint16_t Fault code error + */ +__weak uint16_t RVBS_CheckFaultState(RDivider_Handle_t *pHandle) +{ + uint16_t fault; +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + if (MC_NULL == pHandle) + { + fault = MC_SW_ERROR; + } + else + { +#endif + /* If both thresholds are equal, single threshold feature is used */ + if (pHandle->OverVoltageThreshold == pHandle->OverVoltageThresholdLow) + { + if (pHandle->_Super.AvBusVoltage_d > pHandle->OverVoltageThreshold) + { + fault = MC_OVER_VOLT; + } + else if (pHandle->_Super.AvBusVoltage_d < pHandle->UnderVoltageThreshold) + { + fault = MC_UNDER_VOLT; + } + else + { + fault = MC_NO_ERROR; + } + } + else + { + /* If both thresholds are different, hysteresis feature is used (Brake mode) + */ + if (pHandle->_Super.AvBusVoltage_d < pHandle->UnderVoltageThreshold) + { + fault = MC_UNDER_VOLT; + } + else if (false == pHandle->OverVoltageHysteresisUpDir) + { + if (pHandle->_Super.AvBusVoltage_d < pHandle->OverVoltageThresholdLow) + { + pHandle->OverVoltageHysteresisUpDir = true; + fault = MC_NO_ERROR; + } + else + { + fault = MC_OVER_VOLT; + } + } + else + { + if (pHandle->_Super.AvBusVoltage_d > pHandle->OverVoltageThreshold) + { + pHandle->OverVoltageHysteresisUpDir = false; + fault = MC_OVER_VOLT; + } + else + { + fault = MC_NO_ERROR; + } + } + } +#ifdef NULL_PTR_RDIV_BUS_VLT_SNS + } +#endif + return (fault); +} + + +/** + * @} + */ + +/** + * @} + */ + +/** @} */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/r_divider_bus_voltage_sensor.h b/src/firmware/motor/mcsdk/r_divider_bus_voltage_sensor.h new file mode 100644 index 0000000000..6d6b5e8344 --- /dev/null +++ b/src/firmware/motor/mcsdk/r_divider_bus_voltage_sensor.h @@ -0,0 +1,113 @@ +/** + ****************************************************************************** + * @file r_divider_bus_voltage_sensor.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Resistor Divider Bus Voltage Sensor component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup RDividerBusVoltageSensor + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef RDIVIDER_BUSVOLTAGESENSOR_H +#define RDIVIDER_BUSVOLTAGESENSOR_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/bus_voltage_sensor.h" +#include "firmware/motor/regular_conversion_manager.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup BusVoltageSensor + * @{ + */ + + /** @addtogroup RDividerBusVoltageSensor + * @{ + */ + + + /** + * @brief Rdivider class parameters definition + */ + typedef struct + { + BusVoltageSensor_Handle_t _Super; /*!< Bus voltage sensor component handle. */ + + RegConv_t VbusRegConv; /*!< It contains all the parameters required to execute + a regular conversion for Vbus monitoring*/ + uint16_t LowPassFilterBW; /*!< Use this number to configure the Vbus + first order software filter bandwidth. + hLowPassFilterBW = VBS_CalcBusReading + call rate [Hz]/ FilterBandwidth[Hz] */ + uint16_t OverVoltageThreshold; /*!< It represents the over voltage protection + intervention threshold. To be expressed + in digital value through formula: + hOverVoltageThreshold (digital value) = + Over Voltage Threshold (V) * 65536 + / hConversionFactor */ + uint16_t + OverVoltageThresholdLow; /*!< It represents the over voltage protection + intervention threshold low level for hysteresis + feature when "switch on brake resistor" is used. + To be expressed in digital value through formula: + hOverVoltageThresholdLow (digital value) = + Over Voltage Threshold Low(V) * 65536 + / hConversionFactor */ + bool OverVoltageHysteresisUpDir; /*!< "Switch on brake resistor" hysteresis + direction. */ + uint16_t UnderVoltageThreshold; /*!< It represents the under voltage protection + intervention threshold. To be expressed + in digital value through formula: + hUnderVoltageThreshold (digital value)= + Under Voltage Threshold (V) * 65536 + / hConversionFactor */ + uint16_t *aBuffer; /*!< Buffer used to compute average value.*/ + uint8_t elem; /*!< Number of stored elements in the average buffer.*/ + uint8_t index; /*!< Index of last stored element in the average buffer.*/ + uint8_t convHandle; /*!< handle to the regular conversion */ + + } RDivider_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + void RVBS_Init(RDivider_Handle_t *pHandle); + void RVBS_Clear(RDivider_Handle_t *pHandle); + uint16_t RVBS_CalcAvVbusFilt(RDivider_Handle_t *pHandle); + uint16_t RVBS_CalcAvVbus(RDivider_Handle_t *pHandle); + uint16_t RVBS_CheckFaultState(RDivider_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + + /** @} */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* RDIVIDER_BUSVOLTAGESENSOR_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/ramp_ext_mngr.c b/src/firmware/motor/mcsdk/ramp_ext_mngr.c new file mode 100644 index 0000000000..a7811471c3 --- /dev/null +++ b/src/firmware/motor/mcsdk/ramp_ext_mngr.c @@ -0,0 +1,336 @@ +/** + ****************************************************************************** + * @file ramp_ext_mngr.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Ramp Extended Manager component of the Motor Control SDK: + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/ramp_ext_mngr.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup RampExtMngr Ramp Manager + * @brief Ramp Extended Manager component of the Motor Control SDK + * + * @todo Document the Ramp Extended Manager "module". + * + * @{ + */ +/* Private function prototypes -----------------------------------------------*/ +uint32_t getScalingFactor(int32_t Target); + +/** + * @brief It reset the state variable to zero. + * @param pHandle related Handle of struct RampMngr_Handle_t + * @retval none. + */ +void REMNG_Init(RampExtMngr_Handle_t *pHandle) +{ +#ifdef NULL_RMP_EXT_MNG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->Ext = 0; + pHandle->TargetFinal = 0; + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; + pHandle->ScalingFactor = 1U; +#ifdef NULL_RMP_EXT_MNG + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Exec the ramp calculations and returns the current value of the + state variable. + It must be called at fixed interval defined in the hExecFreq. + * @param pHandle related Handle of struct RampMngr_Handle_t + * @retval int32_t value of the state variable + */ +__weak int32_t REMNG_Calc(RampExtMngr_Handle_t *pHandle) +{ + int32_t ret_val; +#ifdef NULL_RMP_EXT_MNG + if (MC_NULL == pHandle) + { + ret_val = 0; + } + else + { +#endif + int32_t current_ref; + + current_ref = pHandle->Ext; + + /* Update the variable and terminates the ramp if needed. */ + if (pHandle->RampRemainingStep > 1U) + { + /* Increment/decrement the reference value. */ + current_ref += pHandle->IncDecAmount; + + /* Decrement the number of remaining steps */ + pHandle->RampRemainingStep--; + } + else if (1U == pHandle->RampRemainingStep) + { + /* Set the backup value of TargetFinal. */ + current_ref = pHandle->TargetFinal * ((int32_t)pHandle->ScalingFactor); + pHandle->RampRemainingStep = 0U; + } + else + { + /* Do nothing. */ + } + + pHandle->Ext = current_ref; + ret_val = pHandle->Ext / ((int32_t)pHandle->ScalingFactor); +#ifdef NULL_RMP_EXT_MNG + } +#endif + return (ret_val); +} + +/** + * @brief Setup the ramp to be executed + * @param pHandle related Handle of struct RampMngr_Handle_t + * @param hTargetFinal (signed 32bit) final value of state variable at the end + * of the ramp. + * @param hDurationms (unsigned 32bit) the duration of the ramp expressed in + * milliseconds. It is possible to set 0 to perform an instantaneous + * change in the value. + * @retval bool It returns true is command is valid, false otherwise + */ +__weak bool REMNG_ExecRamp(RampExtMngr_Handle_t *pHandle, int32_t TargetFinal, + uint32_t Durationms) +{ + bool retVal = true; +#ifdef NULL_RMP_EXT_MNG + if (MC_NULL == pHandle) + { + retVal = false; + } + else + { +#endif + uint32_t aux; + int32_t aux1; + int32_t current_ref; + + + /* Get current state */ + current_ref = pHandle->Ext / ((int32_t)pHandle->ScalingFactor); + + if (0U == Durationms) + { + pHandle->ScalingFactor = getScalingFactor(TargetFinal); + pHandle->Ext = TargetFinal * ((int32_t)pHandle->ScalingFactor); + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; + } + else + { + uint32_t wScalingFactor = getScalingFactor(TargetFinal - current_ref); + uint32_t wScalingFactor2 = getScalingFactor(current_ref); + uint32_t wScalingFactor3 = getScalingFactor(TargetFinal); + uint32_t wScalingFactorMin; + + if (wScalingFactor < wScalingFactor2) + { + if (wScalingFactor < wScalingFactor3) + { + wScalingFactorMin = wScalingFactor; + } + else + { + wScalingFactorMin = wScalingFactor3; + } + } + else + { + if (wScalingFactor2 < wScalingFactor3) + { + wScalingFactorMin = wScalingFactor2; + } + else + { + wScalingFactorMin = wScalingFactor3; + } + } + + pHandle->ScalingFactor = wScalingFactorMin; + pHandle->Ext = current_ref * ((int32_t)pHandle->ScalingFactor); + + /* Store the TargetFinal to be applied in the last step */ + pHandle->TargetFinal = TargetFinal; + + /* Compute the (wRampRemainingStep) number of steps remaining to complete + the ramp. */ + aux = Durationms * + ((uint32_t) + pHandle->FrequencyHz); /* Check for overflow and use prescaler */ + aux /= 1000U; + pHandle->RampRemainingStep = aux; + pHandle->RampRemainingStep++; + + /* Compute the increment/decrement amount (wIncDecAmount) to be applied to + the reference value at each CalcTorqueReference. */ + aux1 = (TargetFinal - current_ref) * ((int32_t)pHandle->ScalingFactor); + aux1 /= ((int32_t)pHandle->RampRemainingStep); + pHandle->IncDecAmount = aux1; + } +#ifdef NULL_RMP_EXT_MNG + } +#endif + return retVal; +} + +/** + * @brief Returns the current value of the state variable. + * @param pHandle related Handle of struct RampMngr_Handle_t + * @retval int32_t value of the state variable + */ +__weak int32_t REMNG_GetValue(const RampExtMngr_Handle_t *pHandle) +{ +#ifdef NULL_RMP_EXT_MNG + return ((MC_NULL == pHandle) ? 0 + : (pHandle->Ext / ((int32_t)pHandle->ScalingFactor))); +#else + return (pHandle->Ext / ((int32_t)pHandle->ScalingFactor)); +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Check if the settled ramp has been completed. + * @param pHandle related Handle of struct RampMngr_Handle_t. + * @retval bool It returns true if the ramp is completed, false otherwise. + */ +__weak bool REMNG_RampCompleted(const RampExtMngr_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_RMP_EXT_MNG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (0U == pHandle->RampRemainingStep) + { + retVal = true; + } + else + { + /* nothing to do */ + } +#ifdef NULL_RMP_EXT_MNG + } +#endif + return (retVal); +} + +/** + * @brief Stop the execution of the ramp keeping the last reached value. + * @param pHandle related Handle of struct RampMngr_Handle_t. + * @retval none + */ +__weak void REMNG_StopRamp(RampExtMngr_Handle_t *pHandle) +{ +#ifdef NULL_RMP_EXT_MNG + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; +#ifdef NULL_RMP_EXT_MNG + } +#endif +} + +/** + * @brief Calculating the scaling factor to maximixe the resolution. It + * perform the 2^int(31-log2(Target)) with an iterative approach. + * It allows to keep Target * Scaling factor inside int32_t type. + * @param Target Input data. + * @retval uint32_t It returns the optimized scaling factor. + */ +__weak uint32_t getScalingFactor(int32_t Target) +{ + uint32_t TargetAbs; + int32_t aux; + uint8_t i; + + if (Target < 0) + { + aux = -Target; + TargetAbs = (uint32_t)aux; + } + else + { + TargetAbs = (uint32_t)Target; + } + for (i = 1U; i < 32U; i++) + { + uint32_t limit = (((uint32_t)1) << (31U - i)); + if (TargetAbs >= limit) + { + break; + } + else + { + /* Nothing to do */ + } + } + return (((uint32_t)1) << (i - 1U)); +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/ramp_ext_mngr.h b/src/firmware/motor/mcsdk/ramp_ext_mngr.h new file mode 100644 index 0000000000..848f39a34b --- /dev/null +++ b/src/firmware/motor/mcsdk/ramp_ext_mngr.h @@ -0,0 +1,83 @@ +/** + ****************************************************************************** + * @file ramp_ext_mngr.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Ramp Extended Manager component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup RampExtMngr + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef RAMPEXTMNGR_H +#define RAMPEXTMNGR_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/mc_type.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup RampExtMngr + * @{ + */ + + /** + * @brief RampExtMngr Handle Definition. + */ + typedef struct + { + uint32_t FrequencyHz; /*!< Execution frequency expressed in Hz */ + int32_t TargetFinal; /*!< Backup of hTargetFinal to be applied in the + last step.*/ + int32_t Ext; /*!< Current state variable multiplied by 32768.*/ + uint32_t RampRemainingStep; /*!< Number of steps remaining to complete the + ramp.*/ + int32_t IncDecAmount; /*!< Increment/decrement amount to be applied to + the reference value at each + CalcTorqueReference.*/ + uint32_t ScalingFactor; /*!< Scaling factor between output value and + its internal representation.*/ + } RampExtMngr_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + void REMNG_Init(RampExtMngr_Handle_t *pHandle); + int32_t REMNG_Calc(RampExtMngr_Handle_t *pHandle); + bool REMNG_ExecRamp(RampExtMngr_Handle_t *pHandle, int32_t TargetFinal, + uint32_t Durationms); + int32_t REMNG_GetValue(const RampExtMngr_Handle_t *pHandle); + bool REMNG_RampCompleted(const RampExtMngr_Handle_t *pHandle); + void REMNG_StopRamp(RampExtMngr_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* RAMPEXTMNGR_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/revup_ctrl.c b/src/firmware/motor/mcsdk/revup_ctrl.c new file mode 100644 index 0000000000..984ef51cfc --- /dev/null +++ b/src/firmware/motor/mcsdk/revup_ctrl.c @@ -0,0 +1,932 @@ +/** + ****************************************************************************** + * @file revup_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Rev-Up Control component of the Motor Control SDK: + * + * * Main Rev-Up procedure to execute programmed phases + * * On the Fly (OTF) + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + * @ingroup RevUpCtrlFOC + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/revup_ctrl.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + + +/** @defgroup RevUpCtrl Rev-Up Control + * @brief Rev-Up Control component of the Motor Control SDK + * + * Used to start up the motor with a set of pre-programmed phases. + * + * The number of phases of the Rev-Up procedure range is from 0 to 5. + * The Rev-Up controller must be called at speed loop frequency. + * + * @{ + */ + + + +/** @defgroup RevUpCtrlFOC FOC Rev-Up Control component + * @brief Rev-Up control component used to start motor driven with + * the Field Oriented Control technique + * + * @{ + */ + +/* Private defines -----------------------------------------------------------*/ + +/** + * @brief Timeout used to reset integral term of PLL. + * It is expressed in ms. + * + */ +#define RUC_OTF_PLL_RESET_TIMEOUT 100u + + +/* Private functions ----------------------------------------------------------*/ + + +/* Returns the mechanical speed of a selected phase */ +static int16_t RUC_GetPhaseFinalMecSpeed01Hz(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase) +{ + int16_t hRetVal = 0; +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + hRetVal = pHandle->ParamsData[bPhase].hFinalMecSpeedUnit; +#ifdef NULL_PTR_REV_UP_CTL + } +#endif + return (hRetVal); +} + + +/** + * @brief Initialize and configure the FOC RevUpCtrl Component + * @param pHandle: Pointer on Handle structure of FOC RevUp controller. + * @param pSTC: Pointer on speed and torque controller structure. + * @param pVSS: Pointer on virtual speed sensor structure. + * @param pSNSL: Pointer on sensorless state observer structure. + * @param pPWM: Pointer on the PWM structure. + */ +__weak void RUC_Init(RevUpCtrl_Handle_t *pHandle, SpeednTorqCtrl_Handle_t *pSTC, + VirtualSpeedSensor_Handle_t *pVSS, STO_Handle_t *pSNSL, + PWMC_Handle_t *pPWM) +{ +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + RevUpCtrl_PhaseParams_t *pRUCPhaseParams = &pHandle->ParamsData[0]; + uint8_t bPhase = 0U; + + pHandle->pSTC = pSTC; + pHandle->pVSS = pVSS; + pHandle->pSNSL = pSNSL; + pHandle->pPWM = pPWM; + pHandle->OTFSCLowside = false; + pHandle->EnteredZone1 = false; + + while ((pRUCPhaseParams != MC_NULL) && (bPhase < RUC_MAX_PHASE_NUMBER)) + { + /* Dump HF data for now HF data are forced to 16 bits*/ + pRUCPhaseParams = (RevUpCtrl_PhaseParams_t *) + pRUCPhaseParams->pNext; // cstat !MISRAC2012-Rule-11.5 + bPhase++; + } + + if (0U == bPhase) + { + /* nothing to do error */ + } + else + { + pHandle->ParamsData[bPhase - 1u].pNext = MC_NULL; + + pHandle->bPhaseNbr = bPhase; + + pHandle->bResetPLLTh = + (uint8_t)((RUC_OTF_PLL_RESET_TIMEOUT * pHandle->hRUCFrequencyHz) / 1000U); + } +#ifdef NULL_PTR_REV_UP_CTL + } +#endif +} + +/** + * @brief Initialize internal FOC RevUp controller state. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param hMotorDirection: Rotor rotation direction. + * This parameter must be -1 or +1. + */ +__weak void RUC_Clear(RevUpCtrl_Handle_t *pHandle, int16_t hMotorDirection) +{ +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + VirtualSpeedSensor_Handle_t *pVSS = pHandle->pVSS; + SpeednTorqCtrl_Handle_t *pSTC = pHandle->pSTC; + RevUpCtrl_PhaseParams_t *pPhaseParams = pHandle->ParamsData; + + pHandle->hDirection = hMotorDirection; + pHandle->EnteredZone1 = false; + + /*Initializes the rev up stages counter.*/ + pHandle->bStageCnt = 0U; + pHandle->bOTFRelCounter = 0U; + pHandle->OTFSCLowside = false; + + /* Calls the clear method of VSS.*/ + VSS_Clear(pVSS); + + /* Sets the STC in torque mode.*/ + STC_SetControlMode(pSTC, MCM_TORQUE_MODE); + + /* Sets the mechanical starting angle of VSS.*/ + VSS_SetMecAngle(pVSS, pHandle->hStartingMecAngle * hMotorDirection); + + /* Sets to zero the starting torque of STC */ + (void)STC_ExecRamp(pSTC, 0, 0U); + + /* Gives the first command to STC and VSS.*/ + (void)STC_ExecRamp(pSTC, pPhaseParams->hFinalTorque * hMotorDirection, + (uint32_t)(pPhaseParams->hDurationms)); + + VSS_SetMecAcceleration(pVSS, pPhaseParams->hFinalMecSpeedUnit * hMotorDirection, + pPhaseParams->hDurationms); + + /* Compute hPhaseRemainingTicks.*/ + pHandle->hPhaseRemainingTicks = + (uint16_t)((((uint32_t)pPhaseParams->hDurationms) * + ((uint32_t)pHandle->hRUCFrequencyHz)) / + 1000U); + + pHandle->hPhaseRemainingTicks++; + + /*Set the next phases parameter pointer.*/ + pHandle->pCurrentPhaseParams = + (RevUpCtrl_PhaseParams_t *) + pPhaseParams->pNext; // cstat !MISRAC2012-Rule-11.5 + + /*Timeout counter for PLL reset during OTF.*/ + pHandle->bResetPLLCnt = 0U; +#ifdef NULL_PTR_REV_UP_CTL + } +#endif +} + +/** + * @brief FOC Main Rev-Up controller procedure executing overall programmed phases and + * on-the-fly startup handling. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Boolean set to false when entire Rev-Up phases have been completed. + */ +__weak bool RUC_OTF_Exec(RevUpCtrl_Handle_t *pHandle) +{ + bool retVal = true; +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + bool IsSpeedReliable; + bool condition = false; + + if (pHandle->hPhaseRemainingTicks > 0u) + { + /* Decrease the hPhaseRemainingTicks.*/ + pHandle->hPhaseRemainingTicks--; + + /* OTF start-up */ + if (0U == pHandle->bStageCnt) + { + if (false == pHandle->EnteredZone1) + { + if (pHandle->pSNSL->pFctStoOtfResetPLL != MC_NULL) + { + pHandle->bResetPLLCnt++; + if (pHandle->bResetPLLCnt > pHandle->bResetPLLTh) + { + pHandle->pSNSL->pFctStoOtfResetPLL(pHandle->pSNSL); + pHandle->bOTFRelCounter = 0U; + pHandle->bResetPLLCnt = 0U; + } + } + + IsSpeedReliable = + pHandle->pSNSL->pFctSTO_SpeedReliabilityCheck(pHandle->pSNSL); + + if (IsSpeedReliable) + { + if (pHandle->bOTFRelCounter < 127U) + { + pHandle->bOTFRelCounter++; + } + } + else + { + pHandle->bOTFRelCounter = 0U; + } + + if (pHandle->pSNSL->pFctStoOtfResetPLL != MC_NULL) + { + if (pHandle->bOTFRelCounter == (pHandle->bResetPLLTh >> 1)) + { + condition = true; + } + } + else + { + if (127U == pHandle->bOTFRelCounter) + { + condition = true; + } + } + + if (true == condition) + { + bool bCollinearSpeed = false; + int16_t hObsSpeedUnit = + SPD_GetAvrgMecSpeedUnit(pHandle->pSNSL->_Super); + int16_t hObsSpeedUnitAbsValue = + ((hObsSpeedUnit < 0) + ? (-hObsSpeedUnit) + : (hObsSpeedUnit)); /* hObsSpeedUnit absolute value */ + + if (pHandle->hDirection > 0) + { + if (hObsSpeedUnit > 0) + { + bCollinearSpeed = + true; /* actual and reference speed are collinear*/ + } + } + else + { + if (hObsSpeedUnit < 0) + { + bCollinearSpeed = + true; /* actual and reference speed are collinear*/ + } + } + + if (false == bCollinearSpeed) + { + /*reverse speed management*/ + pHandle->bOTFRelCounter = 0U; + } + else /*speeds are collinear*/ + { + if ((uint16_t)(hObsSpeedUnitAbsValue) > + pHandle->hMinStartUpValidSpeed) + { + /* startup end, go to run */ + pHandle->pSNSL->pFctForceConvergency1(pHandle->pSNSL); + pHandle->EnteredZone1 = true; + } + else if ((uint16_t)(hObsSpeedUnitAbsValue) > + pHandle->hMinStartUpFlySpeed) + { + /* synch with startup*/ + /* nearest phase search*/ + int16_t hOldFinalMecSpeedUnit = 0; + int16_t hOldFinalTorque = 0; + int32_t wDeltaSpeedRevUp; + int32_t wDeltaTorqueRevUp; + bool bError = false; + VSS_SetCopyObserver(pHandle->pVSS); + pHandle->pSNSL->pFctForceConvergency2(pHandle->pSNSL); + + if (MC_NULL == pHandle->pCurrentPhaseParams) + { + bError = true; + pHandle->hPhaseRemainingTicks = 0U; + } + else + { + while ( + pHandle->pCurrentPhaseParams->hFinalMecSpeedUnit < + hObsSpeedUnitAbsValue) + { + if (pHandle->pCurrentPhaseParams->pNext == + MC_NULL) + { + /* sets for Revup fail error*/ + bError = true; + pHandle->hPhaseRemainingTicks = 0U; + break; + } + else + { + /* skips this phase*/ + hOldFinalMecSpeedUnit = + pHandle->pCurrentPhaseParams + ->hFinalMecSpeedUnit; + hOldFinalTorque = pHandle->pCurrentPhaseParams + ->hFinalTorque; + // cstat !MISRAC2012-Rule-11.5 + pHandle->pCurrentPhaseParams = + (RevUpCtrl_PhaseParams_t *) + pHandle->pCurrentPhaseParams->pNext; + pHandle->bStageCnt++; + } + } + } + if (false == bError) + { + /* calculation of the transition phase from OTF to + * standard revup */ + int16_t hTorqueReference; + + wDeltaSpeedRevUp = + ((int32_t)(pHandle->pCurrentPhaseParams + ->hFinalMecSpeedUnit)) - + ((int32_t)(hOldFinalMecSpeedUnit)); + wDeltaTorqueRevUp = + ((int32_t)(pHandle->pCurrentPhaseParams + ->hFinalTorque)) - + ((int32_t)(hOldFinalTorque)); + + if ((int32_t)0 == wDeltaSpeedRevUp) + { + /* Nothing to do */ + } + else + { + hTorqueReference = + (int16_t)((((int32_t)hObsSpeedUnit) * + wDeltaTorqueRevUp) / + wDeltaSpeedRevUp) + + hOldFinalTorque; + + (void)STC_ExecRamp( + pHandle->pSTC, + pHandle->hDirection * hTorqueReference, 0U); + } + + pHandle->hPhaseRemainingTicks = 1U; + + pHandle->pCurrentPhaseParams = + &pHandle->OTFPhaseParams; + + pHandle->bStageCnt = 6U; + } /* no MC_NULL error */ + } /* speed > MinStartupFly */ + else + { + } + } /* speeds are collinear */ + } /* speed is reliable */ + } /*EnteredZone1 1 is false */ + else + { + pHandle->pSNSL->pFctForceConvergency1(pHandle->pSNSL); + } + } /*stage 0*/ + } /* hPhaseRemainingTicks > 0 */ + + if (0U == pHandle->hPhaseRemainingTicks) + { + if (pHandle->pCurrentPhaseParams != MC_NULL) + { + if (0U == pHandle->bStageCnt) + { + /*end of OTF*/ + PWMC_SwitchOffPWM(pHandle->pPWM); + pHandle->OTFSCLowside = true; + PWMC_TurnOnLowSides(pHandle->pPWM, 0u); + pHandle->bOTFRelCounter = 0U; + } + else if (1U == pHandle->bStageCnt) + { + PWMC_SwitchOnPWM(pHandle->pPWM); + pHandle->OTFSCLowside = false; + } + else + { + } + + /* If it becomes zero the current phase has been completed.*/ + /* Gives the next command to STC and VSS.*/ + (void)STC_ExecRamp( + pHandle->pSTC, + pHandle->pCurrentPhaseParams->hFinalTorque * pHandle->hDirection, + (uint32_t)(pHandle->pCurrentPhaseParams->hDurationms)); + + VSS_SetMecAcceleration(pHandle->pVSS, + pHandle->pCurrentPhaseParams->hFinalMecSpeedUnit * + pHandle->hDirection, + pHandle->pCurrentPhaseParams->hDurationms); + + /* Compute hPhaseRemainingTicks.*/ + pHandle->hPhaseRemainingTicks = + (uint16_t)((((uint32_t)pHandle->pCurrentPhaseParams->hDurationms) * + (uint32_t)pHandle->hRUCFrequencyHz) / + 1000U); + pHandle->hPhaseRemainingTicks++; + + /*Set the next phases parameter pointer.*/ + pHandle->pCurrentPhaseParams = + pHandle->pCurrentPhaseParams->pNext; // cstat !MISRAC2012-Rule-11.5 + + /*Increases the rev up stages counter.*/ + pHandle->bStageCnt++; + } + else + { + if (pHandle->bStageCnt == + (pHandle->bPhaseNbr - (uint8_t)1)) /* End of user programmed revup */ + { + retVal = false; + } + else if (7U == pHandle->bStageCnt) /* End of first OTF runs */ + { + pHandle->bStageCnt = 0U; /* Breaking state */ + pHandle->hPhaseRemainingTicks = 0U; + } + else + { + /* Nothing to do */ + } + } + } +#ifdef NULL_PTR_REV_UP_CTL + } +#endif + return (retVal); +} + +/** + * @brief FOC Main Rev-Up controller procedure executing overall programmed phases. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Boolean set to false when entire Rev-Up phases have been completed. + */ +__weak bool RUC_Exec(RevUpCtrl_Handle_t *pHandle) +{ + bool retVal = true; +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + retVal = false; + } + else + { +#endif + if (pHandle->hPhaseRemainingTicks > 0U) + { + /* Decrease the hPhaseRemainingTicks.*/ + pHandle->hPhaseRemainingTicks--; + + } /* hPhaseRemainingTicks > 0 */ + + if (0U == pHandle->hPhaseRemainingTicks) + { + if (pHandle->pCurrentPhaseParams != MC_NULL) + { + /* If it becomes zero the current phase has been completed.*/ + /* Gives the next command to STC and VSS.*/ + (void)STC_ExecRamp( + pHandle->pSTC, + pHandle->pCurrentPhaseParams->hFinalTorque * pHandle->hDirection, + (uint32_t)(pHandle->pCurrentPhaseParams->hDurationms)); + + VSS_SetMecAcceleration(pHandle->pVSS, + pHandle->pCurrentPhaseParams->hFinalMecSpeedUnit * + pHandle->hDirection, + pHandle->pCurrentPhaseParams->hDurationms); + + /* Compute hPhaseRemainingTicks.*/ + pHandle->hPhaseRemainingTicks = + (uint16_t)((((uint32_t)pHandle->pCurrentPhaseParams->hDurationms) * + ((uint32_t)pHandle->hRUCFrequencyHz)) / + 1000U); + pHandle->hPhaseRemainingTicks++; + + /*Set the next phases parameter pointer.*/ + pHandle->pCurrentPhaseParams = + pHandle->pCurrentPhaseParams->pNext; // cstat !MISRAC2012-Rule-11.5 + + /*Increases the rev up stages counter.*/ + pHandle->bStageCnt++; + } + else + { + retVal = false; + } + } +#ifdef NULL_PTR_REV_UP_CTL + } +#endif + return (retVal); +} + +/** + * @brief It checks if this stage is used for align motor. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Returns 1 if the alignment is correct otherwise it returns 0 + */ +uint8_t RUC_IsAlignStageNow(RevUpCtrl_Handle_t *pHandle) +{ + uint8_t align_flag = 0; +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int16_t speed; + speed = RUC_GetPhaseFinalMecSpeed01Hz(pHandle, pHandle->bStageCnt); + if (0 == speed) + { + align_flag = 1; + } +#ifdef NULL_PTR_REV_UP_CTL + } +#endif + return (align_flag); +} + +/** + * @brief Provide current state of Rev-Up controller procedure. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Boolean set to true when entire Rev-Up phases have been completed. + */ +__weak bool RUC_Completed(RevUpCtrl_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (MC_NULL == pHandle->pCurrentPhaseParams) + { + retVal = true; + } +#ifdef NULL_PTR_REV_UP_CTL + } +#endif + return (retVal); +} + +/** + * @brief Allow to exit from Rev-Up process at the current rotor speed. + * @param pHandle: Pointer on Handle structure of RevUp controller. + */ +__weak void RUC_Stop(RevUpCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + VirtualSpeedSensor_Handle_t *pVSS = pHandle->pVSS; + pHandle->pCurrentPhaseParams = MC_NULL; + pHandle->hPhaseRemainingTicks = 0U; + VSS_SetMecAcceleration(pVSS, SPD_GetAvrgMecSpeedUnit(&pVSS->_Super), 0U); +#ifdef NULL_PTR_REV_UP_CTL + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif + +/** + * @brief Check that alignment and first acceleration stage are completed. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Boolean set to true when first acceleration stage has been reached. + */ +__weak bool RUC_FirstAccelerationStageReached(RevUpCtrl_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (pHandle->bStageCnt >= pHandle->bFirstAccelerationStage) + { + retVal = true; + } +#ifdef NULL_PTR_REV_UP_CTL + } +#endif + return (retVal); +} + +/** + * @brief Allow to modify duration of a selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase where new duration shall be modified. + * This parameter must be a number between 0 and 6. + * @param hDurationms: new duration value required for associated phase. + * This parameter must be set in millisecond. + */ +__weak void RUC_SetPhaseDurationms(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + uint16_t hDurationms) +{ +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->ParamsData[bPhase].hDurationms = hDurationms; +#ifdef NULL_PTR_REV_UP_CTL + } +#endif +} + +/** + * @brief Allow to modify targeted mechanical speed of a selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase where new mechanical speed shall be modified. + * This parameter must be a number between 0 and 6. + * @param hFinalMecSpeedUnit: new targeted mechanical speed. + * This parameter must be expressed in 0.1Hz. + */ +__weak void RUC_SetPhaseFinalMecSpeedUnit(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + int16_t hFinalMecSpeedUnit) +{ +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->ParamsData[bPhase].hFinalMecSpeedUnit = hFinalMecSpeedUnit; +#ifdef NULL_PTR_REV_UP_CTL + } +#endif +} + +/** + * @brief Allow to modify targeted the motor torque of a selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase where new the motor torque shall be modified. + * This parameter must be a number between 0 and 6. + * @param hFinalTorque: new targeted motor torque. + */ +__weak void RUC_SetPhaseFinalTorque(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + int16_t hFinalTorque) +{ +#ifdef NULL_PTR_REV_UP_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->ParamsData[bPhase].hFinalTorque = hFinalTorque; +#ifdef NULL_PTR_REV_UP_CTL + } +#endif +} + +/** + * @brief Allow to configure a Rev-Up phase. + * @param pHandle: Pointer on Handle structure of Rev-Up controller. + * @param phaseNumber : number of phases relative to the programmed Rev-Up + * @param phaseData: + * - RevUp phase where new motor torque shall be modified. + * This parameter must be a number between 0 and 6. + * - RevUp phase where new mechanical speed shall be modified. + * This parameter must be a number between 0 and 6. + * - New duration value required for associated phase in ms unit. + * @retval Boolean set to true + */ +__weak bool RUC_SetPhase(RevUpCtrl_Handle_t *pHandle, uint8_t phaseNumber, + RevUpCtrl_PhaseParams_t *phaseData) +{ + bool retValue = true; +#ifdef NULL_PTR_REV_UP_CTL + if ((MC_NULL == pHandle) || (MC_NULL == phaseData)) + { + retValue = false; + } + else + { +#endif + pHandle->ParamsData[phaseNumber].hFinalTorque = phaseData->hFinalTorque; + pHandle->ParamsData[phaseNumber].hFinalMecSpeedUnit = + phaseData->hFinalMecSpeedUnit; + pHandle->ParamsData[phaseNumber].hDurationms = phaseData->hDurationms; +#ifdef NULL_PTR_REV_UP_CTL + } +#endif + return (retValue); +} + +/** + * @brief Allow to read duration set in selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase from where duration is read. + * This parameter must be a number between 0 and 6. + * @retval Returns duration used in selected phase in ms unit. + */ +__weak uint16_t RUC_GetPhaseDurationms(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase) +{ +#ifdef NULL_PTR_REV_UP_CTL + return ((MC_NULL == pHandle) ? 0U + : (uint16_t)pHandle->ParamsData[bPhase].hDurationms); +#else + return ((uint16_t)pHandle->ParamsData[bPhase].hDurationms); +#endif +} + +/** + * @brief Allow to read targeted rotor speed set in selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase from where targeted rotor speed is read. + * This parameter must be a number between 0 and 6. + * @retval Returns targeted rotor speed set for a selected phase. + */ +__weak int16_t RUC_GetPhaseFinalMecSpeedUnit(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase) +{ +#ifdef NULL_PTR_REV_UP_CTL + return ((MC_NULL == pHandle) + ? 0 + : (int16_t)pHandle->ParamsData[bPhase].hFinalMecSpeedUnit); +#else + return ((int16_t)pHandle->ParamsData[bPhase].hFinalMecSpeedUnit); +#endif +} + +/** + * @brief Allow to read targeted motor torque set in selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase from where targeted motor torque is read. + * This parameter must be a number between 0 and 6. + * @retval Returns targeted motor torque set for a selected phase. + */ +__weak int16_t RUC_GetPhaseFinalTorque(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase) +{ +#ifdef NULL_PTR_REV_UP_CTL + return ((MC_NULL == pHandle) ? 0 : (int16_t)pHandle->ParamsData[bPhase].hFinalTorque); +#else + return ((int16_t)pHandle->ParamsData[bPhase].hFinalTorque); +#endif +} + +/** + * @brief Allow to read total number of programmed phases. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Returns number of phases relative to the programmed Rev-Up. + * + */ + +__weak uint8_t RUC_GetNumberOfPhases(RevUpCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_REV_UP_CTL + return ((MC_NULL == pHandle) ? 0U : (uint8_t)pHandle->bPhaseNbr); +#else + return ((uint8_t)pHandle->bPhaseNbr); +#endif +} + +/** + * @brief Allow to read a programmed phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param phaseNumber : number of phases relative to the programmed Rev-Up + * @param phaseData: + * - RevUp phase from where targeted rotor speed is read. + * This parameter must be a number between 0 and 6. + * - RevUp phase from where targeted motor torque is read. + * This parameter must be a number between 0 and 6. + * - Duration set in selected phase in ms unit. + * @retval Returns Boolean set to true value. + */ +__weak bool RUC_GetPhase(RevUpCtrl_Handle_t *pHandle, uint8_t phaseNumber, + RevUpCtrl_PhaseParams_t *phaseData) +{ + bool retValue = true; +#ifdef NULL_PTR_REV_UP_CTL + if ((MC_NULL == pHandle) || (MC_NULL == phaseData)) + { + retValue = false; + } + else + { +#endif + phaseData->hFinalTorque = (int16_t)pHandle->ParamsData[phaseNumber].hFinalTorque; + phaseData->hFinalMecSpeedUnit = + (int16_t)pHandle->ParamsData[phaseNumber].hFinalMecSpeedUnit; + phaseData->hDurationms = (uint16_t)pHandle->ParamsData[phaseNumber].hDurationms; +#ifdef NULL_PTR_REV_UP_CTL + } +#endif + return (retValue); +} + +/** + * @brief Allow to read status of On The Fly (OTF) feature. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Boolean set to true at the end of OTF processing. + */ +__weak bool RUC_Get_SCLowsideOTF_Status(RevUpCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_REV_UP_CTL + return ((MC_NULL == pHandle) ? false : pHandle->OTFSCLowside); +#else + return (pHandle->OTFSCLowside); +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/revup_ctrl.h b/src/firmware/motor/mcsdk/revup_ctrl.h new file mode 100644 index 0000000000..046d95b33c --- /dev/null +++ b/src/firmware/motor/mcsdk/revup_ctrl.h @@ -0,0 +1,237 @@ +/** + ****************************************************************************** + * @file revup_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * RevUpCtrl component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup RevUpCtrlFOC + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef REVUP_CTRL_H +#define REVUP_CTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" +#include "pwm_curr_fdbk.h" +#include "speed_torq_ctrl.h" +#include "sto_speed_pos_fdbk.h" +#include "virtual_speed_sensor.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup RevUpCtrl + * @{ + */ + +/** @addtogroup RevUpCtrlFOC + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** + * @brief Maximum number of phases allowed for RevUp process. + * + */ +#define RUC_MAX_PHASE_NUMBER 5u + + /** + * @brief RevUpCtrl_PhaseParams_t structure used for phases definition + * + */ + typedef struct + { + uint16_t hDurationms; /**< @brief Duration of the RevUp phase. + This parameter is expressed in millisecond.*/ + int16_t hFinalMecSpeedUnit; /**< @brief Mechanical speed assumed by VSS at the end + of the RevUp phase. Expressed in the unit defined + by #SPEED_UNIT */ + int16_t hFinalTorque; /**< @brief Motor torque reference imposed by STC at the + end of RevUp phase. This value represents + actually the Iq current expressed in digit.*/ + void *pNext; /**< @brief Pointer on the next phase section to proceed + This parameter is NULL for the last element.*/ + } RevUpCtrl_PhaseParams_t; + + /** + * @brief Handle structure of the RevUpCtrl. + * + */ + + typedef struct + { + uint16_t + hRUCFrequencyHz; /**< @brief Frequency call to main RevUp procedure RUC_Exec. + This parameter is equal to speed loop frequency. */ + + int16_t hStartingMecAngle; /**< @brief Starting angle of programmed RevUp.*/ + + uint16_t hPhaseRemainingTicks; /**< @brief Number of clock events remaining to + complete the phase. */ + + int16_t hDirection; /**< @brief Motor direction. + This parameter can be any value -1 or +1 */ + + RevUpCtrl_PhaseParams_t *pCurrentPhaseParams; /**< @brief Pointer on the current + RevUp phase processed. */ + + RevUpCtrl_PhaseParams_t + ParamsData[RUC_MAX_PHASE_NUMBER]; /**< @brief Start up Phases sequences used + by RevUp controller. Up to five phases + can be used for the start up. */ + + uint8_t bPhaseNbr; /**< @brief Number of phases relative to the programmed RevUp + sequence. This parameter can be any value from 1 to 5 */ + + uint8_t bFirstAccelerationStage; /**< @brief Indicates the phase to start the + final acceleration. At start of this stage + sensor-less algorithm cleared.*/ + uint16_t hMinStartUpValidSpeed; /**< @brief Minimum rotor speed required to + validate the startup. This parameter is + expressed in SPPED_UNIT */ + uint16_t hMinStartUpFlySpeed; /**< @brief Minimum rotor speed required to validate + the on the fly. This parameter is expressed in + the unit defined by #SPEED_UNIT */ + int16_t + hOTFFinalRevUpCurrent; /**< @brief Final targetted torque for OTF phase. */ + + uint16_t hOTFSection1Duration; /**< @brief On-the-fly phase duration, millisecond. + This parameter is expressed in millisecond.*/ + bool OTFStartupEnabled; /**< @brief Flag for OTF feature activation. + Feature disabled when set to false */ + uint8_t bOTFRelCounter; /**< @brief Counts the number of reliability of state + observer */ + + bool OTFSCLowside; /**< @brief Flag to indicate status of low side switchs. + This parameter can be true when Low Sides switch is ON + otherwise set to false. */ + bool EnteredZone1; /**< @brief Flag to indicate that the minimum rotor speed has + been reached. */ + + uint8_t bResetPLLTh; /**< @brief Threshold to reset PLL during OTF */ + + uint8_t bResetPLLCnt; /**< @brief Counter to reset PLL during OTF when the + threshold is reached. */ + + uint8_t bStageCnt; /**< @brief Counter of executed phases. + This parameter can be any value from 0 to 5 */ + + RevUpCtrl_PhaseParams_t + OTFPhaseParams; /**< @brief RevUp phase parameter of OTF feature.*/ + + SpeednTorqCtrl_Handle_t + *pSTC; /**< @brief Speed and torque controller object used by RevUpCtrl.*/ + + VirtualSpeedSensor_Handle_t + *pVSS; /**< @brief Virtual speed sensor object used by RevUpCtrl.*/ + + STO_Handle_t *pSNSL; /**< @brief STO sensor object used by OTF startup.*/ + + PWMC_Handle_t *pPWM; /**< @brief PWM object used by OTF startup.*/ + + } RevUpCtrl_Handle_t; + + + /* Exported functions ------------------------------------------------------- */ + + /* Initializes and configures the RevUpCtrl Component */ + void RUC_Init(RevUpCtrl_Handle_t *pHandle, SpeednTorqCtrl_Handle_t *pSTC, + VirtualSpeedSensor_Handle_t *pVSS, STO_Handle_t *pSNSL, + PWMC_Handle_t *pPWM); + + /* Initializes the internal RevUp controller state */ + void RUC_Clear(RevUpCtrl_Handle_t *pHandle, int16_t hMotorDirection); + + /* Main Rev-Up controller procedure executing overall programmed phases. */ + bool RUC_Exec(RevUpCtrl_Handle_t *pHandle); + + /* Main Rev-Up controller procedure that executes overall programmed phases and + * on-the-fly startup handling.*/ + bool RUC_OTF_Exec(RevUpCtrl_Handle_t *pHandle); + + /* Provide current state of Rev-Up controller procedure */ + bool RUC_Completed(RevUpCtrl_Handle_t *pHandle); + + /* Allows to exit from RevUp process at the current Rotor speed. */ + void RUC_Stop(RevUpCtrl_Handle_t *pHandle); + + /* Checks that alignment and first acceleration stage are completed. */ + bool RUC_FirstAccelerationStageReached(RevUpCtrl_Handle_t *pHandle); + + /* Allows to modify duration (ms unit) of a selected phase. */ + void RUC_SetPhaseDurationms(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + uint16_t hDurationms); + + /* Allows to modify targeted mechanical speed of a selected phase. */ + void RUC_SetPhaseFinalMecSpeedUnit(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + int16_t hFinalMecSpeedUnit); + + /* Allows to modify targeted the motor torque of a selected phase. */ + void RUC_SetPhaseFinalTorque(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + int16_t hFinalTorque); + + /* Allows to read duration set in selected phase. */ + uint16_t RUC_GetPhaseDurationms(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase); + + /* Allows to read targeted Rotor speed set in selected phase. */ + int16_t RUC_GetPhaseFinalMecSpeedUnit(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase); + + /* Allows to read targeted motor torque set in selected phase. */ + int16_t RUC_GetPhaseFinalTorque(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase); + + /* Allows to read total number of programmed phases */ + uint8_t RUC_GetNumberOfPhases(RevUpCtrl_Handle_t *pHandle); + + /* It is used to check if this stage is used for align motor. */ + uint8_t RUC_IsAlignStageNow(RevUpCtrl_Handle_t *pHandle); + + /* Allows to read status of On The Fly (OTF) feature */ + bool RUC_Get_SCLowsideOTF_Status(RevUpCtrl_Handle_t *pHandle); + + /* Allows to read a programmed phase. */ + bool RUC_GetPhase(RevUpCtrl_Handle_t *pHandle, uint8_t phaseNumber, + RevUpCtrl_PhaseParams_t *phaseData); + + /* Allows to configure a Rev-Up phase. */ + bool RUC_SetPhase(RevUpCtrl_Handle_t *pHandle, uint8_t phaseNumber, + RevUpCtrl_PhaseParams_t *phaseData); + + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* REVUP_CTRL_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/revup_ctrl_sixstep.c b/src/firmware/motor/mcsdk/revup_ctrl_sixstep.c new file mode 100644 index 0000000000..a337717a85 --- /dev/null +++ b/src/firmware/motor/mcsdk/revup_ctrl_sixstep.c @@ -0,0 +1,567 @@ +/** + ****************************************************************************** + * @file revup_ctrl_sixstep.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides the functions that implement the features + * of the Rev-Up Control component for Six-Step drives of the Motor + * Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + * @ingroup RevUpCtrl6S + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/revup_ctrl_sixstep.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup RevUpCtrl + * + * @{ + */ + +/** @defgroup RevUpCtrl6S Six-Step Rev-Up Control component + * @brief Rev-Up Control component used to start motor driven with the Six-Step technique + * + * @{ + */ + + +/* Private defines -----------------------------------------------------------*/ + +/** + * @brief Timeout used to reset integral term of PLL. + * It is expressed in ms. + * + */ +#define RUC_OTF_PLL_RESET_TIMEOUT 100u + +/* Private functions ----------------------------------------------------------*/ + +/* Returns the mechanical speed of a selected phase */ +static int16_t RUC_GetPhaseFinalMecSpeed01Hz(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase) +{ + int16_t hRetVal = 0; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + hRetVal = pHandle->ParamsData[bPhase].hFinalMecSpeedUnit; + } + return (hRetVal); +} + +/** + * @brief Initialize and configure the 6-Step RevUpCtrl Component + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param pSTC: Pointer on speed and torque controller structure. + * @param pVSS: Pointer on virtual speed sensor structure. + */ +__weak void RUC_Init(RevUpCtrl_Handle_t *pHandle, SpeednTorqCtrl_Handle_t *pSTC, + VirtualSpeedSensor_Handle_t *pVSS) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + RevUpCtrl_PhaseParams_t *pRUCPhaseParams = &pHandle->ParamsData[0]; + uint8_t bPhase = 0U; + + pHandle->pSTC = pSTC; + pHandle->pVSS = pVSS; + pHandle->EnteredZone1 = false; + + while ((pRUCPhaseParams != MC_NULL) && (bPhase < RUC_MAX_PHASE_NUMBER)) + { + /* Dump HF data for now HF data are forced to 16 bits*/ + pRUCPhaseParams = (RevUpCtrl_PhaseParams_t *) + pRUCPhaseParams->pNext; // cstat !MISRAC2012-Rule-11.5 + bPhase++; + } + + if (0U == bPhase) + { + /* nothing to do error */ + } + else + { + pHandle->ParamsData[bPhase - 1u].pNext = MC_NULL; + + pHandle->bPhaseNbr = bPhase; + } + } +} + +/* + * @brief Initialize internal 6-Step RevUp controller state. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param hMotorDirection: Rotor rotation direction. + * This parameter must be -1 or +1. + */ + +__weak void RUC_Clear(RevUpCtrl_Handle_t *pHandle, int16_t hMotorDirection) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + VirtualSpeedSensor_Handle_t *pVSS = pHandle->pVSS; + SpeednTorqCtrl_Handle_t *pSTC = pHandle->pSTC; + RevUpCtrl_PhaseParams_t *pPhaseParams = pHandle->ParamsData; + + pHandle->hDirection = hMotorDirection; + pHandle->EnteredZone1 = false; + + /*Initializes the rev up stages counter.*/ + pHandle->bStageCnt = 0U; + + /* Calls the clear method of VSS.*/ + VSS_Clear(pVSS); + + /* Sets the STC in torque mode.*/ + STC_SetControlMode(pSTC, MCM_TORQUE_MODE); + + /* Sets the mechanical starting angle of VSS.*/ + VSS_SetMecAngle(pVSS, pHandle->hStartingMecAngle * hMotorDirection); + + /* Sets to zero the starting torque of STC */ + (void)STC_ExecRamp(pSTC, STC_GetDutyCycleRef(pSTC), 0U); + + /* Gives the first command to STC and VSS.*/ + (void)STC_ExecRamp(pSTC, pPhaseParams->hFinalPulse, + (uint32_t)(pPhaseParams->hDurationms)); + + VSS_SetMecAcceleration(pVSS, pPhaseParams->hFinalMecSpeedUnit * hMotorDirection, + pPhaseParams->hDurationms); + + /* Compute hPhaseRemainingTicks.*/ + pHandle->hPhaseRemainingTicks = + (uint16_t)((((uint32_t)pPhaseParams->hDurationms) * + ((uint32_t)pHandle->hRUCFrequencyHz)) / + 1000U); + + pHandle->hPhaseRemainingTicks++; + + /*Set the next phases parameter pointer.*/ + pHandle->pCurrentPhaseParams = + (RevUpCtrl_PhaseParams_t *) + pPhaseParams->pNext; // cstat !MISRAC2012-Rule-11.5 + } +} + +/** + * @brief Update rev-up duty cycle relative to actual Vbus value to be applied + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param BusVHandle: pointer to the bus voltage sensor + */ +__weak void RUC_UpdatePulse(RevUpCtrl_Handle_t *pHandle, + BusVoltageSensor_Handle_t *BusVHandle) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + uint16_t tPulseUpdateFactor = + 10 * NOMINAL_BUS_VOLTAGE_V / VBS_GetAvBusVoltage_V(BusVHandle); + pHandle->PulseUpdateFactor = tPulseUpdateFactor; + } +} + +/* + * @brief 6-Step Main revup controller procedure executing overall programmed phases. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Boolean set to true when entire revup phases have been completed. + */ +__weak bool RUC_Exec(RevUpCtrl_Handle_t *pHandle) +{ + bool retVal = true; + + if (MC_NULL == pHandle) + { + retVal = false; + } + else + { + if (pHandle->hPhaseRemainingTicks > 0U) + { + /* Decrease the hPhaseRemainingTicks.*/ + pHandle->hPhaseRemainingTicks--; + + } /* hPhaseRemainingTicks > 0 */ + + if (0U == pHandle->hPhaseRemainingTicks) + { + if (pHandle->pCurrentPhaseParams != MC_NULL) + { + /* If it becomes zero the current phase has been completed.*/ + /* Gives the next command to STC and VSS.*/ + uint16_t hPulse = pHandle->pCurrentPhaseParams->hFinalPulse * + pHandle->PulseUpdateFactor / 10; + (void)STC_ExecRamp(pHandle->pSTC, hPulse, + (uint32_t)(pHandle->pCurrentPhaseParams->hDurationms)); + + VSS_SetMecAcceleration(pHandle->pVSS, + pHandle->pCurrentPhaseParams->hFinalMecSpeedUnit * + pHandle->hDirection, + pHandle->pCurrentPhaseParams->hDurationms); + + /* Compute hPhaseRemainingTicks.*/ + pHandle->hPhaseRemainingTicks = + (uint16_t)((((uint32_t)pHandle->pCurrentPhaseParams->hDurationms) * + ((uint32_t)pHandle->hRUCFrequencyHz)) / + 1000U); + pHandle->hPhaseRemainingTicks++; + + /*Set the next phases parameter pointer.*/ + pHandle->pCurrentPhaseParams = + pHandle->pCurrentPhaseParams->pNext; // cstat !MISRAC2012-Rule-11.5 + + /*Increases the rev up stages counter.*/ + pHandle->bStageCnt++; + } + else + { + retVal = false; + } + } + } + return (retVal); +} + + + +/* + * @brief It is used to check if this stage is used for align motor. + * @param this related object of class CRUC. + * @retval Returns 1 if the alignment is correct otherwise it returns 0 + */ +uint8_t RUC_IsAlignStageNow(RevUpCtrl_Handle_t *pHandle) +{ + uint8_t align_flag = 0; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + int16_t speed; + speed = RUC_GetPhaseFinalMecSpeed01Hz(pHandle, pHandle->bStageCnt); + if (0 == speed) + { + align_flag = 1; + } + } + return (align_flag); +} + +/* + * @brief Provide current state of revup controller procedure. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Boolean set to true when entire revup phases have been completed. + */ +__weak bool RUC_Completed(RevUpCtrl_Handle_t *pHandle) +{ + bool retVal = false; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + if (MC_NULL == pHandle->pCurrentPhaseParams) + { + retVal = true; + } + } + return (retVal); +} + +/* + * @brief Allow to exit from RevUp process at the current rotor speed. + * @param pHandle: Pointer on Handle structure of RevUp controller. + */ +__weak void RUC_Stop(RevUpCtrl_Handle_t *pHandle) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + VirtualSpeedSensor_Handle_t *pVSS = pHandle->pVSS; + pHandle->pCurrentPhaseParams = MC_NULL; + pHandle->hPhaseRemainingTicks = 0U; + VSS_SetMecAcceleration(pVSS, SPD_GetAvrgMecSpeedUnit(&pVSS->_Super), 0U); + } +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif + +/* + * @brief Check that alignment and first acceleration stage are completed. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Boolean set to true when first acceleration stage has been reached. + */ +__weak bool RUC_FirstAccelerationStageReached(RevUpCtrl_Handle_t *pHandle) +{ + bool retVal = false; + VirtualSpeedSensor_Handle_t *pVSS = pHandle->pVSS; + int16_t hSpeed; + + hSpeed = SPD_GetAvrgMecSpeedUnit(&pVSS->_Super); + if (hSpeed < 0) + hSpeed = -hSpeed; + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + if (pHandle->bStageCnt >= pHandle->bFirstAccelerationStage) + { + retVal = true; + } + } + return (retVal); +} + +/* + * @brief Allow to modify duration of a selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase where new duration shall be modified. + * This parameter must be a number between 0 and 6. + * @param hDurationms: new duration value required for associated phase. + * This parameter must be set in millisecond. + */ +__weak void RUC_SetPhaseDurationms(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + uint16_t hDurationms) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->ParamsData[bPhase].hDurationms = hDurationms; + } +} + +/* + * @brief Allow to modify targeted mechanical speed of a selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase where new mechanical speed shall be modified. + * This parameter must be a number between 0 and 6. + * @param hFinalMecSpeedUnit: new targeted mechanical speed. + * This parameter must be expressed in 0.1Hz. + */ +__weak void RUC_SetPhaseFinalMecSpeedUnit(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + int16_t hFinalMecSpeedUnit) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->ParamsData[bPhase].hFinalMecSpeedUnit = hFinalMecSpeedUnit; + } +} + +/** + * @brief Allow to modify targeted PWM counter pulse of a selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase where new the motor torque shall be modified. + * This parameter must be a number between 0 and 6. + * @param hFinalPulse: new targeted motor torque. + */ +__weak void RUC_SetPhaseFinalPulse(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + uint16_t hFinalPulse) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->ParamsData[bPhase].hFinalPulse = hFinalPulse; + } +} + +/* + * @brief Allow to configure a revUp phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Returns boolean set to true + */ +__weak bool RUC_SetPhase(RevUpCtrl_Handle_t *pHandle, uint8_t phaseNumber, + RevUpCtrl_PhaseParams_t *phaseData) +{ + bool retValue = true; + + if ((MC_NULL == pHandle) || (MC_NULL == phaseData)) + { + retValue = false; + } + else + { + pHandle->ParamsData[phaseNumber].hFinalPulse = phaseData->hFinalPulse; + pHandle->ParamsData[phaseNumber].hFinalMecSpeedUnit = + phaseData->hFinalMecSpeedUnit; + pHandle->ParamsData[phaseNumber].hDurationms = phaseData->hDurationms; + } + return (retValue); +} + +/* + * @brief Allow to read duration set in selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase from where duration is read. + * This parameter must be a number between 0 and 6. + * @retval Returns duration used in selected phase. + */ +__weak uint16_t RUC_GetPhaseDurationms(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase) +{ + return ((MC_NULL == pHandle) ? 0U + : (uint16_t)pHandle->ParamsData[bPhase].hDurationms); +} + +/* + * @brief Allow to read targeted rotor speed set in selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase from where targeted rotor speed is read. + * This parameter must be a number between 0 and 6. + * @retval Returns targeted rotor speed set in selected phase. + */ +__weak int16_t RUC_GetPhaseFinalMecSpeedUnit(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase) +{ + return ((MC_NULL == pHandle) + ? 0 + : (int16_t)pHandle->ParamsData[bPhase].hFinalMecSpeedUnit); +} + +/** + * @brief Allow to read targeted PWM counter pulse set in selected phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @param bPhase: RevUp phase from where targeted motor torque is read. + * This parameter must be a number between 0 and 6. + * @retval Returns targeted motor torque set in selected phase. + */ +__weak int16_t RUC_GetPhaseFinalPulse(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase) +{ + return ((MC_NULL == pHandle) ? 0 : (int16_t)pHandle->ParamsData[bPhase].hFinalPulse); +} + +/* + * @brief Allow to read total number of programmed phases. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Returns number of phases relative to the programmed revup. + */ +__weak uint8_t RUC_GetNumberOfPhases(RevUpCtrl_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle) ? 0U : (uint8_t)pHandle->bPhaseNbr); +} + +/* + * @brief Allow to read a programmed phase. + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Returns number of phases relative to the programmed revup. + */ +__weak bool RUC_GetPhase(RevUpCtrl_Handle_t *pHandle, uint8_t phaseNumber, + RevUpCtrl_PhaseParams_t *phaseData) +{ + bool retValue = true; + + if ((MC_NULL == pHandle) || (MC_NULL == phaseData)) + { + retValue = false; + } + else + { + phaseData->hFinalPulse = (int16_t)pHandle->ParamsData[phaseNumber].hFinalPulse; + phaseData->hFinalMecSpeedUnit = + (int16_t)pHandle->ParamsData[phaseNumber].hFinalMecSpeedUnit; + phaseData->hDurationms = (uint16_t)pHandle->ParamsData[phaseNumber].hDurationms; + } + return (retValue); +} + +/** + * @brief Allow to read spinning direction of the motor + * @param pHandle: Pointer on Handle structure of RevUp controller. + * @retval Returns direction of the motor. + */ +__weak int16_t RUC_GetDirection(RevUpCtrl_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle) ? 0U : (int16_t)pHandle->hDirection); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/revup_ctrl_sixstep.h b/src/firmware/motor/mcsdk/revup_ctrl_sixstep.h new file mode 100644 index 0000000000..a3e5876ff1 --- /dev/null +++ b/src/firmware/motor/mcsdk/revup_ctrl_sixstep.h @@ -0,0 +1,213 @@ +/** + ****************************************************************************** + * @file revup_ctrl_sixstep.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Six-step variant of the Rev up control component of the Motor Control + * SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup RevUpCtrl6S + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef REVUP_CTRL_SIXSTEP_H +#define REVUP_CTRL_SIXSTEP_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/bus_voltage_sensor.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/speed_ctrl.h" +#include "firmware/motor/mcsdk/virtual_speed_sensor.h" +#include "firmware/motor/power_stage_parameters.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup RevUpCtrl + * @{ + */ + +/** @addtogroup RevUpCtrl6S + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +/** + * @brief Maximum number of phases allowed for RevUp process. + * + */ +#define RUC_MAX_PHASE_NUMBER 5u + + /** + * @brief RevUpCtrl_PhaseParams_t structure used for phases definition + * + */ + typedef struct + { + uint16_t hDurationms; /* Duration of the RevUp phase. + This parameter is expressed in millisecond.*/ + int16_t hFinalMecSpeedUnit; /* Mechanical speed assumed by VSS at the end of + the RevUp phase. Expressed in the unit defined + by #SPEED_UNIT */ + uint16_t + hFinalPulse; /**< @brief Final pulse factor according to sensed Vbus value + + This field parameter is dedicated to 6-Step use */ + void *pNext; /* Pointer on the next phase section to proceed + This parameter is NULL for the last element.*/ + } RevUpCtrl_PhaseParams_t; + + /** + * + * + */ + + typedef struct + { + uint16_t hRUCFrequencyHz; /* Frequency call to main RevUp procedure RUC_Exec. + This parameter is equal to speed loop frequency. */ + + int16_t hStartingMecAngle; /* Starting angle of programmed RevUp.*/ + + uint16_t hPhaseRemainingTicks; /* Number of clock events remaining to complete the + phase. */ + + int16_t hDirection; /* Motor direction. + This parameter can be any value -1 or +1 */ + + RevUpCtrl_PhaseParams_t + *pCurrentPhaseParams; /* Pointer on the current RevUp phase processed. */ + + RevUpCtrl_PhaseParams_t + ParamsData[RUC_MAX_PHASE_NUMBER]; /* Start up Phases sequences used by RevUp + controller. Up to five phases can be used + for the start up. */ + + uint16_t + PulseUpdateFactor; /**< @brief Used to update the 6-Step rev-up pulse to the + actual Vbus value. + + This field parameter is dedicated to 6-Step use */ + uint8_t bPhaseNbr; /* Number of phases relative to the programmed RevUp sequence. + This parameter can be any value from 1 to 5 */ + + uint8_t bFirstAccelerationStage; /* Indicate the phase to start the final + acceleration. At start of this stage + sensor-less algorithm cleared.*/ + uint16_t hMinStartUpValidSpeed; /* Minimum rotor speed required to validate the + startup. This parameter is expressed in + SPPED_UNIT */ + bool EnteredZone1; /**< @brief Flag to indicate that the minimum rotor speed has + been reached. */ + + uint8_t bStageCnt; /**< @brief Counter of executed phases. + This parameter can be any value from 0 to 5 */ + + SpeednTorqCtrl_Handle_t + *pSTC; /**< @brief Speed and torque controller object used by RevUpCtrl.*/ + + VirtualSpeedSensor_Handle_t + *pVSS; /**< @brief Virtual speed sensor object used by RevUpCtrl.*/ + + } RevUpCtrl_Handle_t; + + + /* Exported functions ------------------------------------------------------- */ + + /* Initializes and configures the RevUpCtrl Component */ + void RUC_Init(RevUpCtrl_Handle_t *pHandle, SpeednTorqCtrl_Handle_t *pSTC, + VirtualSpeedSensor_Handle_t *pVSS); + + /* Initializes the internal RevUp controller state */ + void RUC_Clear(RevUpCtrl_Handle_t *pHandle, int16_t hMotorDirection); + + /* Updates the pulse according to sensed Vbus value */ + void RUC_UpdatePulse(RevUpCtrl_Handle_t *pHandle, + BusVoltageSensor_Handle_t *BusVHandle); + + /* Main Rev-Up controller procedure executing overall programmed phases. */ + bool RUC_Exec(RevUpCtrl_Handle_t *pHandle); + + /* Provide current state of Rev-Up controller procedure */ + bool RUC_Completed(RevUpCtrl_Handle_t *pHandle); + + /* Allows to exit from RevUp process at the current Rotor speed. */ + void RUC_Stop(RevUpCtrl_Handle_t *pHandle); + + /* Checks that alignment and first acceleration stage are completed. */ + bool RUC_FirstAccelerationStageReached(RevUpCtrl_Handle_t *pHandle); + + /* Allows to modify duration (ms unit) of a selected phase. */ + void RUC_SetPhaseDurationms(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + uint16_t hDurationms); + + /* Allows to modify targeted mechanical speed of a selected phase. */ + void RUC_SetPhaseFinalMecSpeedUnit(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + int16_t hFinalMecSpeedUnit); + + /* Function used to set the final Pulse targeted at the end of a specific phase. */ + void RUC_SetPhaseFinalPulse(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase, + uint16_t hFinalTorque); + + /* Allows to read duration set in selected phase. */ + uint16_t RUC_GetPhaseDurationms(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase); + + /* Allows to read targeted Rotor speed set in selected phase. */ + int16_t RUC_GetPhaseFinalMecSpeedUnit(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase); + + /* Function used to read the Final pulse factor of a specific RevUp phase */ + int16_t RUC_GetPhaseFinalPulse(RevUpCtrl_Handle_t *pHandle, uint8_t bPhase); + + /* Allows to read total number of programmed phases */ + uint8_t RUC_GetNumberOfPhases(RevUpCtrl_Handle_t *pHandle); + + /* It is used to check if this stage is used for align motor. */ + uint8_t RUC_IsAlignStageNow(RevUpCtrl_Handle_t *pHandle); + + /* Allows to read a programmed phase. */ + bool RUC_GetPhase(RevUpCtrl_Handle_t *pHandle, uint8_t phaseNumber, + RevUpCtrl_PhaseParams_t *phaseData); + + /* Allows to configure a Rev-Up phase. */ + bool RUC_SetPhase(RevUpCtrl_Handle_t *pHandle, uint8_t phaseNumber, + RevUpCtrl_PhaseParams_t *phaseData); + + /* It is used to check the spinning direction of the motor. */ + int16_t RUC_GetDirection(RevUpCtrl_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* REVUP_CTRL_SIXSTEP_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/speed_ctrl.c b/src/firmware/motor/mcsdk/speed_ctrl.c new file mode 100644 index 0000000000..145f779d35 --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_ctrl.c @@ -0,0 +1,525 @@ +/* + ****************************************************************************** + * @file speed_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the following features + * of the Speed Control component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/speed_ctrl.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" + +#define CHECK_BOUNDARY + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup SpeednTorqCtrl Speed Control + * @brief Speed Control component of the Motor Control SDK + * + * @todo Document the Speed Control "module". + * + * @{ + */ + +/** + * @brief Initializes all the object variables, usually it has to be called + * once right after object creation. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @param pPI the PI object used as controller for the speed regulation. + * @param SPD_Handle the speed sensor used to perform the speed regulation. + * @retval none. + */ +__weak void STC_Init(SpeednTorqCtrl_Handle_t *pHandle, PID_Handle_t *pPI, + SpeednPosFdbk_Handle_t *SPD_Handle) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->PISpeed = pPI; + pHandle->SPD = SPD_Handle; + pHandle->Mode = pHandle->ModeDefault; + pHandle->SpeedRefUnitExt = ((int32_t)pHandle->MecSpeedRefUnitDefault) * 65536; + pHandle->DutyCycleRef = ((uint32_t)pHandle->DutyCycleRefDefault) * 65536; + pHandle->TargetFinal = 0; + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; + } +} + +/** + * @brief It sets in real time the speed sensor utilized by the STC. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @param SPD_Handle Speed sensor component to be set. + * @retval none + */ +__weak void STC_SetSpeedSensor(SpeednTorqCtrl_Handle_t *pHandle, + SpeednPosFdbk_Handle_t *SPD_Handle) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->SPD = SPD_Handle; + } +} + +/** + * @brief It returns the speed sensor utilized by the FOC. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval SpeednPosFdbk_Handle_t speed sensor utilized by the FOC. + */ +__weak SpeednPosFdbk_Handle_t *STC_GetSpeedSensor(SpeednTorqCtrl_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle) ? MC_NULL : pHandle->SPD); +} + +/** + * @brief It should be called before each motor restart. If STC is set in + speed mode, this method resets the integral term of speed regulator. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval none. + */ +__weak void STC_Clear(SpeednTorqCtrl_Handle_t *pHandle) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + if (MCM_SPEED_MODE == pHandle->Mode) + { + PID_SetIntegralTerm(pHandle->PISpeed, 0); + } + pHandle->DutyCycleRef = ((uint32_t)pHandle->DutyCycleRefDefault) * 65536; + } +} + +/** + * @brief Get the current mechanical rotor speed reference. + * Expressed in the unit defined by SPEED_UNIT. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval int16_t current mechanical rotor speed reference. + * Expressed in the unit defined by SPEED_UNIT. + */ +__weak int16_t STC_GetMecSpeedRefUnit(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NO_FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + return ((MC_NULL == pHandle) ? 0 : (int16_t)(pHandle->SpeedRefUnitExt >> 16)); +#else + return ((MC_NULL == pHandle) ? 0 : (int16_t)(pHandle->SpeedRefUnitExt / 65536)); +#endif +} + +/** + * @brief Get the current motor dutycycle reference. This value represents + * actually the dutycycle reference expressed in digit. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval uint16_t current dutycycle reference. This value is actually expressed in + * digit. + */ +__weak uint16_t STC_GetDutyCycleRef(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NO_FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + return ((MC_NULL == pHandle) ? 0 : (uint16_t)(pHandle->DutyCycleRef >> 16)); +#else + return ((MC_NULL == pHandle) ? 0 : (uint16_t)(pHandle->DutyCycleRef / 65536)); +#endif +} + +/** + * @brief Set the modality of the speed controller. Two modality + * are available Torque mode and Speed mode. + * In Torque mode is possible to set directly the dutycycle + * reference or execute a motor dutycycle ramp. This value represents + * actually the reference expressed in digit. + * In Speed mode is possible to set the mechanical rotor speed + * reference or execute a speed ramp. The required motor dutycycle is + * automatically calculated by the STC. + * This command interrupts the execution of any previous ramp command + * maintaining the last value of dutycycle. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @param bMode modality of STC. It can be one of these two settings: + * MCM_TORQUE_MODE to enable the Torque mode or MCM_SPEED_MODE to + * enable the Speed mode. + * @retval none + */ +__weak void STC_SetControlMode(SpeednTorqCtrl_Handle_t *pHandle, MC_ControlMode_t bMode) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->Mode = bMode; + pHandle->RampRemainingStep = 0u; /* Interrupts previous ramp. */ + } +} + +/** + * @brief Get the modality of the speed controller. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval MC_ControlMode_t It returns the modality of STC. It can be one of + * these two values: MCM_TORQUE_MODE or MCM_SPEED_MODE. + */ +__weak MC_ControlMode_t STC_GetControlMode(SpeednTorqCtrl_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle) ? MCM_TORQUE_MODE : pHandle->Mode); +} + +/** + * @brief Starts the execution of a ramp using new target and duration. This + * command interrupts the execution of any previous ramp command. + * The generated ramp will be in the modality previously set by + * STC_SetControlMode method. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @param hTargetFinal final value of command. This is different accordingly + * the STC modality. + * hTargetFinal is the value of mechanical rotor speed reference at the end + * of the ramp.Expressed in the unit defined by SPEED_UNIT + * @param hDurationms the duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the value. + * @retval bool It return false if the absolute value of hTargetFinal is out of + * the boundary of the application (Above max application speed or below min + * application speed in this case the command is ignored and the + * previous ramp is not interrupted, otherwise it returns true. + */ +__weak bool STC_ExecRamp(SpeednTorqCtrl_Handle_t *pHandle, int16_t hTargetFinal, + uint32_t hDurationms) +{ + bool allowedRange = true; + + if (MC_NULL == pHandle) + { + allowedRange = false; + } + else + { + uint32_t wAux; + int32_t wAux1; + int16_t hCurrentReference; + + /* Check if the hTargetFinal is out of the bound of application. */ + if (MCM_TORQUE_MODE == pHandle->Mode) + { + hCurrentReference = STC_GetDutyCycleRef(pHandle); +#ifdef CHECK_BOUNDARY + if ((int32_t)hTargetFinal > (int32_t)pHandle->MaxPositiveDutyCycle) + { + allowedRange = false; + } +#endif + } + else + { +#ifdef NO_FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hCurrentReference = (int16_t)(pHandle->SpeedRefUnitExt >> 16); +#else + hCurrentReference = (int16_t)(pHandle->SpeedRefUnitExt / 65536); +#endif + +#ifdef CHECK_BOUNDARY + if ((int32_t)hTargetFinal > (int32_t)pHandle->MaxAppPositiveMecSpeedUnit) + { + allowedRange = false; + } + else if (hTargetFinal < pHandle->MinAppNegativeMecSpeedUnit) + { + allowedRange = false; + } + else if ((int32_t)hTargetFinal < (int32_t)pHandle->MinAppPositiveMecSpeedUnit) + { + if (hTargetFinal > pHandle->MaxAppNegativeMecSpeedUnit) + { + allowedRange = false; + } + } + else + { + /* Nothing to do */ + } +#endif + } + + if (true == allowedRange) + { + /* Interrupts the execution of any previous ramp command */ + if (0U == hDurationms) + { + if (MCM_SPEED_MODE == pHandle->Mode) + { + pHandle->SpeedRefUnitExt = ((int32_t)hTargetFinal) * 65536; + } + else + { + pHandle->DutyCycleRef = ((int32_t)hTargetFinal) * 65536; + } + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; + } + else + { + /* Store the hTargetFinal to be applied in the last step */ + pHandle->TargetFinal = hTargetFinal; + + /* Compute the (wRampRemainingStep) number of steps remaining to complete + the ramp. */ + wAux = ((uint32_t)hDurationms) * ((uint32_t)pHandle->STCFrequencyHz); + wAux /= 1000U; + pHandle->RampRemainingStep = wAux; + pHandle->RampRemainingStep++; + + /* Compute the increment/decrement amount (wIncDecAmount) to be applied to + the reference value at each CalcSpeedReference. */ + wAux1 = (((int32_t)hTargetFinal) - ((int32_t)hCurrentReference)) * 65536; + wAux1 /= ((int32_t)pHandle->RampRemainingStep); + pHandle->IncDecAmount = wAux1; + } + } + } + return (allowedRange); +} + +/** + * @brief This command interrupts the execution of any previous ramp command. + * The last value of mechanical rotor speed reference is maintained. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval none + */ +__weak void STC_StopRamp(SpeednTorqCtrl_Handle_t *pHandle) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; + } +} + +/** + * @brief It is used to compute the new value of motor speed reference. It + * must be called at fixed time equal to hSTCFrequencyHz. It is called + * passing as parameter the speed sensor used to perform the speed + * regulation. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval int16_t motor dutycycle reference. This value represents actually the + * dutycycle expressed in digit. + */ +__weak uint16_t STC_CalcSpeedReference(SpeednTorqCtrl_Handle_t *pHandle) +{ + uint16_t hDutyCycleReference; + + if (MC_NULL == pHandle) + { + hDutyCycleReference = 0; + } + else + { + int32_t wCurrentReference; + int16_t hMeasuredSpeed; + int16_t hTargetSpeed; + int16_t hError; + + if (MCM_TORQUE_MODE == pHandle->Mode) + { + wCurrentReference = pHandle->DutyCycleRef; + } + else + { + wCurrentReference = pHandle->SpeedRefUnitExt; + } + + /* Update the speed reference or the torque reference according to the mode + and terminates the ramp if needed. */ + if (pHandle->RampRemainingStep > 1U) + { + /* Increment/decrement the reference value. */ + wCurrentReference += pHandle->IncDecAmount; + + /* Decrement the number of remaining steps */ + pHandle->RampRemainingStep--; + } + else if (1U == pHandle->RampRemainingStep) + { + /* Set the backup value of hTargetFinal. */ + wCurrentReference = ((int32_t)pHandle->TargetFinal) * 65536; + pHandle->RampRemainingStep = 0U; + } + else + { + /* Do nothing. */ + } + + if (MCM_SPEED_MODE == pHandle->Mode) + { + /* Run the speed control loop */ + + /* Compute speed error */ +#ifdef NO_FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hTargetSpeed = (int16_t)(wCurrentReference >> 16); +#else + hTargetSpeed = (int16_t)(wCurrentReference / 65536); +#endif + hMeasuredSpeed = SPD_GetAvrgMecSpeedUnit(pHandle->SPD); + if (hTargetSpeed < 0) + hError = hMeasuredSpeed - hTargetSpeed; + else + hError = hTargetSpeed - hMeasuredSpeed; + hDutyCycleReference = PI_Controller(pHandle->PISpeed, (int32_t)hError); + + pHandle->SpeedRefUnitExt = wCurrentReference; + pHandle->DutyCycleRef = ((int32_t)hDutyCycleReference) * 65536; + } + else + { + pHandle->DutyCycleRef = wCurrentReference; +#ifdef NO_FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hDutyCycleReference = (int16_t)(wCurrentReference >> 16); +#else + hDutyCycleReference = (int16_t)(wCurrentReference / 65536); +#endif + } + } + return (hDutyCycleReference); +} + +/** + * @brief Get the Default mechanical rotor speed reference. + * Expressed in the unit defined by #SPEED_UNIT. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval int16_t It returns the Default mechanical rotor speed. + * Expressed in the unit defined by #SPEED_UNIT + */ +__weak int16_t STC_GetMecSpeedRefUnitDefault(SpeednTorqCtrl_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle) ? 0 : pHandle->MecSpeedRefUnitDefault); +} + +/** + * @brief Returns the Application maximum positive value of rotor speed. Expressed in the + * unit defined by #SPEED_UNIT. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + */ +__weak uint16_t STC_GetMaxAppPositiveMecSpeedUnit(SpeednTorqCtrl_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle) ? 0U : pHandle->MaxAppPositiveMecSpeedUnit); +} + +/** + * @brief Returns the Application minimum negative value of rotor speed. Expressed in the + * unit defined by #SPEED_UNIT. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + */ +__weak int16_t STC_GetMinAppNegativeMecSpeedUnit(SpeednTorqCtrl_Handle_t *pHandle) +{ + return ((MC_NULL == pHandle) ? 0 : pHandle->MinAppNegativeMecSpeedUnit); +} + +/** + * @brief Check if the settled speed ramp has been completed. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval bool It returns true if the ramp is completed, false otherwise. + */ +__weak bool STC_RampCompleted(SpeednTorqCtrl_Handle_t *pHandle) +{ + bool retVal = false; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + if (0U == pHandle->RampRemainingStep) + { + retVal = true; + } + } + return (retVal); +} + +/** + * @brief Stop the execution of speed ramp. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval bool It returns true if the command is executed, false otherwise. + */ +__weak bool STC_StopSpeedRamp(SpeednTorqCtrl_Handle_t *pHandle) +{ + bool retVal = false; + + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + if (MCM_SPEED_MODE == pHandle->Mode) + { + pHandle->RampRemainingStep = 0u; + retVal = true; + } + } + return (retVal); +} + +/** + * @brief Force the speed reference to the curren speed. It is used + * at the START_RUN state to initialize the speed reference. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component + * @retval none + */ +__weak void STC_ForceSpeedReferenceToCurrentSpeed(SpeednTorqCtrl_Handle_t *pHandle) +{ + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { + pHandle->SpeedRefUnitExt = + ((int32_t)SPD_GetAvrgMecSpeedUnit(pHandle->SPD)) * (int32_t)65536; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/speed_ctrl.h b/src/firmware/motor/mcsdk/speed_ctrl.h new file mode 100644 index 0000000000..ed1cec0982 --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_ctrl.h @@ -0,0 +1,173 @@ +/** + ****************************************************************************** + * @file speed_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Speed & Torque Control component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeednTorqCtrl + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SPEEDCTRLCLASS_H +#define __SPEEDCTRLCLASS_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" +#include "pid_regulator.h" +#include "speed_pos_fdbk.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednTorqCtrl + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief Speed Control parameters definition + */ + typedef struct + { + MC_ControlMode_t Mode; /*!< Modality of STC. It can be one of these two + settings: STC_TORQUE_MODE to enable the + Torque mode or STC_SPEED_MODE to enable the + Speed mode.*/ + int16_t TargetFinal; /*!< Backup of hTargetFinal to be applied in the + last step.*/ + int32_t SpeedRefUnitExt; /*!< Current mechanical rotor speed reference + expressed in SPEED_UNIT multiplied by + 65536.*/ + uint32_t DutyCycleRef; /*!< Current pulse reference.*/ + uint32_t RampRemainingStep; /*!< Number of steps remaining to complete the + ramp.*/ + PID_Handle_t *PISpeed; /*!< The regulator used to perform the speed + control loop.*/ + SpeednPosFdbk_Handle_t *SPD; /*!< The speed sensor used to perform the speed + regulation.*/ + int32_t IncDecAmount; /*!< Increment/decrement amount to be applied to + the reference value at each + CalcSpeedReference.*/ + + uint16_t STCFrequencyHz; /*!< Frequency on which the user updates + the torque reference calling + STC_CalcTorqueReference method + expressed in Hz */ + uint16_t + MaxAppPositiveMecSpeedUnit; /*!< Application maximum positive value + of the rotor mechanical speed. Expressed in + the unit defined by #SPEED_UNIT.*/ + uint16_t + MinAppPositiveMecSpeedUnit; /*!< Application minimum positive value + of the rotor mechanical speed. Expressed in + the unit defined by #SPEED_UNIT.*/ + int16_t MaxAppNegativeMecSpeedUnit; /*!< Application maximum negative value + of the rotor mechanical speed. Expressed + in the unit defined by #SPEED_UNIT.*/ + int16_t MinAppNegativeMecSpeedUnit; /*!< Application minimum negative value + of the rotor mechanical speed. Expressed + in the unit defined by #SPEED_UNIT.*/ + uint16_t MaxPositiveDutyCycle; /*!< Maximum positive value of motor + torque. This value represents + actually the maximum Iq current + expressed in digit.*/ + MC_ControlMode_t ModeDefault; /*!< Default STC modality.*/ + int16_t MecSpeedRefUnitDefault; /*!< Default mechanical rotor speed + reference expressed in the unit + defined by #SPEED_UNIT.*/ + uint16_t DutyCycleRefDefault; /*!< Default pulse reference.*/ + } SpeednTorqCtrl_Handle_t; + + + + /* It initializes all the object variables */ + void STC_Init(SpeednTorqCtrl_Handle_t *pHandle, PID_Handle_t *oPI, + SpeednPosFdbk_Handle_t *oSPD); + + /* It resets the integral term of speed regulator */ + void STC_Clear(SpeednTorqCtrl_Handle_t *pHandle); + + /* Get the current mechanical rotor speed reference. Expressed in the unit defined by + * SPEED_UNIT.*/ + int16_t STC_GetMecSpeedRefUnit(SpeednTorqCtrl_Handle_t *pHandle); + + /* Get the current motor duty cycle reference. */ + uint16_t STC_GetDutyCycleRef(SpeednTorqCtrl_Handle_t *pHandle); + + /* Set the mode of the speed controller (Torque mode or Speed mode)*/ + void STC_SetControlMode(SpeednTorqCtrl_Handle_t *pHandle, MC_ControlMode_t bMode); + + /* Get the mode of the speed controller. */ + MC_ControlMode_t STC_GetControlMode(SpeednTorqCtrl_Handle_t *pHandle); + + /* Starts the execution of a ramp using new target and duration. */ + bool STC_ExecRamp(SpeednTorqCtrl_Handle_t *pHandle, int16_t hTargetFinal, + uint32_t hDurationms); + + /* It computes the new value of motor speed reference */ + uint16_t STC_CalcSpeedReference(SpeednTorqCtrl_Handle_t *pHandle); + + /* It interrupts the execution of any previous ramp command.*/ + void STC_StopRamp(SpeednTorqCtrl_Handle_t *pHandle); + + /* Get the Default mechanical rotor speed reference. Expressed in the unit defined by + * SPEED_UNIT.*/ + int16_t STC_GetMecSpeedRefUnitDefault(SpeednTorqCtrl_Handle_t *pHandle); + + /* Returns the Application maximum positive rotor mechanical speed. Expressed in the + * unit defined by SPEED_UNIT.*/ + uint16_t STC_GetMaxAppPositiveMecSpeedUnit(SpeednTorqCtrl_Handle_t *pHandle); + + /* Returns the Application minimum negative rotor mechanical speed. Expressed in the + * unit defined by SPEED_UNIT.*/ + int16_t STC_GetMinAppNegativeMecSpeedUnit(SpeednTorqCtrl_Handle_t *pHandle); + + /* Check if the settled speed ramp has been completed.*/ + bool STC_RampCompleted(SpeednTorqCtrl_Handle_t *pHandle); + + /* Stop the execution of speed ramp. */ + bool STC_StopSpeedRamp(SpeednTorqCtrl_Handle_t *pHandle); + + /* It sets in real time the speed sensor utilized by the 6step. */ + void STC_SetSpeedSensor(SpeednTorqCtrl_Handle_t *pHandle, + SpeednPosFdbk_Handle_t *oSPD); + + /* It returns the speed sensor utilized by the 6step. */ + SpeednPosFdbk_Handle_t *STC_GetSpeedSensor(SpeednTorqCtrl_Handle_t *pHandle); + + /* Force the speed reference to the current speed */ + void STC_ForceSpeedReferenceToCurrentSpeed(SpeednTorqCtrl_Handle_t *pHandle); + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* __SPEEDCTRLCLASS_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/speed_pos_fdbk.c b/src/firmware/motor/mcsdk/speed_pos_fdbk.c new file mode 100644 index 0000000000..1f4887a698 --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_pos_fdbk.c @@ -0,0 +1,363 @@ +/** + ****************************************************************************** + * @file speed_pos_fdbk.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Speed & Position Feedback component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" + +#include "firmware/motor/common_defs.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup SpeednPosFdbk Speed & Position Feedback + * + * @brief Speed & Position Feedback components of the Motor Control SDK + * + * These components provide the speed and the angular position of the rotor of a motor + * (both electrical and mechanical). + * + * Several implementations of the Speed and Position Feedback feature are provided by the + * Motor to account for the specificities of the motor used on the application: + * + * - @ref hall_speed_pos_fdbk "Hall Speed & Position Feedback" for motors with Hall effect + * sensors + * - @ref Encoder "Encoder Speed & Position Feedback" for motors with a quadrature + * encoder + * - two general purpose sensorless implementations are provided: + * @ref SpeednPosFdbk_STO_PLL "State Observer with PLL" and + * @ref STO_CORDIC_SpeednPosFdbk "State Observer with CORDIC" + * - "High Frequency Injection" for anisotropic I-PMSM motors (Not included in this + * release). + * + * @{ + */ + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief It returns the last computed rotor electrical angle, expressed in + * s16degrees. 1 s16degree = 360�/65536 + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @retval int16_t rotor electrical angle (s16degrees) + */ +__weak int16_t SPD_GetElAngle(const SpeednPosFdbk_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_POS_FBK + return ((MC_NULL == pHandle) ? 0 : pHandle->hElAngle); +#else + return (pHandle->hElAngle); +#endif +} + +/** + * @brief It returns the last computed rotor mechanical angle, expressed in + * s16degrees. Mechanical angle frame is based on parameter bElToMecRatio + * and, if occasionally provided - through function SPD_SetMecAngle - + * of a measured mechanical angle, on information computed thereof. + * @note both Hall sensor and Sensor-less do not implement either + * mechanical angle computation or acceleration computation. + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @retval int16_t rotor mechanical angle (s16degrees) + */ +__weak int32_t SPD_GetMecAngle(const SpeednPosFdbk_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_POS_FBK + return ((MC_NULL == pHandle) ? 0 : pHandle->wMecAngle); +#else + return (pHandle->wMecAngle); +#endif +} + +/** + * @brief Returns the last computed average mechanical speed, expressed in + * the unit defined by #SPEED_UNIT. + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + */ +__weak int16_t SPD_GetAvrgMecSpeedUnit(const SpeednPosFdbk_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_POS_FBK + return ((MC_NULL == pHandle) ? 0 : pHandle->hAvrMecSpeedUnit); +#else + return (pHandle->hAvrMecSpeedUnit); +#endif +} + +/** + * @brief It returns the last computed electrical speed, expressed in Dpp. + * 1 Dpp = 1 s16Degree/control Period. The control period is the period + * on which the rotor electrical angle is computed (through function + * SPD_CalcElectricalAngle). + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @retval int16_t rotor electrical speed (Dpp) + */ +__weak int16_t SPD_GetElSpeedDpp(const SpeednPosFdbk_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_POS_FBK + return ((MC_NULL == pHandle) ? 0 : pHandle->hElSpeedDpp); +#else + return (pHandle->hElSpeedDpp); +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief It returns the last instantaneous computed electrical speed, expressed in Dpp. + * 1 Dpp = 1 s16Degree/control Period. The control period is the period + * on which the rotor electrical angle is computed (through function + * SPD_CalcElectricalAngle). + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @retval int16_t rotor instantaneous electrical speed (Dpp) + */ +__weak int16_t SPD_GetInstElSpeedDpp(const SpeednPosFdbk_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_POS_FBK + return ((MC_NULL == pHandle) ? 0 : pHandle->InstantaneousElSpeedDpp); +#else + return (pHandle->InstantaneousElSpeedDpp); +#endif +} + +/** + * @brief It returns the result of the last reliability check performed. + * Reliability is measured with reference to parameters + * hMaxReliableElSpeedUnit, hMinReliableElSpeedUnit, + * bMaximumSpeedErrorsNumber and/or specific parameters of the derived + * true = sensor information is reliable + * false = sensor information is not reliable + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @retval bool sensor reliability state + */ +__weak bool SPD_Check(const SpeednPosFdbk_Handle_t *pHandle) +{ + bool SpeedSensorReliability = true; +#ifdef NULL_PTR_SPD_POS_FBK + if ((MC_NULL == pHandle) || + (pHandle->bSpeedErrorNumber == pHandle->bMaximumSpeedErrorsNumber)) +#else + if (pHandle->bSpeedErrorNumber == pHandle->bMaximumSpeedErrorsNumber) +#endif + { + SpeedSensorReliability = false; + } + return (SpeedSensorReliability); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif + +/** + * @brief This method must be called - at least - with the same periodicity + * on which speed control is executed. It computes and returns - through + * parameter pMecSpeedUnit - the rotor average mechanical speed, + * expressed in the unit defined by #SPEED_UNIT. It computes and returns + * the reliability state of the sensor; reliability is measured with + * reference to parameters hMaxReliableElSpeedUnit, hMinReliableElSpeedUnit, + * bMaximumSpeedErrorsNumber and/or specific parameters of the derived + * true = sensor information is reliable + * false = sensor information is not reliable + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @param pMecSpeedUnit pointer to int16_t, used to return the rotor average + * mechanical speed (expressed in the unit defined by #SPEED_UNIT) + * @retval none + */ +__weak bool SPD_IsMecSpeedReliable(SpeednPosFdbk_Handle_t *pHandle, + const int16_t *pMecSpeedUnit) +{ + bool SpeedSensorReliability = true; +#ifdef NULL_PTR_SPD_POS_FBK + if ((MC_NULL == pHandle) || (MC_NULL == pMecSpeedUnit)) + { + SpeedSensorReliability = false; + } + else + { +#endif + uint16_t hAbsMecSpeedUnit; + uint16_t hAbsMecAccelUnitP; + int16_t hAux; + uint8_t bSpeedErrorNumber; + uint8_t bMaximumSpeedErrorsNumber = pHandle->bMaximumSpeedErrorsNumber; + bool SpeedError = false; + + bSpeedErrorNumber = pHandle->bSpeedErrorNumber; + + /* Compute absoulte value of mechanical speed */ + if (*pMecSpeedUnit < 0) + { + hAux = -(*pMecSpeedUnit); + hAbsMecSpeedUnit = (uint16_t)hAux; + } + else + { + hAbsMecSpeedUnit = (uint16_t)(*pMecSpeedUnit); + } + + if (hAbsMecSpeedUnit > pHandle->hMaxReliableMecSpeedUnit) + { + SpeedError = true; + } + + if (hAbsMecSpeedUnit < pHandle->hMinReliableMecSpeedUnit) + { + SpeedError = true; + } + + /* Compute absoulte value of mechanical acceleration */ + if (pHandle->hMecAccelUnitP < 0) + { + hAux = -(pHandle->hMecAccelUnitP); + hAbsMecAccelUnitP = (uint16_t)hAux; + } + else + { + hAbsMecAccelUnitP = (uint16_t)pHandle->hMecAccelUnitP; + } + + if (hAbsMecAccelUnitP > pHandle->hMaxReliableMecAccelUnitP) + { + SpeedError = true; + } + + if (true == SpeedError) + { + if (bSpeedErrorNumber < bMaximumSpeedErrorsNumber) + { + bSpeedErrorNumber++; + } + } + else + { + if (bSpeedErrorNumber < bMaximumSpeedErrorsNumber) + { + bSpeedErrorNumber = 0u; + } + } + + if (bSpeedErrorNumber == bMaximumSpeedErrorsNumber) + { + SpeedSensorReliability = false; + } + + pHandle->bSpeedErrorNumber = bSpeedErrorNumber; +#ifdef NULL_PTR_SPD_POS_FBK + } +#endif + return (SpeedSensorReliability); +} + +/** + * @brief This method returns the average mechanical rotor speed expressed in + * "S16Speed". It means that:\n + * - it is zero for zero speed,\n + * - it become INT16_MAX when the average mechanical speed is equal to + * hMaxReliableMecSpeedUnit,\n + * - it becomes -INT16_MAX when the average mechanical speed is equal to + * -hMaxReliableMecSpeedUnit. + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @retval int16_t The average mechanical rotor speed expressed in "S16Speed". + */ +__weak int16_t SPD_GetS16Speed(const SpeednPosFdbk_Handle_t *pHandle) +{ + int16_t tempValue; +#ifdef NULL_PTR_SPD_POS_FBK + if (MC_NULL == pHandle) + { + tempValue = 0; + } + else + { +#endif + int32_t wAux = (int32_t)pHandle->hAvrMecSpeedUnit; + wAux *= INT16_MAX; + wAux /= (int16_t)pHandle->hMaxReliableMecSpeedUnit; + tempValue = (int16_t)wAux; +#ifdef NULL_PTR_SPD_POS_FBK + } +#endif + return (tempValue); +} + +/** + * @brief This method returns the coefficient used to transform electrical to + * mechanical quantities and viceversa. It usually coincides with motor + * pole pairs number. + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @retval uint8_t The motor pole pairs number. + */ +__weak uint8_t SPD_GetElToMecRatio(const SpeednPosFdbk_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_POS_FBK + return ((MC_NULL == pHandle) ? 0U : pHandle->bElToMecRatio); +#else + return (pHandle->bElToMecRatio); +#endif +} + +/** + * @brief This method sets the coefficient used to transform electrical to + * mechanical quantities and viceversa. It usually coincides with motor + * pole pairs number. + * @param pHandle: handler of the current instance of the SpeednPosFdbk component + * @param bPP The motor pole pairs number to be set. + */ +__weak void SPD_SetElToMecRatio(SpeednPosFdbk_Handle_t *pHandle, uint8_t bPP) +{ +#ifdef NULL_PTR_SPD_POS_FBK + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->bElToMecRatio = bPP; +#ifdef NULL_PTR_SPD_POS_FBK + } +#endif +} + + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/speed_pos_fdbk.h b/src/firmware/motor/mcsdk/speed_pos_fdbk.h new file mode 100644 index 0000000000..6feab960ad --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_pos_fdbk.h @@ -0,0 +1,148 @@ +/** + ****************************************************************************** + * @file speed_pos_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides all definitions and functions prototypes + * of the Speed & Position Feedback component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeednPosFdbk + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SPEEDNPOSFDBK_H +#define SPEEDNPOSFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +/* Already into mc_type.h */ +/* #include "stdint.h" */ +#include "mc_type.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednPosFdbk + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /** + * @brief SpeednPosFdbk handles definitions of mechanical and electrical speed, + * mechanical acceleration, mechanical and electrical angle and all constants and + * scale values for a reliable measure and computation in appropriated unit. + */ + typedef struct + { + uint8_t bSpeedErrorNumber; /*!< Number of time the average mechanical speed is not + valid. */ + uint8_t bElToMecRatio; /*!< Coefficient used to transform electrical to mechanical + quantities and viceversa. It usually coincides with + motor pole pairs number. */ + uint8_t SpeedUnit; /*!< The speed unit value is defined into mc_stm_types.h by + [SPEED_UNIT](measurement_units.md) in tenth of Hertz.*/ + uint8_t bMaximumSpeedErrorsNumber; /*!< Maximum value of not valid speed + measurements before an error is reported.*/ + int16_t hElAngle; /*!< Estimated electrical angle reported by the implemented + speed and position method. */ + int16_t hMecAngle; /*!< Instantaneous measure of rotor mechanical angle. */ + int32_t + wMecAngle; /*!< Mechanical angle frame based on coefficient #bElToMecRatio. */ + int16_t hAvrMecSpeedUnit; /*!< Average mechanical speed expressed in the unit + defined by [SPEED_UNIT](measurement_units.md). */ + int16_t + hElSpeedDpp; /*!< Instantaneous electrical speed expressed in Digit Per + control Period ([dpp](measurement_units.md)), expresses the + angular speed as the variation of the electrical angle. */ + int16_t InstantaneousElSpeedDpp; /*!< Instantaneous computed electrical speed, + expressed in [dpp](measurement_units.md). */ + int16_t hMecAccelUnitP; /*!< Average mechanical acceleration expressed in the unit + defined by #SpeedUnit, only reported with encoder + implementation */ + uint16_t + hMaxReliableMecSpeedUnit; /*!< Maximum value of measured mechanical speed that + is considered to be valid. Expressed in the unit + defined by [SPEED_UNIT](measurement_units.md). */ + uint16_t + hMinReliableMecSpeedUnit; /*!< Minimum value of measured mechanical speed that + is considered to be valid. Expressed in the unit + defined by [SPEED_UNIT](measurement_units.md).*/ + uint16_t + hMaxReliableMecAccelUnitP; /*!< Maximum value of measured acceleration that is + considered to be valid. Constant value equal to + 65535, expressed in the unit defined by + [SPEED_UNIT](measurement_units.md). */ + uint16_t hMeasurementFrequency; /*!< Frequency at which the user will request a + measurement of the rotor electrical angle. + Expressed in PWM_FREQ_SCALING * Hz. */ + uint32_t DPPConvFactor; /*!< Conversion factor (65536/#PWM_FREQ_SCALING) used to + convert measured speed from the unit defined by + [SPEED_UNIT](measurement_units.md) to + [dpp](measurement_units.md). */ + + + } SpeednPosFdbk_Handle_t; + + /** + * @brief input structure type definition for SPD_CalcAngle + */ + typedef struct + { + alphabeta_t Valfa_beta; /*!< Voltage Components in alfa beta reference frame */ + alphabeta_t Ialfa_beta; /*!< Current Components in alfa beta reference frame */ + uint16_t Vbus; /*!< Virtual Bus Voltage information */ + } Observer_Inputs_t; + + + int16_t SPD_GetElAngle(const SpeednPosFdbk_Handle_t *pHandle); + + int32_t SPD_GetMecAngle(const SpeednPosFdbk_Handle_t *pHandle); + + int16_t SPD_GetAvrgMecSpeedUnit(const SpeednPosFdbk_Handle_t *pHandle); + + int16_t SPD_GetElSpeedDpp(const SpeednPosFdbk_Handle_t *pHandle); + + int16_t SPD_GetInstElSpeedDpp(const SpeednPosFdbk_Handle_t *pHandle); + + bool SPD_Check(const SpeednPosFdbk_Handle_t *pHandle); + + bool SPD_IsMecSpeedReliable(SpeednPosFdbk_Handle_t *pHandle, + const int16_t *pMecSpeedUnit); + + int16_t SPD_GetS16Speed(const SpeednPosFdbk_Handle_t *pHandle); + + uint8_t SPD_GetElToMecRatio(const SpeednPosFdbk_Handle_t *pHandle); + + void SPD_SetElToMecRatio(SpeednPosFdbk_Handle_t *pHandle, uint8_t bPP); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* SPEEDNPOSFDBK_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/speed_potentiometer.c b/src/firmware/motor/mcsdk/speed_potentiometer.c new file mode 100644 index 0000000000..fa21f2f79a --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_potentiometer.c @@ -0,0 +1,261 @@ +/** + ****************************************************************************** + * @file speed_potentiometer.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Speed Potentiometer component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 20222 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeedPotentiometer + */ + +/* Includes ------------------------------------------------------------------*/ +#include "speed_potentiometer.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup Potentiometer + * @{ + */ + +/** @defgroup SpeedPotentiometer Speed Potentiometer + * @brief Potentiometer reading component that sets the motor + * speed reference from the potentiometer value + * + * The Speed Potentiometer component uses the services of the + * @ref Potentiometer component to read a potentiometer. Values read + * from this potentiometer are used to set the rotation speed reference + * of a motor. + * + * The state of a Speed Potentiometer component is maintained in a + * SpeedPotentiometer_Handle_t structure. To use the Speed Potentiometer component, + * a SpeedPotentiometer_Handle_t structure needs to be instanciated and initialized. + * The initialization is performed thanks to the SPDPOT_Init() function. Prior to + * calling this function, some of the fields of this structure need to be given a + * value. See the Potentiometer_Handle_t and below for more details on this. + * + * A Speed Potentiometer component sets speed references by executing speed ramps + * thanks to the STC_ExecRamp() function. Prior to doing so, the component checks + * if the motor is started (that is: if its state machine has reached the #RUN state) + * and if its control modality is [Speed](@ref MCM_SPEED_MODE). If either of these + * conditions is not met, no speed ramp is executed. + * + * In addition, a speed ramp is executed only if the value of the potentiometer at + * that time differs from the one of the previous ramp that the component filed by + * a configurable amount. This amount is gieven by the + * @ref SpeedPotentiometer_Handle_t::SpeedAdjustmentRange "SpeedAdjustmentRange" field + * of the Handle structure. + * + * The speed range accessible through the potentiometer is bounded by a minimum speed + * and a maximum speed. the minimum speed is stated at compile time in the + * @ref SpeedPotentiometer_Handle_t::MinimumSpeed "MinimumSpeed" field of the Handle + * structure. The maximum speed is deduced from the + * @ref SpeedPotentiometer_Handle_t::ConversionFactor "ConversionFactor" field thanks to + * the following formula: + * + * $$ + * MaximumSpeed = \frac{(65536 - MinimumSpeed \times ConversionFactor + * )}{ConversionFactor} + * $$ + * + * where 65536 is the maximum value that the potentiometer (the ADC actually) can produce. + * + * The @ref SpeedPotentiometer_Handle_t::MinimumSpeed "MinimumSpeed" can be set so that + * when the potentiometer is set to its minimum value, the motor stil spins. This is + * useful when the Motor Control application uses a sensorless speed and position sensing + * algorithm that cannot work below a given speed. + * + * The duration of speed ramps is controlled with the @ref + * SpeedPotentiometer_Handle_t::RampSlope "RampSlope" field of the Handle. This field + * actually sets the acceleration used to change from one speed to another. + * + * A potentiometer provides absolute values. A Speed Potentiometer component turns these + * values into either positive or negative speed references depending on the actual speed + * of the motor. So, if a motor is started with a negative speed, the references set by + * the Speed Potentiometer component targetting it will also be negative. + * + * Values measured from the potentiometer are expressed in "u16digits": these are 16-bit + * values directly read from an ADC. They need to be converted to the [speed + * unit](#SPEED_UNIT) used by the API of the motor control library in order to generatethe + * speed references for the ramps. + * + * @note In the current version of the Speed Potentiometer component, the periodic ADC + * measures **must** be performed on the Medium Frequency Task. This can be done by using + * the MC_APP_PostMediumFrequencyHook_M1() function of the @ref MCAppHooks service + * for instance. + * + * @{ + */ + +/* Public functions ----------------------------------------------------------*/ + +/** + * @brief Initializes a Speed Potentiometer component + * + * This function must be called once before the component can be used. + * + * @param pHandle Handle on the Speed Potentiometer component to initialize + */ +void SPDPOT_Init(SpeedPotentiometer_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_POT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + POT_Init(&pHandle->Pot); + + SPDPOT_Clear(pHandle); +#ifdef NULL_PTR_SPD_POT + } +#endif /* NULL_PTR_SPD_POT */ +} + +/** + * @brief Clears the state of a Speed Potentiometer component + * + * The state of the @ref Potentiometer component instance used by the + * Speed Potentiometer component is also cleared. + * + * @param pHandle Handle on the Speed Potentiometer component + */ +void SPDPOT_Clear(SpeedPotentiometer_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_POT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + POT_Clear((Potentiometer_Handle_t *)pHandle); + + pHandle->LastSpeedRefSet = (uint16_t)0; + pHandle->IsRunning = false; +#ifdef NULL_PTR_SPD_POT + } +#endif /* NULL_PTR_SPD_POT */ +} + +/** + * @brief Reads the value of the potentiometer of a Speed Potentiometer component and sets + * the rotation speed reference of the motor it targets acordingly + * + * The potentiometer handled by the Speed Potentiometer component is read. If its value + * differs from the one that was last used to set the speed reference of the motor by more + * than @ref SpeedPotentiometer_Handle_t::SpeedAdjustmentRange "SpeedAdjustmentRange", + then + * this new value is used to set a new speed reference. + * + * If the motor does not spin (it is not in the #RUN state) or if the current motor + control + * modality is not speed (#MCM_SPEED_MODE), nothing is done. + * + * This function needs to be called periodically. See the @ref Potentiometer + * documentation for more details. + + * @param pHandle Handle on the Speed Potentiometer component + */ +bool SPDPOT_Run(SpeedPotentiometer_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_SPD_POT + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + SpeednTorqCtrl_Handle_t *pSTC = pHandle->pMCI->pSTC; + + POT_TakeMeasurement((Potentiometer_Handle_t *)pHandle); + + if (MCM_SPEED_MODE == STC_GetControlMode(pSTC)) + { + if (RUN == MCI_GetSTMState(pHandle->pMCI)) + { + if (false == pHandle->IsRunning) + { + /* Making sure the potentiometer value is going to be considered. */ + pHandle->LastSpeedRefSet ^= 65535; + + /* Remember that the motor is running */ + pHandle->IsRunning = true; + } + else + { /* Nothing to do */ + } + + if (POT_ValidValueAvailable((Potentiometer_Handle_t *)pHandle)) + { + uint16_t potValue = POT_GetValue((Potentiometer_Handle_t *)pHandle); + + if (potValue <= + pHandle->LastSpeedRefSet - pHandle->SpeedAdjustmentRange || + potValue >= + pHandle->LastSpeedRefSet + pHandle->SpeedAdjustmentRange) + { + SpeednPosFdbk_Handle_t *speedHandle; + uint32_t rampDuration; + int16_t currentSpeed; + int16_t requestedSpeed; + int16_t deltaSpeed; + + speedHandle = STC_GetSpeedSensor(pSTC); + currentSpeed = SPD_GetAvrgMecSpeedUnit(speedHandle); + requestedSpeed = (int16_t)(potValue / pHandle->ConversionFactor + + pHandle->MinimumSpeed); + + deltaSpeed = (int16_t)requestedSpeed - + ((currentSpeed >= 0) ? currentSpeed : -currentSpeed); + if (deltaSpeed < 0) + deltaSpeed = -deltaSpeed; + + rampDuration = (uint32_t)deltaSpeed * 1000U / pHandle->RampSlope; + + if (currentSpeed < 0) + requestedSpeed = -requestedSpeed; + + STC_ExecRamp(pSTC, requestedSpeed, rampDuration); + + pHandle->LastSpeedRefSet = potValue; + retVal = true; + } + } + else + { /* Nothing to do */ + } + } + else + { + // + pHandle->IsRunning = false; + } + } + else + { + pHandle->IsRunning = false; + } +#ifdef NULL_PTR_SPD_POT + } +#endif /* NULL_PTR_SPD_POT */ + + return retVal; +} diff --git a/src/firmware/motor/mcsdk/speed_potentiometer.h b/src/firmware/motor/mcsdk/speed_potentiometer.h new file mode 100644 index 0000000000..88ae455b06 --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_potentiometer.h @@ -0,0 +1,129 @@ +/** + ****************************************************************************** + * @file speed_potentiometer.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains the definitions and functions prototypes for the + * Speed Potentiometer component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeedPotentiometer + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SPEED_POTENTIOMETER_H +#define SPEED_POTENTIOMETER_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mc_interface.h" +#include "firmware/motor/mcsdk/potentiometer.h" + + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup Potentiometer + * @{ + */ + + /** @addtogroup SpeedPotentiometer + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief Handle structure of a Speed Potentiometer component. + * + * A Speed Potentiometer component reads the value set on a potentiometer + * and uses it to set the rotation speed reference of a motor. To get potentiometer + * values, an instance of a Potentiometer component is used. + * + * This structure contains all the information needed for a Speed Potentiometer + * component instance to work. + * + * See the @ref SpeedPotentiometer component documentation for more details. + */ + typedef struct + { + Potentiometer_Handle_t + Pot; /**< @brief Instance of the @ref Potentiometer component used + * to read the potentiometer + * + * This structure must be set prior to calling POT_Init(). See + * the @ref Potentiometer component for all details. + */ + + MCI_Handle_t* + pMCI; /**< @brief Motor Control interface structure of the target motor + * + * This field must be set prior to calling POT_Init() + */ + uint32_t RampSlope; /**< @brief Acceleration to use when setting the speed + * reference in #SPEED_UNIT/s. + * + * This field must be set prior to calling POT_Init() + */ + uint16_t ConversionFactor; /**< @brief Factor to convert speed between u16digit + * and #SPEED_UNIT. + * + * This field must be set prior to calling POT_Init() + */ + uint16_t + SpeedAdjustmentRange; /**< @brief Represents the range used to trigger a speed + * ramp command. In u16digits + * + * This field must be set prior to calling POT_Init() + */ + uint16_t MinimumSpeed; /**< @brief Minimum settable speed expressed in #SPEED_UNIT + * + * This field must be set prior to calling POT_Init() + */ + uint16_t LastSpeedRefSet; /**< @brief Last speed reference set to the target + motor. In u16digit */ + bool IsRunning; /**< @brief Used to track the transitions of the motor to and from + the `RUN` state */ + } SpeedPotentiometer_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /* Initializes a Speed Potentiometer component */ + void SPDPOT_Init(SpeedPotentiometer_Handle_t* pHandle); + /* Clears the state of a Speed Potentiometer component */ + void SPDPOT_Clear(SpeedPotentiometer_Handle_t* pHandle); + /* Reads the value of the potentiometer of a Speed Potentiometer component and sets + * the rotation speed reference of the motor it targets acordingly */ + bool SPDPOT_Run(SpeedPotentiometer_Handle_t* pHandle); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* SPEED_POTENTIOMETER_H */ diff --git a/src/firmware/motor/mcsdk/speed_regulator_potentiometer.h b/src/firmware/motor/mcsdk/speed_regulator_potentiometer.h new file mode 100644 index 0000000000..77365f0ee9 --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_regulator_potentiometer.h @@ -0,0 +1,107 @@ +/** + ****************************************************************************** + * @file speed_regulator_potentiometer.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Speed Regulator Potentiometer component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeedRegulatorPotentiometer + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SPEEDREGULATOR_H +#define SPEEDREGULATOR_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/speed_torq_ctrl.h" +#include "firmware/motor/regular_conversion_manager.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeedRegulatorPotentiometer + * @{ + */ + + + /** + * @brief structure used for external speed regulator + * + */ + typedef struct + { + RegConv_t SpeedRegConv; + SpeednTorqCtrl_Handle_t + *pSTC; /**< Speed and torque controller object used by the Speed Regulator.*/ + uint16_t ConversionFactor; /**< Factor to convert speed between u16digit and + #SPEED_UNIT. */ + uint16_t LatestConv; /**< Contains the latest potentiometer converted value + expressed in u16digit format */ + uint16_t AvSpeedReg_d; /**< Contains the latest available average speed expressed + in u16digit */ + // uint16_t + + uint16_t LowPassFilterBW; /**< Used to configure the first order software filter + bandwidth. hLowPassFilterBW = SRP_CalcSpeedReading + call rate [Hz]/ FilterBandwidth[Hz] */ + uint16_t SpeedAdjustmentRange; /**< Represents the range used to trigger a speed + ramp command*/ + uint16_t MinimumSpeedRange; /**< Minimum settable speed expressed in u16digit*/ + uint16_t MaximumSpeedRange; /**< Maximum settable speed expressed in u16digit*/ + uint32_t RampSlope; /**< Speed variation in SPPED_UNIT/s. */ + uint16_t *aBuffer; /**< Buffer used to compute average value.*/ + uint8_t elem; /**< Number of stored elements in the average buffer.*/ + uint8_t index; /**< Index of last stored element in the average buffer.*/ + uint8_t convHandle; /**< Handle on the regular conversion */ + bool OutOfSynchro; /**< Check of the matching between potentiometer setting and + measured speed */ + } SRP_Handle_t; + + /* Initializes a Speed Regulator Potentiometer component */ + void SRP_Init(SRP_Handle_t *pHandle, SpeednTorqCtrl_Handle_t *pSTC); + /* Clears a Speed Regulator Potentiometer component */ + void SRP_Clear(SRP_Handle_t *pHandle); + /* Reads the potentiometer of an SRP component to compute an average speed reference + */ + bool SRP_CalcAvSpeedReg(SRP_Handle_t *pHandle); + /* Reads the potentiometer of an SRP component and filters it to compute an average + * speed reference */ + bool SRP_CalcAvSpeedRegFilt(SRP_Handle_t *pHandle); + bool SRP_ExecPotRamp(SRP_Handle_t *pHandle); + bool SRP_CheckSpeedRegSync(SRP_Handle_t *pHandle); + uint16_t SRP_GetSpeedReg_d(SRP_Handle_t *pHandle); + uint16_t SRP_GetAvSpeedReg_d(SRP_Handle_t *pHandle); + uint16_t SRP_GetAvSpeedReg_SU(SRP_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* SPEEDREGULATOR_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/speed_torq_ctrl.c b/src/firmware/motor/mcsdk/speed_torq_ctrl.c new file mode 100644 index 0000000000..954ad31d30 --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_torq_ctrl.c @@ -0,0 +1,727 @@ +/** + ****************************************************************************** + * @file speed_torq_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the following features + * of the Speed & Torque Control component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeednTorqCtrl + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/speed_torq_ctrl.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" + +#define CHECK_BOUNDARY + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup SpeednTorqCtrl Speed & Torque Control + * @brief Speed & Torque Control component of the Motor Control SDK + * + * The MCSDK is able to control the startup phase of the motor in a torque Mode. + * In this case the STC component will be used to manage a torque reference and a torque + * ramp. + * + * @{ + */ + +/** + * @brief Initializes all the object variables. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @param pPI: the PI object used as controller for the speed regulation. + * It can be equal to MC_NULL if the STC is initialized in torque mode + * and it will never be configured in speed mode. + * @param SPD_Handle: the speed sensor used to perform the speed regulation. + * It can be equal to MC_NULL if the STC is used only in torque mode. + * @retval none. + * + * - Called once right after object creation at initialization of the whole MC core. + */ +__weak void STC_Init(SpeednTorqCtrl_Handle_t *pHandle, PID_Handle_t *pPI, + SpeednPosFdbk_Handle_t *SPD_Handle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->PISpeed = pPI; + pHandle->SPD = SPD_Handle; + pHandle->Mode = pHandle->ModeDefault; + pHandle->SpeedRefUnitExt = ((int32_t)pHandle->MecSpeedRefUnitDefault) * 65536; + pHandle->TorqueRef = ((int32_t)pHandle->TorqueRefDefault) * 65536; + pHandle->TargetFinal = 0; + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif +} + +/** + * @brief Sets in real time the speed sensor utilized by the STC. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @param SPD_Handle Speed sensor component to be set. + * @retval none + * + * - Called during tasks execution of the MC state machine into MediumFrequencyTask. + */ +__weak void STC_SetSpeedSensor(SpeednTorqCtrl_Handle_t *pHandle, + SpeednPosFdbk_Handle_t *SPD_Handle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->SPD = SPD_Handle; +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif +} + +/** + * @brief Returns the speed sensor utilized by the FOC. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval SpeednPosFdbk_Handle_t speed sensor utilized by the FOC. + * + * - Called as soon as component parameters are required by MC FW. + */ +__weak SpeednPosFdbk_Handle_t *STC_GetSpeedSensor(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + return ((MC_NULL == pHandle) ? MC_NULL : pHandle->SPD); +#else + return (pHandle->SPD); +#endif +} + +/** + * @brief Resets the integral term of speed regulator if STC is set in speed mode. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval none. + * + * - Called before each motor restart. + */ +__weak void STC_Clear(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (MCM_SPEED_MODE == pHandle->Mode) + { + PID_SetIntegralTerm(pHandle->PISpeed, 0); + } +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif +} + +/** + * @brief Gets the current mechanical rotor speed reference + * @ref SpeednTorqCtrl_Handle_t::SpeedRefUnitExt "SpeedRefUnitExt" expressed in + * the unit defined by [SPEED_UNIT](measurement_units.md). + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval int16_t current mechanical rotor speed reference expressed in + * the unit defined by [SPEED_UNIT](measurement_units.md). + * + * - Called at MC boot procedure and for speed monitoring through MotorPilote. + */ +__weak int16_t STC_GetMecSpeedRefUnit(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifndef FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL +#ifdef NULL_PTR_SPD_TRQ_CTL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + return ((MC_NULL == pHandle) ? 0 : (int16_t)(pHandle->SpeedRefUnitExt >> 16)); +#else + return ((int16_t)(pHandle->SpeedRefUnitExt >> 16)); +#endif +#else +#ifdef NULL_PTR_SPD_TRQ_CTL + return ((MC_NULL == pHandle) ? 0 : (int16_t)(pHandle->SpeedRefUnitExt / 65536)); +#else + return ((int16_t)(pHandle->SpeedRefUnitExt / 65536)); +#endif +#endif +} + +/** + * @brief Gets the current motor torque reference + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval int16_t current motor torque reference. This value represents + * actually the Iq current expressed in digit. + * + * - @ref SpeednTorqCtrl_Handle_t::TorqueRef "TorqueRef" represents + * actually the Iq current reference expressed in digit. + * - To convert current expressed in digit to current expressed in Amps + * is possible to use the formula:\n + * Current(Amp) = [Current(digit) * Vdd micro] / [65536 * Rshunt * Aop] + * - Called during #STC_ExecRamp execution. + */ +__weak int16_t STC_GetTorqueRef(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifndef FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL +#ifdef NULL_PTR_SPD_TRQ_CTL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + return ((MC_NULL == pHandle) ? 0 : (int16_t)(pHandle->TorqueRef >> 16)); +#else + return ((int16_t)(pHandle->TorqueRef >> 16)); +#endif +#else +#ifdef NULL_PTR_SPD_TRQ_CTL + return ((MC_NULL == pHandle) ? 0 : (int16_t)(pHandle->TorqueRef / 65536)); +#else + return ((int16_t)(pHandle->TorqueRef / 65536)); +#endif +#endif +} + +/** + * @brief Sets the modality of the speed and torque controller + * @ref SpeednTorqCtrl_Handle_t::Mode "Mode". + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @param bMode: modality of STC. It can be one of these two settings: + * MCM_TORQUE_MODE to enable the Torque mode or MCM_SPEED_MODE to + * enable the Speed mode. + * @retval none + * + * - Two modality are available Torque mode and Speed mode.\n + * -- In Torque mode is possible to set directly the motor torque + * reference or execute a motor torque ramp. This value represents + * actually the Iq current reference expressed in digit.\n + * -- In Speed mode is possible to set the mechanical rotor speed + * reference or execute a speed ramp. The required motor torque is + * automatically calculated by the STC.\n + * - Interrupts the execution of any previous ramp command + * maintaining the last value of Iq by clearing + * @ref SpeednTorqCtrl_Handle_t::RampRemainingStep "RampRemainingStep". + * - Called generally before Starting the execution of a ramp. + */ +__weak void STC_SetControlMode(SpeednTorqCtrl_Handle_t *pHandle, MC_ControlMode_t bMode) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->Mode = bMode; + pHandle->RampRemainingStep = 0u; /* Interrupts previous ramp. */ +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif +} + +/** + * @brief Gets the modality of the speed and torque controller + * @ref SpeednTorqCtrl_Handle_t::Mode "Mode". + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval MC_ControlMode_t modality of STC. It can be one of + * these two values: MCM_TORQUE_MODE or MCM_SPEED_MODE. + * + * - Called by @ref SpeedRegulatorPotentiometer Speed potentiometer component to manage + * new speed reference. + */ +__weak MC_ControlMode_t STC_GetControlMode(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + return ((MC_NULL == pHandle) ? MCM_TORQUE_MODE : pHandle->Mode); +#else + return (pHandle->Mode); +#endif +} + +/** + * @brief Starts the execution of a ramp using new target and duration. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @param hTargetFinal: final value of command. This is different accordingly + * the STC modality. + * If STC is in Torque mode hTargetFinal is the value of motor torque + * reference at the end of the ramp. This value represents actually the + * Iq current expressed in digit. + * To convert current expressed in Amps to current expressed in digit + * is possible to use the formula:\n + * Current(digit) = [Current(Amp) * 65536 * Rshunt * Aop] / Vdd micro\n + * If STC is in Speed mode hTargetFinal is the value of mechanical + * rotor speed reference at the end of the ramp expressed in the unit + * defined by [SPEED_UNIT](measurement_units.md). + * @param hDurationms: the duration of the ramp expressed in milliseconds. It + * is possible to set 0 to perform an instantaneous change in the value. + * @retval bool returning false if the absolute value of hTargetFinal is out of + * the boundary of the application (Above max application speed or max + * application torque or below min application speed depending on + * current modality of TSC) in this case the command is ignored and the + * previous ramp is not interrupted, otherwise it returns true. + * + * - This command interrupts the execution of any previous ramp command. + * The generated ramp will be in the modality previously set by + * #STC_SetControlMode method. + * - Called during @ref motor profiling, @ref RevUpCtrl "Rev-Up Control" phase, + * @ref EncAlignCtrl "Encoder Alignment Control", + * @ref PositionControl "Position Control" loop or + * speed regulation with @ref SpeedRegulatorPotentiometer Speed potentiometer. + */ +__weak bool STC_ExecRamp(SpeednTorqCtrl_Handle_t *pHandle, int16_t hTargetFinal, + uint32_t hDurationms) +{ + bool allowedRange = true; +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + allowedRange = false; + } + else + { +#endif + uint32_t wAux; + int32_t wAux1; + int16_t hCurrentReference; + + /* Check if the hTargetFinal is out of the bound of application. */ + if (MCM_TORQUE_MODE == pHandle->Mode) + { + hCurrentReference = STC_GetTorqueRef(pHandle); +#ifdef CHECK_BOUNDARY + if ((int32_t)hTargetFinal > (int32_t)pHandle->MaxPositiveTorque) + { + allowedRange = false; + } + if ((int32_t)hTargetFinal < (int32_t)pHandle->MinNegativeTorque) + { + allowedRange = false; + } +#endif + } + else + { +#ifndef FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hCurrentReference = (int16_t)(pHandle->SpeedRefUnitExt >> 16); +#else + hCurrentReference = (int16_t)(pHandle->SpeedRefUnitExt / 65536); +#endif + +#ifdef CHECK_BOUNDARY + if ((int32_t)hTargetFinal > (int32_t)pHandle->MaxAppPositiveMecSpeedUnit) + { + allowedRange = false; + } + else if (hTargetFinal < pHandle->MinAppNegativeMecSpeedUnit) + { + allowedRange = false; + } + else if ((int32_t)hTargetFinal < (int32_t)pHandle->MinAppPositiveMecSpeedUnit) + { + if (hTargetFinal > pHandle->MaxAppNegativeMecSpeedUnit) + { + allowedRange = false; + } + } + else + { + /* Nothing to do */ + } +#endif + } + + if (true == allowedRange) + { + /* Interrupts the execution of any previous ramp command */ + if (0U == hDurationms) + { + if (MCM_SPEED_MODE == pHandle->Mode) + { + pHandle->SpeedRefUnitExt = ((int32_t)hTargetFinal) * 65536; + } + else + { + pHandle->TorqueRef = ((int32_t)hTargetFinal) * 65536; + } + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; + } + else + { + /* Store the hTargetFinal to be applied in the last step */ + pHandle->TargetFinal = hTargetFinal; + + /* Compute the (wRampRemainingStep) number of steps remaining to complete + the ramp. */ + wAux = ((uint32_t)hDurationms) * ((uint32_t)pHandle->STCFrequencyHz); + wAux /= 1000U; + pHandle->RampRemainingStep = wAux; + pHandle->RampRemainingStep++; + + /* Compute the increment/decrement amount (wIncDecAmount) to be applied to + the reference value at each CalcTorqueReference. */ + wAux1 = (((int32_t)hTargetFinal) - ((int32_t)hCurrentReference)) * 65536; + wAux1 /= ((int32_t)pHandle->RampRemainingStep); + pHandle->IncDecAmount = wAux1; + } + } +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif + return (allowedRange); +} + +/** + * @brief Interrupts the execution of any previous ramp command in particular by clearing + * the number of steps remaining to complete the ramp + * @ref SpeednTorqCtrl_Handle_t::RampRemainingStep "RampRemainingStep". + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval none + * + * - If STC has been set in Torque mode the last value of Iq is maintained.\n + * - If STC has been set in Speed mode the last value of mechanical + * rotor speed reference is maintained. + * - Called by MCI_StopSpeedRamp execution command. + */ +__weak void STC_StopRamp(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->RampRemainingStep = 0U; + pHandle->IncDecAmount = 0; +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif +} + +/** + * @brief Computes the new value of motor torque reference. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval int16_t motor torque reference. This value represents actually the + * Iq current expressed in digit. + * To convert current expressed in Amps to current expressed in digit + * is possible to use the formula:\n + * Current(digit) = [Current(Amp) * 65536 * Rshunt * Aop] / Vdd micro + * + * - Must be called at fixed time equal to hSTCFrequencyHz. It is called + * passing as parameter the speed sensor used to perform the speed regulation. + * - Called during START and ALIGNEMENT states of the MC state machine into + * MediumFrequencyTask. + */ +__weak int16_t STC_CalcTorqueReference(SpeednTorqCtrl_Handle_t *pHandle) +{ + int16_t hTorqueReference; +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + hTorqueReference = 0; + } + else + { +#endif + int32_t wCurrentReference; + int16_t hMeasuredSpeed; + int16_t hTargetSpeed; + int16_t hError; + + if (MCM_TORQUE_MODE == pHandle->Mode) + { + wCurrentReference = pHandle->TorqueRef; + } + else + { + wCurrentReference = pHandle->SpeedRefUnitExt; + } + + /* Update the speed reference or the torque reference according to the mode + and terminates the ramp if needed. */ + if (pHandle->RampRemainingStep > 1U) + { + /* Increment/decrement the reference value. */ + wCurrentReference += pHandle->IncDecAmount; + + /* Decrement the number of remaining steps */ + pHandle->RampRemainingStep--; + } + else if (1U == pHandle->RampRemainingStep) + { + /* Set the backup value of hTargetFinal. */ + wCurrentReference = ((int32_t)pHandle->TargetFinal) * 65536; + pHandle->RampRemainingStep = 0U; + } + else + { + /* Do nothing. */ + } + + if (MCM_SPEED_MODE == pHandle->Mode) + { + /* Run the speed control loop */ + + /* Compute speed error */ +#ifndef FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hTargetSpeed = (int16_t)(wCurrentReference >> 16); +#else + hTargetSpeed = (int16_t)(wCurrentReference / 65536); +#endif + hMeasuredSpeed = SPD_GetAvrgMecSpeedUnit(pHandle->SPD); + hError = hTargetSpeed - hMeasuredSpeed; + hTorqueReference = PI_Controller(pHandle->PISpeed, (int32_t)hError); + + pHandle->SpeedRefUnitExt = wCurrentReference; + pHandle->TorqueRef = ((int32_t)hTorqueReference) * 65536; + } + else + { + pHandle->TorqueRef = wCurrentReference; +#ifndef FULL_MISRA_C_COMPLIANCY_SPD_TORQ_CTRL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hTorqueReference = (int16_t)(wCurrentReference >> 16); +#else + hTorqueReference = (int16_t)(wCurrentReference / 65536); +#endif + } +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif + return (hTorqueReference); +} + +/** + * @brief Gets the Default mechanical rotor speed reference + * @ref SpeednTorqCtrl_Handle_t::MecSpeedRefUnitDefault "MecSpeedRefUnitDefault" + * expressed in the unit defined by [SPEED_UNIT](measurement_units.md). + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval int16_t Default mechanical rotor speed. + * + * - It is the first command to STC after the start of speed ramp execution. + * - Called during the boot phase of the MC process. + */ +__weak int16_t STC_GetMecSpeedRefUnitDefault(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + return ((MC_NULL == pHandle) ? 0 : pHandle->MecSpeedRefUnitDefault); +#else + return (pHandle->MecSpeedRefUnitDefault); +#endif +} + +/** + * @brief Returns the Application maximum positive value of rotor speed + * @ref SpeednTorqCtrl_Handle_t::MaxAppPositiveMecSpeedUnit + * "MaxAppPositiveMecSpeedUnit". Expressed in the unit defined by + * [SPEED_UNIT](measurement_units.md). + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * + * - Not used into current implementation. + */ +__weak uint16_t STC_GetMaxAppPositiveMecSpeedUnit(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + return ((MC_NULL == pHandle) ? 0U : pHandle->MaxAppPositiveMecSpeedUnit); +#else + return (pHandle->MaxAppPositiveMecSpeedUnit); +#endif +} + +/** + * @brief Returns the Application minimum negative value of rotor speed + * @ref SpeednTorqCtrl_Handle_t::MinAppNegativeMecSpeedUnit + * "MinAppNegativeMecSpeedUnit". Expressed in the unit defined by + * [SPEED_UNIT](measurement_units.md). + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * + * - Not used into current implementation. + */ +__weak int16_t STC_GetMinAppNegativeMecSpeedUnit(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + return ((MC_NULL == pHandle) ? 0 : pHandle->MinAppNegativeMecSpeedUnit); +#else + return (pHandle->MinAppNegativeMecSpeedUnit); +#endif +} + +/** + * @brief Checks if the settled speed or torque ramp has been completed by checking zero + * value of + * @ref SpeednTorqCtrl_Handle_t::RampRemainingStep "RampRemainingStep". + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval bool returning true if the ramp is completed, false otherwise. + * + * - Called during motor profiler tuning of HALL sensor. + */ +__weak bool STC_RampCompleted(SpeednTorqCtrl_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (0U == pHandle->RampRemainingStep) + { + retVal = true; + } +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif + return (retVal); +} + +/** + * @brief Stops the execution of speed ramp by clearing the number of steps remaining to + * complete the ramp. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval bool returning true if the command is executed, false otherwise. + * + * - Not used into current implementation. + */ +__weak bool STC_StopSpeedRamp(SpeednTorqCtrl_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + if (MCM_SPEED_MODE == pHandle->Mode) + { + pHandle->RampRemainingStep = 0u; + retVal = true; + } +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif + return (retVal); +} + +/** + * @brief Returns the default values of Iqdref. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval default values of Iqdref. + * + * - Called during the boot phase of the MC process. + */ +__weak qd_t STC_GetDefaultIqdref(SpeednTorqCtrl_Handle_t *pHandle) +{ + qd_t IqdRefDefault; +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + IqdRefDefault.q = 0; + IqdRefDefault.d = 0; + } + else + { +#endif + IqdRefDefault.q = pHandle->TorqueRefDefault; + IqdRefDefault.d = pHandle->IdrefDefault; +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif + return (IqdRefDefault); +} + +/** + * @brief Changes the nominal current by setting new values of + * @ref SpeednTorqCtrl_Handle_t::MaxPositiveTorque "MaxPositiveTorque" and + * @ref SpeednTorqCtrl_Handle_t::MinNegativeTorque "MinNegativeTorque". + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @param hNominalCurrent: represents actually the maximum Iq current expressed in digit. + * @retval none + * + * - Not used into current implementation. + */ +__weak void STC_SetNominalCurrent(SpeednTorqCtrl_Handle_t *pHandle, + uint16_t hNominalCurrent) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->MaxPositiveTorque = hNominalCurrent; + pHandle->MinNegativeTorque = -(int16_t)hNominalCurrent; +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif +} + +/** + * @brief Forces the speed reference + * @ref SpeednTorqCtrl_Handle_t::SpeedRefUnitExt "SpeedRefUnitExt" to the current + * speed. + * @param pHandle: handler of the current instance of the SpeednTorqCtrl component. + * @retval none + * + * - Called during the CHARGE_BOOT_CAP, SWITCH_OVER and WAIT_STOP_MOTOR states of the MC + * state machine into MediumFrequencyTask to initialize the speed reference. + */ +__weak void STC_ForceSpeedReferenceToCurrentSpeed(SpeednTorqCtrl_Handle_t *pHandle) +{ +#ifdef NULL_PTR_SPD_TRQ_CTL + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->SpeedRefUnitExt = + ((int32_t)SPD_GetAvrgMecSpeedUnit(pHandle->SPD)) * (int32_t)65536; +#ifdef NULL_PTR_SPD_TRQ_CTL + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/speed_torq_ctrl.h b/src/firmware/motor/mcsdk/speed_torq_ctrl.h new file mode 100644 index 0000000000..95b1faa1bb --- /dev/null +++ b/src/firmware/motor/mcsdk/speed_torq_ctrl.h @@ -0,0 +1,182 @@ +/** + ****************************************************************************** + * @file speed_torq_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Speed & Torque Control component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeednTorqCtrl + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef SPEEDNTORQCTRLCLASS_H +#define SPEEDNTORQCTRLCLASS_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "mc_type.h" +#include "pid_regulator.h" +#include "speed_pos_fdbk.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednTorqCtrl + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief Speed & Torque Control parameters definition + */ + typedef struct + { + MC_ControlMode_t Mode; /*!< Modality of STC. It can be one of these two settings: + MCM_TORQUE_MODE to enable the Torque mode or + MCM_SPEED_MODE to enable the Speed mode. */ + int16_t + TargetFinal; /*!< Backup of #hTargetFinal to be applied in the last step. */ + int32_t SpeedRefUnitExt; /*!< Current mechanical rotor speed reference expressed + in [SPEED_UNIT](measurement_units.md) multiplied by + 65536.*/ + int32_t + TorqueRef; /*!< Current motor torque reference. This value represents actually + the Iq current expressed in digit multiplied by 65536. */ + uint32_t + RampRemainingStep; /*!< Number of steps remaining to complete the ramp. */ + PID_Handle_t + *PISpeed; /*!< The regulator used to perform the speed control loop. */ + SpeednPosFdbk_Handle_t + *SPD; /*!< The speed sensor used to perform the speed regulation. */ + int32_t IncDecAmount; /*!< Increment/decrement amount to be applied to the + reference value at each #CalcTorqueReference. */ + uint16_t + STCFrequencyHz; /*!< Frequency on which the user updates the torque reference + calling #STC_CalcTorqueReference method expressed in Hz */ + uint16_t MaxAppPositiveMecSpeedUnit; /*!< Application maximum positive value of + the rotor mechanical speed. Expressed in + the unit defined by + [SPEED_UNIT](measurement_units.md). */ + uint16_t MinAppPositiveMecSpeedUnit; /*!< Application minimum positive value of + the rotor mechanical speed. Expressed in + the unit defined by + [SPEED_UNIT](measurement_units.md). */ + int16_t MaxAppNegativeMecSpeedUnit; /*!< Application maximum negative value of the + rotor mechanical speed. Expressed in the + unit defined by + [SPEED_UNIT](measurement_units.md). */ + int16_t MinAppNegativeMecSpeedUnit; /*!< Application minimum negative value of the + rotor mechanical speed. Expressed in the + unit defined by + [SPEED_UNIT](measurement_units.md). */ + uint16_t MaxPositiveTorque; /*!< Maximum positive value of motor torque. This + value represents actually the maximum Iq current + expressed in digit. */ + int16_t MinNegativeTorque; /*!< Minimum negative value of motor torque. This value + represents actually the maximum Iq current expressed + in digit. */ + MC_ControlMode_t ModeDefault; /*!< Default STC modality. */ + int16_t MecSpeedRefUnitDefault; /*!< Default mechanical rotor speed reference + expressed in the unit defined by + [SPEED_UNIT](measurement_units.md). */ + int16_t + TorqueRefDefault; /*!< Default motor torque reference. This value represents + actually the Iq current reference expressed in digit. */ + int16_t IdrefDefault; /*!< Default Id current reference expressed in digit. */ + } SpeednTorqCtrl_Handle_t; + + + + /* Initializes all the object variables. */ + void STC_Init(SpeednTorqCtrl_Handle_t *pHandle, PID_Handle_t *pPI, + SpeednPosFdbk_Handle_t *SPD_Handle); + + /* Resets the integral term of speed regulator. */ + void STC_Clear(SpeednTorqCtrl_Handle_t *pHandle); + + /* Gets the current mechanical rotor speed reference. */ + int16_t STC_GetMecSpeedRefUnit(SpeednTorqCtrl_Handle_t *pHandle); + + /* Gets the current motor torque reference. */ + int16_t STC_GetTorqueRef(SpeednTorqCtrl_Handle_t *pHandle); + + /* Sets the mode of the speed and torque controller (Torque mode or Speed mode). */ + void STC_SetControlMode(SpeednTorqCtrl_Handle_t *pHandle, MC_ControlMode_t bMode); + + /* Gets the mode of the speed and torque controller. */ + MC_ControlMode_t STC_GetControlMode(SpeednTorqCtrl_Handle_t *pHandle); + + /* Starts the execution of a ramp using new target and duration. */ + bool STC_ExecRamp(SpeednTorqCtrl_Handle_t *pHandle, int16_t hTargetFinal, + uint32_t hDurationms); + + /* Interrupts the execution of any previous ramp command.*/ + void STC_StopRamp(SpeednTorqCtrl_Handle_t *pHandle); + + /* Computes the new value of motor torque reference. */ + int16_t STC_CalcTorqueReference(SpeednTorqCtrl_Handle_t *pHandle); + + /* Gets the Default mechanical rotor speed reference. */ + int16_t STC_GetMecSpeedRefUnitDefault(SpeednTorqCtrl_Handle_t *pHandle); + + /* Returns the Application maximum positive rotor mechanical speed. */ + uint16_t STC_GetMaxAppPositiveMecSpeedUnit(SpeednTorqCtrl_Handle_t *pHandle); + + /* Returns the Application minimum negative rotor mechanical speed. */ + int16_t STC_GetMinAppNegativeMecSpeedUnit(SpeednTorqCtrl_Handle_t *pHandle); + + /* Checks if the settled speed or torque ramp has been completed. */ + bool STC_RampCompleted(SpeednTorqCtrl_Handle_t *pHandle); + + /* Stops the execution of speed ramp. */ + bool STC_StopSpeedRamp(SpeednTorqCtrl_Handle_t *pHandle); + + /* Sets in real time the speed sensor utilized by the FOC. */ + void STC_SetSpeedSensor(SpeednTorqCtrl_Handle_t *pHandle, + SpeednPosFdbk_Handle_t *SPD_Handle); + + /* Returns the speed sensor utilized by the FOC. */ + SpeednPosFdbk_Handle_t *STC_GetSpeedSensor(SpeednTorqCtrl_Handle_t *pHandle); + + /* It returns the default values of Iqdref. */ + qd_t STC_GetDefaultIqdref(SpeednTorqCtrl_Handle_t *pHandle); + + /*Sets the nominal current. */ + void STC_SetNominalCurrent(SpeednTorqCtrl_Handle_t *pHandle, + uint16_t hNominalCurrent); + + /* Forces the speed reference to the current speed. */ + void STC_ForceSpeedReferenceToCurrentSpeed(SpeednTorqCtrl_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* SPEEDNTORQCTRLCLASS_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/sto_cordic_speed_pos_fdbk.c b/src/firmware/motor/mcsdk/sto_cordic_speed_pos_fdbk.c new file mode 100644 index 0000000000..543617b141 --- /dev/null +++ b/src/firmware/motor/mcsdk/sto_cordic_speed_pos_fdbk.c @@ -0,0 +1,1195 @@ +/** + ****************************************************************************** + * @file sto_cordic_speed_pos_fdbk.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the State Observer + CORDIC Speed & Position Feedback component of the + * Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/sto_cordic_speed_pos_fdbk.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mc_math.h" +#include "firmware/motor/mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup SpeednPosFdbk + * @{ + */ + +/** @defgroup STO_CORDIC_SpeednPosFdbk State Observer CORDIC Speed & Position Feedback + * @brief State Observer with CORDIC Speed & Position Feedback implementation + * + * This component uses a State Observer coupled with a CORDIC (COordinate Rotation DIgital + * Computer) to provide an estimation of the speed and the position of the rotor of the + * motor. + * + * @todo Document the State Observer + CORDIC Speed & Position Feedback "module". + * + * @{ + */ + +/* Private defines -----------------------------------------------------------*/ + +#define C6_COMP_CONST1 (int32_t)1043038 +#define C6_COMP_CONST2 (int32_t)10430 + +/* Private functions prototypes ----------------------------------------------*/ +static void STO_CR_Store_Rotor_Speed(STO_CR_Handle_t *pHandle, int16_t hRotor_Speed, + int16_t hOrRotor_Speed); +static void STO_CR_InitSpeedBuffer(STO_CR_Handle_t *pHandle); + +/** + * @brief It initializes the state observer object + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval none + */ +__weak void STO_CR_Init(STO_CR_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int32_t wAux; + int16_t htempk; + + pHandle->ConsistencyCounter = pHandle->StartUpConsistThreshold; + pHandle->EnableDualCheck = true; + + wAux = (int32_t)1; + pHandle->F3POW2 = 0u; + + htempk = (int16_t)(C6_COMP_CONST1 / (pHandle->hF2)); + + while (htempk != 0) + { + htempk /= (int16_t)2; + wAux *= (int32_t)2; + pHandle->F3POW2++; + } + + pHandle->hF3 = (int16_t)wAux; + wAux = (int32_t)(pHandle->hF2) * pHandle->hF3; + pHandle->hC6 = (int16_t)(wAux / C6_COMP_CONST2); + + STO_CR_Clear(pHandle); + + /* Acceleration measurement set to zero */ + pHandle->_Super.hMecAccelUnitP = 0; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief This method executes Luenberger state observer equations and calls + * CORDIC with the purpose of computing a new speed estimation and + * updating the estimated electrical angle. + * @param pHandle: handler of the current instance of the STO CORDIC component + * pInputs pointer to the observer inputs structure + * @retval int16_t rotor electrical angle (s16Degrees) + */ +__weak int16_t STO_CR_CalcElAngle(STO_CR_Handle_t *pHandle, Observer_Inputs_t *pInputs) +{ + int16_t returnvalue; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if ((NULL == pHandle) || (NULL == pInputs)) + { + returnvalue = 0; + } + else + { +#endif + int32_t wAux, wDirection; + int32_t wAux_Alpha, wAux_Beta; + int32_t wIalfa_est_Next, wIbeta_est_Next; + int32_t wBemf_alfa_est_Next, wBemf_beta_est_Next; + int16_t hAux, hAux_Alfa, hAux_Beta, hIalfa_err, hIbeta_err, hRotor_Speed, + hOrRotor_Speed, hRotor_Acceleration, hRotor_Angle, hValfa, hVbeta; + + int16_t hPrev_Rotor_Angle = pHandle->_Super.hElAngle; + int16_t hPrev_Rotor_Speed = pHandle->_Super.hElSpeedDpp; + int16_t hMax_Instant_Accel = pHandle->MaxInstantElAcceleration; + + if (pHandle->wBemf_alfa_est > ((int32_t)pHandle->hF2 * INT16_MAX)) + { + pHandle->wBemf_alfa_est = INT16_MAX * (int32_t)(pHandle->hF2); + } + else if (pHandle->wBemf_alfa_est <= (-INT16_MAX * (int32_t)(pHandle->hF2))) + { + pHandle->wBemf_alfa_est = -INT16_MAX * (int32_t)(pHandle->hF2); + } + else + { + /* Nothing to do */ + } +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hAux_Alfa = (int16_t)(pHandle->wBemf_alfa_est >> pHandle->F2LOG); +#else + hAux_Alfa = (int16_t)(pHandle->wBemf_alfa_est / pHandle->hF2); +#endif + + if (pHandle->wBemf_beta_est > (INT16_MAX * (int32_t)(pHandle->hF2))) + { + pHandle->wBemf_beta_est = INT16_MAX * (int32_t)(pHandle->hF2); + } + else if (pHandle->wBemf_beta_est <= (-INT16_MAX * (int32_t)(pHandle->hF2))) + { + pHandle->wBemf_beta_est = -INT16_MAX * (int32_t)(pHandle->hF2); + } + else + { + /* Nothing to do */ + } +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hAux_Beta = (int16_t)(pHandle->wBemf_beta_est >> pHandle->F2LOG); +#else + hAux_Beta = (int16_t)(pHandle->wBemf_beta_est / pHandle->hF2); +#endif + + if (pHandle->Ialfa_est > (INT16_MAX * (int32_t)(pHandle->hF1))) + { + pHandle->Ialfa_est = INT16_MAX * (int32_t)(pHandle->hF1); + } + else if (pHandle->Ialfa_est <= (-INT16_MAX * (int32_t)(pHandle->hF1))) + { + pHandle->Ialfa_est = -INT16_MAX * (int32_t)(pHandle->hF1); + } + else + { + /* Nothing to do */ + } + + if (pHandle->Ibeta_est > (INT16_MAX * (int32_t)(pHandle->hF1))) + { + pHandle->Ibeta_est = INT16_MAX * (int32_t)(pHandle->hF1); + } + else if (pHandle->Ibeta_est <= (-INT16_MAX * (int32_t)(pHandle->hF1))) + { + pHandle->Ibeta_est = -INT16_MAX * (int32_t)(pHandle->hF1); + } + else + { + /* Nothing to do */ + } + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hIalfa_err = (int16_t)(pHandle->Ialfa_est >> pHandle->F1LOG); +#else + hIalfa_err = (int16_t)(pHandle->Ialfa_est / pHandle->hF1); +#endif + + hIalfa_err = hIalfa_err - pInputs->Ialfa_beta.alpha; + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hIbeta_err = (int16_t)(pHandle->Ibeta_est >> pHandle->F1LOG); +#else + hIbeta_err = (int16_t)(pHandle->Ibeta_est / pHandle->hF1); +#endif + + hIbeta_err = hIbeta_err - pInputs->Ialfa_beta.beta; + + wAux = (int32_t)(pInputs->Vbus) * pInputs->Valfa_beta.alpha; +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + hValfa = (int16_t)(wAux >> 16); // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 +#else + hValfa = (int16_t)(wAux / 65536); +#endif + + wAux = (int32_t)(pInputs->Vbus) * pInputs->Valfa_beta.beta; + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + hVbeta = (int16_t)(wAux >> 16); // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 +#else + hVbeta = (int16_t)(wAux / 65536); +#endif + + /*alfa axes observer*/ +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hAux = (int16_t)(pHandle->Ialfa_est >> pHandle->F1LOG); +#else + hAux = (int16_t)(pHandle->Ialfa_est / pHandle->hF1); +#endif + + wAux = (int32_t)(pHandle->hC1) * hAux; + wIalfa_est_Next = pHandle->Ialfa_est - wAux; + + wAux = (int32_t)(pHandle->hC2) * hIalfa_err; + wIalfa_est_Next += wAux; + + wAux = (int32_t)(pHandle->hC5) * hValfa; + wIalfa_est_Next += wAux; + + wAux = (int32_t)(pHandle->hC3) * hAux_Alfa; + wIalfa_est_Next -= wAux; + + wAux = (int32_t)(pHandle->hC4) * hIalfa_err; + wBemf_alfa_est_Next = pHandle->wBemf_alfa_est + wAux; + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wAux = (int32_t)hAux_Beta >> pHandle->F3POW2; +#else + wAux = (int32_t)hAux_Beta / pHandle->hF3; +#endif + + wAux = wAux * pHandle->hC6; + wAux = hPrev_Rotor_Speed * wAux; + wBemf_alfa_est_Next += wAux; + + /*beta axes observer*/ +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hAux = (int16_t)(pHandle->Ibeta_est >> pHandle->F1LOG); +#else + hAux = (int16_t)(pHandle->Ibeta_est / pHandle->hF1); +#endif + + wAux = (int32_t)(pHandle->hC1) * hAux; + wIbeta_est_Next = pHandle->Ibeta_est - wAux; + + wAux = (int32_t)(pHandle->hC2) * hIbeta_err; + wIbeta_est_Next += wAux; + + wAux = (int32_t)(pHandle->hC5) * hVbeta; + wIbeta_est_Next += wAux; + + wAux = (int32_t)(pHandle->hC3) * hAux_Beta; + wIbeta_est_Next -= wAux; + + wAux = (int32_t)(pHandle->hC4) * hIbeta_err; + wBemf_beta_est_Next = pHandle->wBemf_beta_est + wAux; + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wAux = (int32_t)hAux_Alfa >> pHandle->F3POW2; +#else + wAux = (int32_t)hAux_Alfa / pHandle->hF3; +#endif + + wAux = wAux * pHandle->hC6; + wAux = hPrev_Rotor_Speed * wAux; + wBemf_beta_est_Next -= wAux; + + if (pHandle->Orig_ElSpeedDpp >= 0) + { + wDirection = 1; + } + else + { + wDirection = -1; + } + + /*Stores observed b-emfs */ + pHandle->hBemf_alfa_est = hAux_Alfa; + pHandle->hBemf_beta_est = hAux_Beta; + + /*Calls the CORDIC blockset*/ + wAux_Alpha = pHandle->wBemf_alfa_est * wDirection; + wAux_Beta = pHandle->wBemf_beta_est * wDirection; + + hRotor_Angle = MCM_PhaseComputation(wAux_Alpha, -wAux_Beta); + + hOrRotor_Speed = (int16_t)(hRotor_Angle - hPrev_Rotor_Angle); + hRotor_Acceleration = hOrRotor_Speed - hPrev_Rotor_Speed; + + hRotor_Speed = hOrRotor_Speed; + + if (wDirection == 1) + { + if (hRotor_Speed < 0) + { + hRotor_Speed = 0; + } + else + { + if (hRotor_Acceleration > hMax_Instant_Accel) + { + hRotor_Speed = hPrev_Rotor_Speed + hMax_Instant_Accel; + + pHandle->_Super.hElAngle = hPrev_Rotor_Angle + hRotor_Speed; + } + else + { + pHandle->_Super.hElAngle = hRotor_Angle; + } + } + } + else + { + if (hRotor_Speed > 0) + { + hRotor_Speed = 0; + } + else + { + if (hRotor_Acceleration < (-hMax_Instant_Accel)) + { + hRotor_Speed = hPrev_Rotor_Speed - hMax_Instant_Accel; + + pHandle->_Super.hElAngle = hPrev_Rotor_Angle + hRotor_Speed; + } + else + { + pHandle->_Super.hElAngle = hRotor_Angle; + } + } + } + + + if (hRotor_Acceleration > hMax_Instant_Accel) + { + hOrRotor_Speed = hPrev_Rotor_Speed + hMax_Instant_Accel; + } + else if (hRotor_Acceleration < (-hMax_Instant_Accel)) + { + hOrRotor_Speed = hPrev_Rotor_Speed - hMax_Instant_Accel; + } + else + { + /* nothing to do */ + } + + + STO_CR_Store_Rotor_Speed(pHandle, hRotor_Speed, hOrRotor_Speed); + + /*storing previous values of currents and bemfs*/ + pHandle->Ialfa_est = wIalfa_est_Next; + pHandle->wBemf_alfa_est = wBemf_alfa_est_Next; + + pHandle->Ibeta_est = wIbeta_est_Next; + pHandle->wBemf_beta_est = wBemf_beta_est_Next; + returnvalue = pHandle->_Super.hElAngle; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif + return (returnvalue); +} + +/** + * @brief Computes the rotor average mechanical speed in the unit defined by + * #SPEED_UNIT and writes it in pMecSpeedUnit + * + * This method must be called - at least - with the same periodicity + * on which the speed control is executed. It computes and returns - through + * parameter pMecSpeedUnit - the rotor average mechanical speed, expressed in + * the unit defined by #SPEED_UNIT. Average is computed considering a FIFO depth + * equal to STO_CR_Handle_t::SpeedBufferSizeUnit. + * + * Moreover it also computes and returns the reliability state of the sensor, + * measured with reference to parameters STO_CR_Handle_t::Reliability_hysteresys, + * STO_CR_Handle_t::VariancePercentage and STO_CR_Handle_t::SpeedBufferSizeUnit of + * the STO_CR_Handle_t handle. + * + * @param pHandle handler of the current instance of the STO CORDIC component + * @param pMecSpeedUnit pointer to int16_t, used to return the rotor average + * mechanical speed + * @retval true if the sensor information is reliable, false otherwise + */ + +__weak bool STO_CR_CalcAvrgMecSpeedUnit(STO_CR_Handle_t *pHandle, int16_t *pMecSpeedUnit) +{ + bool bAux = false; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if ((NULL == pHandle) || (NULL == pMecSpeedUnit)) + { + /* Nothing to do */ + } + else + { +#endif + uint8_t i; + uint8_t bSpeedBufferSizeUnit = pHandle->SpeedBufferSizeUnit; + bool bIs_Speed_Reliable = false; + + int32_t wAvrSpeed_dpp = (int32_t)0; + int32_t wError, wAux, wAvrSquareSpeed; + int32_t wAvrQuadraticError = 0; + int32_t wObsBemf, wEstBemf; + int32_t wObsBemfSq = 0; + int32_t wEstBemfSq = 0; + int32_t wEstBemfSqLo; + /* false positive */ + + bool bIs_Bemf_Consistent = false; + + for (i = 0U; i < bSpeedBufferSizeUnit; i++) + { + wAvrSpeed_dpp += (int32_t)(pHandle->Speed_Buffer[i]); + } + + if ((uint8_t)0 == bSpeedBufferSizeUnit) + { + /* Nothing to do */ + } + else + { + wAvrSpeed_dpp = wAvrSpeed_dpp / (int16_t)bSpeedBufferSizeUnit; + } + + + /* value is written during init and computed + by MC Workbench and always >= 1 */ + // cstat -MISRAC2012-Rule-1.3_d + + for (i = 0U; i < bSpeedBufferSizeUnit; i++) + { + wError = (int32_t)(pHandle->Speed_Buffer[i]) - wAvrSpeed_dpp; + wError = (wError * wError); + wAvrQuadraticError += wError; + } + + + /*It computes the measurement variance */ + wAvrQuadraticError = wAvrQuadraticError / (int16_t)bSpeedBufferSizeUnit; + // cstat +MISRAC2012-Rule-1.3_d + /* The maximum variance acceptable is here calculated as a function of average + * speed */ + wAvrSquareSpeed = wAvrSpeed_dpp * wAvrSpeed_dpp; + int64_t lAvrSquareSpeed = (int64_t)(wAvrSquareSpeed)*pHandle->VariancePercentage; + wAvrSquareSpeed = lAvrSquareSpeed / (int16_t)128; + + if (wAvrQuadraticError < wAvrSquareSpeed) + { + bIs_Speed_Reliable = true; + } + else + { + /* Nothing to do */ + } + + /*Computation of Mechanical speed unit */ + wAux = wAvrSpeed_dpp * (int32_t)(pHandle->_Super.hMeasurementFrequency); + wAux = wAux * (int32_t)(pHandle->_Super.SpeedUnit); + wAux = wAux / (int32_t)(pHandle->_Super.DPPConvFactor); + wAux = wAux / (int16_t)(pHandle->_Super.bElToMecRatio); + + *pMecSpeedUnit = (int16_t)wAux; + pHandle->_Super.hAvrMecSpeedUnit = (int16_t)wAux; + + pHandle->IsSpeedReliable = bIs_Speed_Reliable; + + /*Bemf Consistency Check algorithm*/ + if (true == pHandle->EnableDualCheck) /*do algorithm if it's enabled*/ + { + /* wAux abs value */ + /* false positive */ + wAux = ((wAux < 0) ? (-wAux) : (wAux)); // cstat !MISRAC2012-Rule-14.3_b + // !RED-cond-never !RED-cmp-never + + if (wAux < (int32_t)(pHandle->MaxAppPositiveMecSpeedUnit)) + { + /*Computation of Observed back-emf*/ + wObsBemf = (int32_t)(pHandle->hBemf_alfa_est); + wObsBemfSq = wObsBemf * wObsBemf; + wObsBemf = (int32_t)(pHandle->hBemf_beta_est); + wObsBemfSq += wObsBemf * wObsBemf; + + /*Computation of Estimated back-emf*/ + wEstBemf = + (wAux * 32767) / (int16_t)(pHandle->_Super.hMaxReliableMecSpeedUnit); + wEstBemfSq = (wEstBemf * (int32_t)(pHandle->BemfConsistencyGain)) / 64; + wEstBemfSq *= wEstBemf; + + /*Computation of threshold*/ + wEstBemfSqLo = wEstBemfSq - ((wEstBemfSq / 64) * + (int32_t)(pHandle->BemfConsistencyCheck)); + + /*Check*/ + if (wObsBemfSq > wEstBemfSqLo) + { + bIs_Bemf_Consistent = true; + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do */ + } + + pHandle->IsBemfConsistent = bIs_Bemf_Consistent; + pHandle->Obs_Bemf_Level = wObsBemfSq; + pHandle->Est_Bemf_Level = wEstBemfSq; + } + else + { + bIs_Bemf_Consistent = true; + } + + /*Decision making*/ + if (pHandle->IsAlgorithmConverged == false) + { + bAux = SPD_IsMecSpeedReliable(&pHandle->_Super, pMecSpeedUnit); + } + else + { + if ((pHandle->IsSpeedReliable == false) || (bIs_Bemf_Consistent == false)) + { + pHandle->ReliabilityCounter++; + if (pHandle->ReliabilityCounter >= pHandle->Reliability_hysteresys) + { + pHandle->ReliabilityCounter = 0U; + pHandle->_Super.bSpeedErrorNumber = + pHandle->_Super.bMaximumSpeedErrorsNumber; + bAux = false; + } + else + { + bAux = SPD_IsMecSpeedReliable(&pHandle->_Super, pMecSpeedUnit); + } + } + else + { + pHandle->ReliabilityCounter = 0U; + bAux = SPD_IsMecSpeedReliable(&pHandle->_Super, pMecSpeedUnit); + } + } +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif + return (bAux); +} + +/** + * @brief It clears state observer object by re-initializing private variables + * @param pHandle pointer on the component instance to work on. + */ +__weak void STO_CR_Clear(STO_CR_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->Ialfa_est = (int32_t)0; + pHandle->Ibeta_est = (int32_t)0; + pHandle->wBemf_alfa_est = (int32_t)0; + pHandle->wBemf_beta_est = (int32_t)0; + pHandle->_Super.hElAngle = (int16_t)0; + pHandle->_Super.hElSpeedDpp = (int16_t)0; + pHandle->Orig_ElSpeedDpp = (int16_t)0; + pHandle->ConsistencyCounter = 0u; + pHandle->ReliabilityCounter = 0u; + pHandle->IsAlgorithmConverged = false; + pHandle->IsBemfConsistent = false; + pHandle->Obs_Bemf_Level = (int32_t)0; + pHandle->Est_Bemf_Level = (int32_t)0; + pHandle->DppBufferSum = (int32_t)0; + pHandle->DppOrigBufferSum = (int32_t)0; + pHandle->ForceConvergency = false; + pHandle->ForceConvergency2 = false; + + STO_CR_InitSpeedBuffer(pHandle); +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif +} + +/** + * @brief It stores in estimated speed FIFO latest calculated value of motor + * speed + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval none + */ +inline static void STO_CR_Store_Rotor_Speed(STO_CR_Handle_t *pHandle, + int16_t hRotor_Speed, int16_t hOrRotor_Speed) +{ + uint8_t bBuffer_index = pHandle->Speed_Buffer_Index; + + bBuffer_index++; + if (bBuffer_index == pHandle->SpeedBufferSizeUnit) + { + bBuffer_index = 0U; + } + else + { + /* Nothing too do */ + } + + pHandle->SpeedBufferOldestEl = pHandle->Speed_Buffer[bBuffer_index]; + pHandle->OrigSpeedBufferOldestEl = pHandle->Orig_Speed_Buffer[bBuffer_index]; + + pHandle->Speed_Buffer[bBuffer_index] = hRotor_Speed; + pHandle->Orig_Speed_Buffer[bBuffer_index] = hOrRotor_Speed; + pHandle->Speed_Buffer_Index = bBuffer_index; +} + + +/** + * @brief It clears the estimated speed buffer + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval none + */ +static void STO_CR_InitSpeedBuffer(STO_CR_Handle_t *pHandle) +{ + uint8_t b_i; + uint8_t bSpeedBufferSizeUnit = pHandle->SpeedBufferSizeUnit; + + /*init speed buffer*/ + for (b_i = 0U; b_i < bSpeedBufferSizeUnit; b_i++) + { + pHandle->Speed_Buffer[b_i] = (int16_t)0; + pHandle->Orig_Speed_Buffer[b_i] = (int16_t)0; + } + + pHandle->Speed_Buffer_Index = 0u; + pHandle->SpeedBufferOldestEl = (int16_t)0; + pHandle->OrigSpeedBufferOldestEl = (int16_t)0; +} + + +/** + * @brief Returns true if the Observer has converged or false otherwise. + * + * Internally performs a set of checks necessary to state whether + * the state observer algorithm has converged or not. + * + * This function is to be periodically called during the motor rev-up procedure + * at the same frequency as the *_CalcElAngle() functions. + * + * It returns true if the estimated angle and speed can be considered reliable, + * false otherwise. + * + * @param pHandle pointer on the component instance + * @param hForcedMecSpeedUnit Mechanical speed as forced by VSS, in the unit defined by + * #SPEED_UNIT + */ +__weak bool STO_CR_IsObserverConverged(STO_CR_Handle_t *pHandle, + int16_t hForcedMecSpeedUnit) +{ + bool bAux = false; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int32_t wAux; + int32_t wtemp; + int16_t hEstimatedSpeedUnit; + int16_t hUpperThreshold; + int16_t hLowerThreshold; + int16_t lForcedMecSpeedUnit; + + + if (pHandle->ForceConvergency2 == true) + { + lForcedMecSpeedUnit = pHandle->_Super.hAvrMecSpeedUnit; + } + else + { + lForcedMecSpeedUnit = hForcedMecSpeedUnit; + } + + if (pHandle->ForceConvergency == true) + { + bAux = true; + pHandle->IsAlgorithmConverged = true; + pHandle->_Super.bSpeedErrorNumber = 0U; + } + else + { + hEstimatedSpeedUnit = pHandle->_Super.hAvrMecSpeedUnit; + wtemp = (int32_t)hEstimatedSpeedUnit * (int32_t)lForcedMecSpeedUnit; + + if (wtemp > 0) + { + if (hEstimatedSpeedUnit < 0) + { + hEstimatedSpeedUnit = -hEstimatedSpeedUnit; + } + else + { + /* Nothing to do */ + } + + if (lForcedMecSpeedUnit < 0) + { + lForcedMecSpeedUnit = -lForcedMecSpeedUnit; + } + else + { + /* Nothing to do */ + } + + wAux = (int32_t)(lForcedMecSpeedUnit) * + (int16_t)pHandle->SpeedValidationBand_H; + hUpperThreshold = (int16_t)(wAux / (int32_t)16); + + wAux = (int32_t)(lForcedMecSpeedUnit) * + (int16_t)pHandle->SpeedValidationBand_L; + hLowerThreshold = (int16_t)(wAux / (int32_t)16); + + /* If the variance of the estimated speed is low enough...*/ + if (true == pHandle->IsSpeedReliable) + { + if ((uint16_t)hEstimatedSpeedUnit > pHandle->MinStartUpValidSpeed) + { + /*...and the estimated value is quite close to the expected + * value... */ + if (hEstimatedSpeedUnit >= hLowerThreshold) + { + if (hEstimatedSpeedUnit <= hUpperThreshold) + { + pHandle->ConsistencyCounter++; + + /*... for hConsistencyThreshold consecutive times... */ + if (pHandle->ConsistencyCounter >= + pHandle->StartUpConsistThreshold) + { + /* the algorithm converged.*/ + bAux = true; + pHandle->IsAlgorithmConverged = true; + pHandle->_Super.bSpeedErrorNumber = 0U; + } + } + else + { + pHandle->ConsistencyCounter = 0U; + } + } + else + { + pHandle->ConsistencyCounter = 0U; + } + } + else + { + pHandle->ConsistencyCounter = 0U; + } + } + else + { + pHandle->ConsistencyCounter = 0U; + } + } + } +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif + return (bAux); +} + +/* false positive */ +// cstat -MISRAC2012-Rule-2.2_b +/** + * @brief It exports estimated Bemf alpha-beta in qd_t format + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval alphabeta_t Bemf alpha-beta + */ +__weak alphabeta_t STO_CR_GetEstimatedBemf(STO_CR_Handle_t *pHandle) +{ + alphabeta_t Vaux; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + Vaux.alpha = 0; + Vaux.beta = 0; + } + else + { +#endif + Vaux.alpha = pHandle->hBemf_alfa_est; + Vaux.beta = pHandle->hBemf_beta_est; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif + return (Vaux); +} + +/** + * @brief It exports the stator current alpha-beta as estimated by state + * observer + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval alphabeta_t State observer estimated stator current Ialpha-beta + */ +__weak alphabeta_t STO_CR_GetEstimatedCurrent(STO_CR_Handle_t *pHandle) +{ + alphabeta_t Iaux; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + Iaux.alpha = 0; + Iaux.beta = 0; + } + else + { +#endif +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + Iaux.alpha = (int16_t)(pHandle->Ialfa_est >> pHandle->F1LOG); +#else + Iaux.alpha = (int16_t)(pHandle->Ialfa_est / (pHandle->hF1)); +#endif + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + Iaux.beta = (int16_t)(pHandle->Ibeta_est >> pHandle->F1LOG); +#else + Iaux.beta = (int16_t)(pHandle->Ibeta_est / (pHandle->hF1)); +#endif +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif + return (Iaux); +} +// cstat +MISRAC2012-Rule-2.2_b + +/** + * @brief It exports current observer gains through parameters hhC2 and hhC4 + * @param pHandle: handler of the current instance of the STO CORDIC component + * @param phC2 pointer to int16_t used to return parameters hhC2 + * @param phC4 pointer to int16_t used to return parameters hhC4 + * @retval none + */ +__weak void STO_CR_GetObserverGains(STO_CR_Handle_t *pHandle, int16_t *phC2, + int16_t *phC4) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if ((NULL == pHandle) || (NULL == phC2) || (NULL == phC4)) + { + /* Nothing to do */ + } + else + { +#endif + *phC2 = pHandle->hC2; + *phC4 = pHandle->hC4; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif +} + +/** + * @brief It allows setting new values for observer gains + * @param pHandle: handler of the current instance of the STO CORDIC component + * @param wK1 new value for observer gain hhC1 + * @param wK2 new value for observer gain hhC2 + * @retval none + */ +__weak void STO_CR_SetObserverGains(STO_CR_Handle_t *pHandle, int16_t hhC1, int16_t hhC2) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hC2 = hhC1; + pHandle->hC4 = hhC2; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief This method must be called - at least - with the same periodicity + * on which speed control is executed. It computes and update object + * variable hElSpeedDpp that is estimated average electrical speed + * expressed in dpp used for instance in observer equations. + * Average is computed considering a FIFO depth equal to + * bSpeedBufferSizedpp. + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval none + */ +__weak void STO_CR_CalcAvrgElSpeedDpp(STO_CR_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int32_t wSum = pHandle->DppBufferSum; + int32_t wSumOrig = pHandle->DppOrigBufferSum; + int32_t wAvrSpeed_dpp; + int16_t hSpeedBufferSizedpp = (int16_t)(pHandle->SpeedBufferSizedpp); + int16_t hSpeedBufferSizeUnit = (int16_t)(pHandle->SpeedBufferSizeUnit); + int16_t hBufferSizeDiff; + int16_t hIndexNew = (int16_t)pHandle->Speed_Buffer_Index; + int16_t hIndexOld; + int16_t hIndexOldTemp; + + hBufferSizeDiff = hSpeedBufferSizeUnit - hSpeedBufferSizedpp; + + if (0 == hBufferSizeDiff) + { + wSum = wSum + pHandle->Speed_Buffer[hIndexNew] - pHandle->SpeedBufferOldestEl; + wSumOrig = wSumOrig + pHandle->Orig_Speed_Buffer[hIndexNew] - + pHandle->OrigSpeedBufferOldestEl; + } + else + { + hIndexOldTemp = hIndexNew + hBufferSizeDiff; + + if (hIndexOldTemp >= hSpeedBufferSizeUnit) + { + hIndexOld = hIndexOldTemp - hSpeedBufferSizeUnit; + } + else + { + hIndexOld = hIndexOldTemp; + } + + wSum = wSum + pHandle->Speed_Buffer[hIndexNew] - + pHandle->Speed_Buffer[hIndexOld]; + + wSumOrig = wSumOrig + pHandle->Orig_Speed_Buffer[hIndexNew] - + pHandle->Orig_Speed_Buffer[hIndexOld]; + } + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_CORDIC + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wAvrSpeed_dpp = (int32_t)(wSum >> pHandle->SpeedBufferSizedppLOG); + pHandle->_Super.hElSpeedDpp = (int16_t)wAvrSpeed_dpp; + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wAvrSpeed_dpp = (int32_t)(wSumOrig >> pHandle->SpeedBufferSizedppLOG); +#else + if (hSpeedBufferSizedpp != 0) + { + wAvrSpeed_dpp = wSum / hSpeedBufferSizedpp; + pHandle->_Super.hElSpeedDpp = (int16_t)wAvrSpeed_dpp; + wAvrSpeed_dpp = wSumOrig / hSpeedBufferSizedpp; + } + else + { + wAvrSpeed_dpp = (int32_t)0; + } +#endif + + pHandle->Orig_ElSpeedDpp = (int16_t)wAvrSpeed_dpp; + + pHandle->DppBufferSum = wSum; + + pHandle->DppOrigBufferSum = wSumOrig; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif +} + +/** + * @brief It exports estimated Bemf squared level + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval int32_t + */ +__weak int32_t STO_CR_GetEstimatedBemfLevel(const STO_CR_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + return ((NULL == pHandle) ? 0 : pHandle->Est_Bemf_Level); +#else + return (pHandle->Est_Bemf_Level); +#endif +} + +/** + * @brief It exports observed Bemf squared level + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval int32_t + */ +__weak int32_t STO_CR_GetObservedBemfLevel(const STO_CR_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + return ((NULL == pHandle) ? 0 : pHandle->Obs_Bemf_Level); +#else + return (pHandle->Obs_Bemf_Level); +#endif +} + +/** + * @brief It enables/disables the bemf consistency check + * @param pHandle: handler of the current instance of the STO CORDIC component + * @param bSel boolean; true enables check; false disables check + */ +__weak void STO_CR_BemfConsistencyCheckSwitch(STO_CR_Handle_t *pHandle, bool bSel) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + /* Noything to do */ + } + else + { +#endif + pHandle->EnableDualCheck = bSel; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif +} + +/** + * @brief It returns the result of the Bemf consistency check + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval bool Bemf consistency state + */ +__weak bool STO_CR_IsBemfConsistent(const STO_CR_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + return ((NULL == pHandle) ? false : pHandle->IsBemfConsistent); +#else + return (pHandle->IsBemfConsistent); +#endif +} + +/** + * @brief This method returns the reliability of the speed sensor + * @param pHandle: handler of the current instance of the STO CORDIC component + * @retval bool speed sensor reliability, measured with reference to parameters + * bReliability_hysteresys, hVariancePercentage and bSpeedBufferSize + * true = sensor information is reliable + * false = sensor information is not reliable + */ +__weak bool STO_CR_IsSpeedReliable(const STO_Handle_t *pHandle) +{ + bool returnbool; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + returnbool = false; + } + else + { +#endif + const STO_CR_Handle_t *pHdl = + (STO_CR_Handle_t *)pHandle->_Super; // cstat !MISRAC2012-Rule-11.3 + returnbool = pHdl->IsSpeedReliable; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif + return (returnbool); +} + +/* @brief It forces the state-observer to declare converged + * @param pHandle: handler of the current instance of the STO CORDIC component + */ +__weak void STO_CR_ForceConvergency1(STO_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + STO_CR_Handle_t *pHdl = + (STO_CR_Handle_t *)pHandle->_Super; // cstat !MISRAC2012-Rule-11.3 + + pHdl->ForceConvergency = true; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif +} + +/* @brief It forces the state-observer to declare converged + * @param pHandle: handler of the current instance of the STO CORDIC component + */ +__weak void STO_CR_ForceConvergency2(STO_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + if (NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + STO_CR_Handle_t *pHdl = + (STO_CR_Handle_t *)pHandle->_Super; // cstat !MISRAC2012-Rule-11.3 + + pHdl->ForceConvergency2 = true; +#ifdef NULL_PTR_STO_COR_SPD_POS_FDB + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/** @} */ +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/sto_cordic_speed_pos_fdbk.h b/src/firmware/motor/mcsdk/sto_cordic_speed_pos_fdbk.h new file mode 100644 index 0000000000..fedc9e9d74 --- /dev/null +++ b/src/firmware/motor/mcsdk/sto_cordic_speed_pos_fdbk.h @@ -0,0 +1,267 @@ +/** + ****************************************************************************** + * @file sto_cordic_speed_pos_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * State Observer + CORDIC Speed & Position Feedback component of the + * Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup STO_CORDIC_SpeednPosFdbk + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STO_CORDIC_SPEEDNPOSFDBK_H +#define STO_CORDIC_SPEEDNPOSFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "speed_pos_fdbk.h" +#include "sto_speed_pos_fdbk.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednPosFdbk + * @{ + */ + + /** @addtogroup STO_CORDIC_SpeednPosFdbk + * @{ + */ + + /** + * @brief This structure is used to handle an instance of the STO_CORDIC component + */ + typedef struct + { + SpeednPosFdbk_Handle_t _Super; + int16_t hC1; /*!< State observer constant C1, it can + be computed as F1 * Rs(ohm)/(Ls[H] * + State observer execution rate [Hz])*/ + int16_t hC2; /*!< Variable containing state observer + constant C2, it can be computed as + F1 * K1/ State observer execution + rate [Hz] being K1 one of the two + observer gains */ + int16_t hC3; /*!< State observer constant C3, it can + be computed as F1 * Max application + speed [rpm] * Motor B-emf constant + [Vllrms/krpm] * sqrt(2)/ (Ls [H] * + max measurable current (A) * State + observer execution rate [Hz])*/ + int16_t hC4; /*!< State Observer constant C4, it can + be computed as K2 * max measurable + current (A) / (Max application speed + [rpm] * Motor B-emf constant + [Vllrms/krpm] * sqrt(2) * F2 * State + observer execution rate [Hz]) being + K2 one of the two observer gains */ + int16_t hC5; /*!< State Observer constant C5, it can + be computed as F1 * max measurable + voltage / (2 * Ls [Hz] * max + measurable current * State observer + execution rate [Hz]) */ + int16_t hC6; /*!< State observer constant C6, computed with a + specific procedure starting from the other + constants */ + int16_t hF1; /*!< State observer scaling factor F1 */ + int16_t hF2; /*!< State observer scaling factor F2 */ + int16_t hF3; /*!< State observer scaling factor F3 */ + uint16_t F3POW2; /*!< State observer scaling factor F3 expressed as power of 2. + E.g. if gain divisor is 512 the value + must be 9 because 2^9 = 512 */ + int32_t Ialfa_est; /*!< Estimated Ialfa current in int32 format */ + int32_t Ibeta_est; /*!< Estimated Ialfa current in int32 format */ + int32_t wBemf_alfa_est; /*!< Estimated B-emf alfa in int32_t format */ + int32_t wBemf_beta_est; /*!< Estimated B-emf beta in int32_t format */ + int16_t hBemf_alfa_est; /*!< Estimated B-emf alfa in int16_t format */ + int16_t hBemf_beta_est; /*!< Estimated B-emf beta in int16_t format */ + int16_t Speed_Buffer[64]; /*!< Estimated speed FIFO, it contains latest + bSpeedBufferSize speed measurements*/ + uint8_t Speed_Buffer_Index; /*!< Position of latest speed estimation in + estimated speed FIFO */ + bool IsSpeedReliable; /*!< Latest private speed reliability information, + updated by the *_CalcAvrgMecSpeedUnit() functions. It + is true if the speed measurement variance is + lower than the threshold corresponding + to hVariancePercentage */ + uint8_t ConsistencyCounter; /*!< Counter of passed tests for start-up + validation */ + uint8_t ReliabilityCounter; /*!< Counter for reliability check internal to + derived class */ + bool IsAlgorithmConverged; /*!< Boolean variable containing observer + convergence information */ + int16_t Orig_Speed_Buffer[64]; /*!< Estimated speed FIFO, it contains latest + bSpeedBufferSize speed measurements, cordic + outputs not modified*/ + int16_t Orig_ElSpeedDpp; + bool + IsBemfConsistent; /*!< Sensor reliability information, updated by the + *_CalcAvrgMecSpeedUnit() functions. It is true if the + observed back-emfs are consistent with expectations */ + int32_t Obs_Bemf_Level; /*!< Observed back-emf Level*/ + int32_t Est_Bemf_Level; /*!< Estimated back-emf Level*/ + bool EnableDualCheck; /*!< Consistency check enabler*/ + int32_t DppBufferSum; /*!< summation of speed buffer elements [dpp]*/ + int32_t + DppOrigBufferSum; /*!< summation of not modified speed buffer elements [dpp]*/ + int16_t SpeedBufferOldestEl; /*!< Oldest element of the speed buffer*/ + int16_t OrigSpeedBufferOldestEl; /*!< Oldest element of the not modified speed + buffer*/ + + uint8_t SpeedBufferSizeUnit; /*!< Depth of FIFO used to average + estimated speed exported by + SPD_GetAvrgMecSpeedUnit. It + must be an integer number between 1 + and 64 */ + uint8_t SpeedBufferSizedpp; /*!< Depth of FIFO used for both averaging + estimated speed exported by + SPD_GetElSpeedDpp and state + observer equations. It must be an + integer number between 1 and + SpeedBufferSizeUnit */ + uint16_t VariancePercentage; /*!< Parameter expressing the maximum + allowed variance of speed estimation + */ + uint8_t SpeedValidationBand_H; /*!< It expresses how much estimated speed + can exceed forced stator electrical + frequency during start-up without + being considered wrong. The + measurement unit is 1/16 of forced + speed */ + uint8_t SpeedValidationBand_L; /*!< It expresses how much estimated speed + can be below forced stator electrical + frequency during start-up without + being considered wrong. The + measurement unit is 1/16 of forced + speed */ + uint16_t MinStartUpValidSpeed; /*!< Minimum mechanical speed required to validate + the start-up. Expressed in the unit defined by + #SPEED_UNIT) + */ + uint8_t StartUpConsistThreshold; /*!< Number of consecutive tests on speed + consistency to be passed before + validating the start-up */ + uint8_t Reliability_hysteresys; /*!< Number of reliability failed + consecutive tests before a speed + check fault is returned to base class + */ + int16_t MaxInstantElAcceleration; /*!< maximum instantaneous electrical + acceleration (dpp per control period) */ + uint8_t BemfConsistencyCheck; /*!< Degree of consistency of the observed + back-emfs, it must be an integer + number ranging from 1 (very high + consistency) down to 64 (very poor + consistency) */ + uint8_t BemfConsistencyGain; /*!< Gain to be applied when checking + back-emfs consistency; default value + is 64 (neutral), max value 105 + (x1.64 amplification), min value 1 + (/64 attenuation) */ + uint16_t MaxAppPositiveMecSpeedUnit; /*!< Maximum positive value of rotor speed. + Expressed in the unit defined by + #SPEED_UNIT. It can be x1.1 greater than + max application speed*/ + uint16_t F1LOG; /*!< F1 gain divisor expressed as power of 2. + E.g. if gain divisor is 512 the value + must be 9 because 2^9 = 512 */ + uint16_t F2LOG; /*!< F2 gain divisor expressed as power of 2. + E.g. if gain divisor is 512 the value + must be 9 because 2^9 = 512 */ + uint16_t SpeedBufferSizedppLOG; /*!< bSpeedBufferSizedpp expressed as power of 2. + E.g. if gain divisor is 512 the value + must be 9 because 2^9 = 512 */ + bool ForceConvergency; /*!< Variable to force observer convergence.*/ + bool ForceConvergency2; /*!< Variable to force observer convergence.*/ + } STO_CR_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /* It initializes the state observer object */ + void STO_CR_Init(STO_CR_Handle_t *pHandle); + + /* It clears state observer object by re-initializing private variables*/ + void STO_CR_Clear(STO_CR_Handle_t *pHandle); + + /* It executes Luenberger state observer and calls CORDIC to compute a new speed + * estimation and update the estimated electrical angle. + */ + int16_t STO_CR_CalcElAngle(STO_CR_Handle_t *pHandle, Observer_Inputs_t *pInputs); + + /* Computes the rotor average mechanical speed in the unit defined by SPEED_UNIT and + * returns it in pMecSpeedUnit */ + bool STO_CR_CalcAvrgMecSpeedUnit(STO_CR_Handle_t *pHandle, int16_t *pMecSpeedUnit); + + /* Checks whether the state observer algorithm has converged.*/ + bool STO_CR_IsObserverConverged(STO_CR_Handle_t *pHandle, + int16_t hForcedMecSpeedUnit); + + /* It exports estimated Bemf alpha-beta in alphabeta_t format */ + alphabeta_t STO_CR_GetEstimatedBemf(STO_CR_Handle_t *pHandle); + + /* It exports the stator current alpha-beta as estimated by state observer */ + alphabeta_t STO_CR_GetEstimatedCurrent(STO_CR_Handle_t *pHandle); + + /* It exports current observer gains through parameters hC2 and hC4 */ + void STO_CR_GetObserverGains(STO_CR_Handle_t *pHandle, int16_t *phC2, int16_t *phC4); + + /* It allows setting new values for observer gains hC1 and hC2 */ + void STO_CR_SetObserverGains(STO_CR_Handle_t *pHandle, int16_t hhC1, int16_t hhC2); + + /* It computes and update the estimated average electrical speed */ + void STO_CR_CalcAvrgElSpeedDpp(STO_CR_Handle_t *pHandle); + + /* It exports estimated Bemf squared level */ + int32_t STO_CR_GetEstimatedBemfLevel(const STO_CR_Handle_t *pHandle); + + /* It exports observed Bemf squared level */ + int32_t STO_CR_GetObservedBemfLevel(const STO_CR_Handle_t *pHandle); + + /* It enables/disables the bemf consistency check */ + void STO_CR_BemfConsistencyCheckSwitch(STO_CR_Handle_t *pHandle, bool bSel); + + /* It returns the result of the Bemf consistency check */ + bool STO_CR_IsBemfConsistent(const STO_CR_Handle_t *pHandle); + + /* It returns the result of the last variance check*/ + bool STO_CR_IsSpeedReliable(const STO_Handle_t *pHandle); + + /* It set internal ForceConvergency1 to true*/ + void STO_CR_ForceConvergency1(STO_Handle_t *pHandle); + + /* It set internal ForceConvergency2 to true*/ + void STO_CR_ForceConvergency2(STO_Handle_t *pHandle); + +/** + * @} + */ + +/** + * @} + */ + +/** @} */ +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /*STO_CORDIC_SPEEDNPOSFDBK_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/sto_pll_speed_pos_fdbk.c b/src/firmware/motor/mcsdk/sto_pll_speed_pos_fdbk.c new file mode 100644 index 0000000000..5827a8a5b8 --- /dev/null +++ b/src/firmware/motor/mcsdk/sto_pll_speed_pos_fdbk.c @@ -0,0 +1,1315 @@ +/** + ****************************************************************************** + * @file sto_pll_speed_pos_fdbk.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the State Observer + PLL Speed & Position Feedback component of the + * Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeednPosFdbk_STO_PLL + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/sto_pll_speed_pos_fdbk.h" + +#include "firmware/motor/mc_math.h" + + + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup SpeednPosFdbk + * @{ + */ + +/** + * @defgroup SpeednPosFdbk_STO_PLL State Observer PLL Speed & Position Feedback + * @brief State Observer with PLL Speed & Position Feedback component of MCSDK + * + * This component uses a State Observer coupled with a software PLL to provide an + * estimation of the speed and the position of the rotor of the motor. + * + * See the [Speed & position feedback sensorless chapter of the User + * Manual](speed_pos_sensorless_bemf_reconstruction.md) for more details on the sensorless + * algorithm. + * @{ + */ + +/* Private defines -----------------------------------------------------------*/ +#define C6_COMP_CONST1 ((int32_t)1043038) +#define C6_COMP_CONST2 ((int32_t)10430) + +/* Private function prototypes -----------------------------------------------*/ +static void STO_Store_Rotor_Speed(STO_PLL_Handle_t *pHandle, int16_t hRotor_Speed); +static int16_t STO_ExecutePLL(STO_PLL_Handle_t *pHandle, int16_t hBemf_alfa_est, + int16_t hBemf_beta_est); +static void STO_InitSpeedBuffer(STO_PLL_Handle_t *pHandle); + + +/** + * @brief Initializes the @p pHandle of STate Observer (STO) PLL component. + * + */ +__weak void STO_PLL_Init(STO_PLL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int16_t htempk; + int32_t wAux; + + pHandle->ConsistencyCounter = pHandle->StartUpConsistThreshold; + pHandle->EnableDualCheck = true; + + wAux = ((int32_t)1); + pHandle->F3POW2 = 0U; + + htempk = (int16_t)(C6_COMP_CONST1 / pHandle->hF2); + + while (htempk != 0) + { + htempk /= ((int16_t)2); + wAux *= ((int32_t)2); + pHandle->F3POW2++; + } + + pHandle->hF3 = (int16_t)wAux; + wAux = ((int32_t)(pHandle->hF2)) * pHandle->hF3; + pHandle->hC6 = (int16_t)(wAux / C6_COMP_CONST2); + + STO_PLL_Clear(pHandle); + + PID_HandleInit(&pHandle->PIRegulator); + + /* Acceleration measurement set to zero */ + pHandle->_Super.hMecAccelUnitP = 0; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif + return; +} + +/** + * @brief Necessary empty return to implement fictitious IRQ_Handler. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param uint8_t: Fictitious interrupt flag. + */ +// cstat !RED-func-no-effect +__weak void STO_PLL_Return(STO_PLL_Handle_t *pHandle, uint8_t flag) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if ((MC_NULL == (void *)pHandle) || ((uint8_t)0 == flag)) + { + /* Nothing to do */ + } + else + { + /* Nothing to do */ + } +#endif + return; +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Calculates the estimated electrical angle. + * + * Executes Luenberger state observer equations and calls + * PLL to compute a new speed estimation and + * update the estimated electrical angle. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param pInput: Pointer to the observer inputs structure. + * @retval int16_t Rotor electrical angle (s16Degrees). + */ +__weak int16_t STO_PLL_CalcElAngle(STO_PLL_Handle_t *pHandle, Observer_Inputs_t *pInputs) +{ + int16_t retValue; + + if ((MC_NULL == pHandle) || (MC_NULL == pInputs)) + { + retValue = 0; + } + else + { + int32_t wAux; + int32_t wDirection; + int32_t wIalfa_est_Next; + int32_t wIbeta_est_Next; + int32_t wBemf_alfa_est_Next; + int32_t wBemf_beta_est_Next; + int16_t hAux; + int16_t hAux_Alfa; + int16_t hAux_Beta; + int16_t hIalfa_err; + int16_t hIbeta_err; + int16_t hRotor_Speed; + int16_t hValfa; + int16_t hVbeta; + + if (pHandle->wBemf_alfa_est > (((int32_t)pHandle->hF2) * INT16_MAX)) + { + pHandle->wBemf_alfa_est = INT16_MAX * ((int32_t)pHandle->hF2); + } + else if (pHandle->wBemf_alfa_est <= (-INT16_MAX * ((int32_t)pHandle->hF2))) + { + pHandle->wBemf_alfa_est = -INT16_MAX * ((int32_t)pHandle->hF2); + } + else + { + /* Nothing to do */ + } +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hAux_Alfa = (int16_t)(pHandle->wBemf_alfa_est >> pHandle->F2LOG); +#else + hAux_Alfa = (int16_t)(pHandle->wBemf_alfa_est / pHandle->hF2); +#endif + + if (pHandle->wBemf_beta_est > (INT16_MAX * ((int32_t)pHandle->hF2))) + { + pHandle->wBemf_beta_est = INT16_MAX * ((int32_t)pHandle->hF2); + } + else if (pHandle->wBemf_beta_est <= (-INT16_MAX * ((int32_t)pHandle->hF2))) + { + pHandle->wBemf_beta_est = (-INT16_MAX * ((int32_t)pHandle->hF2)); + } + else + { + /* Nothing to do */ + } +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hAux_Beta = (int16_t)(pHandle->wBemf_beta_est >> pHandle->F2LOG); +#else + hAux_Beta = (int16_t)(pHandle->wBemf_beta_est / pHandle->hF2); +#endif + + if (pHandle->Ialfa_est > (INT16_MAX * ((int32_t)pHandle->hF1))) + { + pHandle->Ialfa_est = INT16_MAX * ((int32_t)pHandle->hF1); + } + else if (pHandle->Ialfa_est <= (-INT16_MAX * ((int32_t)pHandle->hF1))) + { + pHandle->Ialfa_est = -INT16_MAX * ((int32_t)pHandle->hF1); + } + else + { + /* Nothing to do */ + } + + if (pHandle->Ibeta_est > (INT16_MAX * ((int32_t)pHandle->hF1))) + { + pHandle->Ibeta_est = INT16_MAX * ((int32_t)pHandle->hF1); + } + else if (pHandle->Ibeta_est <= (-INT16_MAX * ((int32_t)pHandle->hF1))) + { + pHandle->Ibeta_est = -INT16_MAX * ((int32_t)pHandle->hF1); + } + else + { + /* Nothing to do */ + } + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hIalfa_err = (int16_t)(pHandle->Ialfa_est >> pHandle->F1LOG); +#else + hIalfa_err = (int16_t)(pHandle->Ialfa_est / pHandle->hF1); +#endif + + hIalfa_err = hIalfa_err - pInputs->Ialfa_beta.alpha; + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hIbeta_err = (int16_t)(pHandle->Ibeta_est >> pHandle->F1LOG); +#else + hIbeta_err = (int16_t)(pHandle->Ibeta_est / pHandle->hF1); +#endif + + hIbeta_err = hIbeta_err - pInputs->Ialfa_beta.beta; + + wAux = ((int32_t)pInputs->Vbus) * pInputs->Valfa_beta.alpha; +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + hValfa = (int16_t)(wAux >> 16); // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 +#else + hValfa = (int16_t)(wAux / 65536); +#endif + + wAux = ((int32_t)pInputs->Vbus) * pInputs->Valfa_beta.beta; + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + hVbeta = (int16_t)(wAux >> 16); // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 +#else + hVbeta = (int16_t)(wAux / 65536); +#endif + + /*alfa axes observer*/ +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hAux = (int16_t)(pHandle->Ialfa_est >> pHandle->F1LOG); +#else + hAux = (int16_t)(pHandle->Ialfa_est / pHandle->hF1); +#endif + + wAux = ((int32_t)pHandle->hC1) * hAux; + wIalfa_est_Next = pHandle->Ialfa_est - wAux; + + wAux = ((int32_t)pHandle->hC2) * hIalfa_err; + wIalfa_est_Next += wAux; + + wAux = ((int32_t)pHandle->hC5) * hValfa; + wIalfa_est_Next += wAux; + + wAux = ((int32_t)pHandle->hC3) * hAux_Alfa; + wIalfa_est_Next -= wAux; + + wAux = ((int32_t)pHandle->hC4) * hIalfa_err; + wBemf_alfa_est_Next = pHandle->wBemf_alfa_est + wAux; + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + wAux = (int32_t)hAux_Beta >> + pHandle->F3POW2; // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 +#else + wAux = ((int32_t)hAux_Beta) / pHandle->hF3; +#endif + + wAux = wAux * pHandle->hC6; + wAux = pHandle->_Super.hElSpeedDpp * wAux; + wBemf_alfa_est_Next += wAux; + + /*beta axes observer*/ +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + hAux = (int16_t)(pHandle->Ibeta_est >> pHandle->F1LOG); +#else + hAux = (int16_t)(pHandle->Ibeta_est / pHandle->hF1); +#endif + + wAux = ((int32_t)pHandle->hC1) * hAux; + wIbeta_est_Next = pHandle->Ibeta_est - wAux; + + wAux = ((int32_t)pHandle->hC2) * hIbeta_err; + wIbeta_est_Next += wAux; + + wAux = ((int32_t)pHandle->hC5) * hVbeta; + wIbeta_est_Next += wAux; + + wAux = ((int32_t)pHandle->hC3) * hAux_Beta; + wIbeta_est_Next -= wAux; + + wAux = ((int32_t)pHandle->hC4) * hIbeta_err; + wBemf_beta_est_Next = pHandle->wBemf_beta_est + wAux; + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + wAux = (int32_t)hAux_Alfa >> + pHandle->F3POW2; // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg + // !MISRAC2012-Rule-10.1_R6 +#else + wAux = ((int32_t)hAux_Alfa) / pHandle->hF3; +#endif + + wAux = wAux * pHandle->hC6; + wAux = pHandle->_Super.hElSpeedDpp * wAux; + wBemf_beta_est_Next -= wAux; + + /*Calls the PLL blockset*/ + pHandle->hBemf_alfa_est = hAux_Alfa; + pHandle->hBemf_beta_est = hAux_Beta; + + if (0 == pHandle->hForcedDirection) + { + /* we are in auxiliary mode, then rely on the speed detected */ + if (pHandle->_Super.hElSpeedDpp >= 0) + { + wDirection = 1; + } + else + { + wDirection = -1; + } + } + else + { + /* we are in main sensor mode, use a forced direction */ + wDirection = pHandle->hForcedDirection; + } + + hAux_Alfa = (int16_t)(hAux_Alfa * wDirection); + hAux_Beta = (int16_t)(hAux_Beta * wDirection); + + hRotor_Speed = STO_ExecutePLL(pHandle, hAux_Alfa, -hAux_Beta); + pHandle->_Super.InstantaneousElSpeedDpp = hRotor_Speed; + + STO_Store_Rotor_Speed(pHandle, hRotor_Speed); + + pHandle->_Super.hElAngle += hRotor_Speed; + + /*storing previous values of currents and bemfs*/ + pHandle->Ialfa_est = wIalfa_est_Next; + pHandle->wBemf_alfa_est = wBemf_alfa_est_Next; + + pHandle->Ibeta_est = wIbeta_est_Next; + pHandle->wBemf_beta_est = wBemf_beta_est_Next; + retValue = pHandle->_Super.hElAngle; + } + return (retValue); +} + +/** + * @brief Computes and returns the average mechanical speed. + * + * This method must be called - at least - with the same periodicity + * on which speed control is executed. It computes and returns - through + * parameter hMecSpeedUnit - the rotor average mechanical speed, + * expressed in #SPEED_UNIT. Average is computed considering a FIFO depth + * equal to bSpeedBufferSizeUnit. Moreover it also computes and returns + * the reliability state of the sensor. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param pMecSpeedUnit: Pointer to int16_t, used to return the rotor average + * mechanical speed (expressed in #SPEED_UNIT). + * @retval True if the sensor information is reliable, false otherwise. + */ + +__weak bool STO_PLL_CalcAvrgMecSpeedUnit(STO_PLL_Handle_t *pHandle, + int16_t *pMecSpeedUnit) +{ + bool bAux; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if ((MC_NULL == pHandle) || (MC_NULL == pMecSpeedUnit)) + { + bAux = false; + } + else + { +#endif + int32_t wAvrSpeed_dpp = (int32_t)0; + int32_t wError; + int32_t wAux; + int32_t wAvrSquareSpeed; + int32_t wAvrQuadraticError = 0; + int32_t wObsBemf, wEstBemf; + int32_t wObsBemfSq = 0; + int32_t wEstBemfSq = 0; + int32_t wEstBemfSqLo; + bool bIs_Speed_Reliable = false; + bool bIs_Bemf_Consistent = false; + uint8_t i, bSpeedBufferSizeUnit = pHandle->SpeedBufferSizeUnit; + + for (i = 0U; i < bSpeedBufferSizeUnit; i++) + { + wAvrSpeed_dpp += (int32_t)(pHandle->Speed_Buffer[i]); + } + + if (0U == bSpeedBufferSizeUnit) + { + /* Nothing to do */ + } + else + { + wAvrSpeed_dpp = wAvrSpeed_dpp / ((int16_t)bSpeedBufferSizeUnit); + } + + for (i = 0U; i < bSpeedBufferSizeUnit; i++) + { + wError = ((int32_t)pHandle->Speed_Buffer[i]) - wAvrSpeed_dpp; + wError = (wError * wError); + wAvrQuadraticError += wError; + } + + /* It computes the measurement variance */ + wAvrQuadraticError = wAvrQuadraticError / ((int16_t)bSpeedBufferSizeUnit); + + /* The maximum variance acceptable is here calculated as a function of average + * speed */ + wAvrSquareSpeed = wAvrSpeed_dpp * wAvrSpeed_dpp; + int64_t lAvrSquareSpeed = (int64_t)(wAvrSquareSpeed)*pHandle->VariancePercentage; + wAvrSquareSpeed = lAvrSquareSpeed / (int16_t)128; + + if (wAvrQuadraticError < wAvrSquareSpeed) + { + bIs_Speed_Reliable = true; + } + + /* Computation of Mechanical speed Unit */ + wAux = wAvrSpeed_dpp * ((int32_t)pHandle->_Super.hMeasurementFrequency); + wAux = wAux * ((int32_t)pHandle->_Super.SpeedUnit); + wAux = wAux / ((int32_t)pHandle->_Super.DPPConvFactor); + wAux = wAux / ((int16_t)pHandle->_Super.bElToMecRatio); + + *pMecSpeedUnit = (int16_t)wAux; + pHandle->_Super.hAvrMecSpeedUnit = (int16_t)wAux; + + pHandle->IsSpeedReliable = bIs_Speed_Reliable; + + /* Bemf Consistency Check algorithm */ + if (true == pHandle->EnableDualCheck) /*do algorithm if it's enabled*/ + { + /* wAux abs value */ + // cstat !MISRAC2012-Rule-14.3_b !RED-func-no-effect !RED-cmp-never + // !RED-cond-never + wAux = ((wAux < 0) ? (-wAux) : (wAux)); + if (wAux < (int32_t)(pHandle->MaxAppPositiveMecSpeedUnit)) + { + /* Computation of Observed back-emf */ + wObsBemf = (int32_t)pHandle->hBemf_alfa_est; + wObsBemfSq = wObsBemf * wObsBemf; + wObsBemf = (int32_t)pHandle->hBemf_beta_est; + wObsBemfSq += wObsBemf * wObsBemf; + + /* Computation of Estimated back-emf */ + wEstBemf = + (wAux * 32767) / ((int16_t)pHandle->_Super.hMaxReliableMecSpeedUnit); + wEstBemfSq = (wEstBemf * ((int32_t)pHandle->BemfConsistencyGain)) / 64; + wEstBemfSq *= wEstBemf; + + /* Computation of threshold */ + wEstBemfSqLo = wEstBemfSq - ((wEstBemfSq / 64) * + ((int32_t)pHandle->BemfConsistencyCheck)); + + /* Check */ + if (wObsBemfSq > wEstBemfSqLo) + { + bIs_Bemf_Consistent = true; + } + } + + pHandle->IsBemfConsistent = bIs_Bemf_Consistent; + pHandle->Obs_Bemf_Level = wObsBemfSq; + pHandle->Est_Bemf_Level = wEstBemfSq; + } + else + { + bIs_Bemf_Consistent = true; + } + + /* Decision making */ + if (false == pHandle->IsAlgorithmConverged) + { + bAux = SPD_IsMecSpeedReliable(&pHandle->_Super, pMecSpeedUnit); + } + else + { + if ((false == pHandle->IsSpeedReliable) || (false == bIs_Bemf_Consistent)) + { + pHandle->ReliabilityCounter++; + if (pHandle->ReliabilityCounter >= pHandle->Reliability_hysteresys) + { + pHandle->ReliabilityCounter = 0U; + pHandle->_Super.bSpeedErrorNumber = + pHandle->_Super.bMaximumSpeedErrorsNumber; + bAux = false; + } + else + { + bAux = SPD_IsMecSpeedReliable(&pHandle->_Super, pMecSpeedUnit); + } + } + else + { + pHandle->ReliabilityCounter = 0U; + bAux = SPD_IsMecSpeedReliable(&pHandle->_Super, pMecSpeedUnit); + } + } +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif + return (bAux); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief Computes and updates the average electrical speed. + * + * This method must be called - at least - with the same periodicity + * on which speed control is executed. It computes and update component + * variable hElSpeedDpp that is estimated average electrical speed + * expressed in dpp used for instance in observer equations. + * Average is computed considering a FIFO depth equal to + * bSpeedBufferSizedpp. + * + * @param pHandle: Handler of the current instance of the STO component. + */ +__weak void STO_PLL_CalcAvrgElSpeedDpp(STO_PLL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int16_t hIndexNew = (int16_t)pHandle->Speed_Buffer_Index; + int16_t hIndexOld; + int16_t hIndexOldTemp; + int32_t wSum = pHandle->DppBufferSum; + int32_t wAvrSpeed_dpp; + int16_t hSpeedBufferSizedpp = (int16_t)pHandle->SpeedBufferSizeDpp; + int16_t hSpeedBufferSizeUnit = (int16_t)pHandle->SpeedBufferSizeUnit; + int16_t hBufferSizeDiff; + + hBufferSizeDiff = hSpeedBufferSizeUnit - hSpeedBufferSizedpp; + + if (0 == hBufferSizeDiff) + { + wSum = wSum + pHandle->Speed_Buffer[hIndexNew] - pHandle->SpeedBufferOldestEl; + } + else + { + hIndexOldTemp = hIndexNew + hBufferSizeDiff; + + if (hIndexOldTemp >= hSpeedBufferSizeUnit) + { + hIndexOld = hIndexOldTemp - hSpeedBufferSizeUnit; + } + else + { + hIndexOld = hIndexOldTemp; + } + + wSum = wSum + pHandle->Speed_Buffer[hIndexNew] - + pHandle->Speed_Buffer[hIndexOld]; + } + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + wAvrSpeed_dpp = wSum >> pHandle->SpeedBufferSizeDppLOG; +#else + if ((int16_t)0 == hSpeedBufferSizedpp) + { + /* Nothing to do */ + wAvrSpeed_dpp = wSum; + } + else + { + wAvrSpeed_dpp = wSum / hSpeedBufferSizedpp; + } +#endif + pHandle->_Super.hElSpeedDpp = (int16_t)wAvrSpeed_dpp; + pHandle->DppBufferSum = wSum; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Clears state observer component by re-initializing private variables in @p + * pHandle. + * + */ +__weak void STO_PLL_Clear(STO_PLL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->Ialfa_est = (int32_t)0; + pHandle->Ibeta_est = (int32_t)0; + pHandle->wBemf_alfa_est = (int32_t)0; + pHandle->wBemf_beta_est = (int32_t)0; + pHandle->_Super.hElAngle = (int16_t)0; + pHandle->_Super.hElSpeedDpp = (int16_t)0; + pHandle->ConsistencyCounter = 0u; + pHandle->ReliabilityCounter = 0u; + pHandle->IsAlgorithmConverged = false; + pHandle->IsBemfConsistent = false; + pHandle->Obs_Bemf_Level = (int32_t)0; + pHandle->Est_Bemf_Level = (int32_t)0; + pHandle->DppBufferSum = (int32_t)0; + pHandle->ForceConvergency = false; + pHandle->ForceConvergency2 = false; + + STO_InitSpeedBuffer(pHandle); + PID_SetIntegralTerm(&pHandle->PIRegulator, (int32_t)0); +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Stores in @p pHandle the latest calculated value of @p hRotor_Speed. + * + */ +inline static void STO_Store_Rotor_Speed(STO_PLL_Handle_t *pHandle, int16_t hRotor_Speed) +{ + uint8_t bBuffer_index = pHandle->Speed_Buffer_Index; + + bBuffer_index++; + if (bBuffer_index == pHandle->SpeedBufferSizeUnit) + { + bBuffer_index = 0U; + } + + pHandle->SpeedBufferOldestEl = pHandle->Speed_Buffer[bBuffer_index]; + pHandle->Speed_Buffer[bBuffer_index] = hRotor_Speed; + pHandle->Speed_Buffer_Index = bBuffer_index; +} + +/** + * @brief Executes PLL algorithm for rotor position extraction from B-emf alpha and beta. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param hBemf_alfa_est: Estimated Bemf alpha on the stator reference frame. + * @param hBemf_beta_est: Estimated Bemf beta on the stator reference frame. + * @retval + */ +inline static int16_t STO_ExecutePLL(STO_PLL_Handle_t *pHandle, int16_t hBemf_alfa_est, + int16_t hBemf_beta_est) +{ + int32_t wAlfa_Sin_tmp; + int32_t wBeta_Cos_tmp; + Trig_Components Local_Components; + int16_t hAux1; + int16_t hAux2; + int16_t hOutput; + + Local_Components = MCM_Trig_Functions(pHandle->_Super.hElAngle); + + /* Alfa & Beta BEMF multiplied by Cos & Sin*/ + wAlfa_Sin_tmp = ((int32_t)hBemf_alfa_est) * ((int32_t)Local_Components.hSin); + wBeta_Cos_tmp = ((int32_t)hBemf_beta_est) * ((int32_t)Local_Components.hCos); + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + hAux1 = (int16_t)(wBeta_Cos_tmp >> 15); // cstat !MISRAC2012-Rule-1.3_n + // !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 +#else + hAux1 = (int16_t)(wBeta_Cos_tmp / 32768); +#endif + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + hAux2 = (int16_t)(wAlfa_Sin_tmp >> 15); // cstat !MISRAC2012-Rule-1.3_n + // !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 +#else + hAux2 = (int16_t)(wAlfa_Sin_tmp / 32768); +#endif + + /* Speed PI regulator */ + hOutput = PI_Controller(&pHandle->PIRegulator, (int32_t)(hAux1)-hAux2); + return (hOutput); +} + +/** + * @brief Clears the estimated speed buffer in @p pHandle. + * + */ +static void STO_InitSpeedBuffer(STO_PLL_Handle_t *pHandle) +{ + uint8_t b_i; + uint8_t bSpeedBufferSize = pHandle->SpeedBufferSizeUnit; + + /*init speed buffer*/ + for (b_i = 0U; b_i < bSpeedBufferSize; b_i++) + { + pHandle->Speed_Buffer[b_i] = (int16_t)0; + } + pHandle->Speed_Buffer_Index = 0U; + pHandle->SpeedBufferOldestEl = (int16_t)0; + + return; +} + +/** + * @brief Checks if the state observer algorithm converged. + * + * Internally performs a set of checks necessary to state whether + * the state observer algorithm converged. To be periodically called + * during motor open-loop ramp-up (e.g. at the same frequency of + * SPD_CalcElAngle), it returns true if the estimated angle and speed + * can be considered reliable, false otherwise. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param hForcedMecSpeedUnit: Mechanical speed in 0.1Hz unit as forced by VSS. + * @retval bool True if the estimated angle and speed are reliables, false otherwise. + */ +__weak bool STO_PLL_IsObserverConverged(STO_PLL_Handle_t *pHandle, + int16_t *phForcedMecSpeedUnit) +{ + bool bAux = false; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if ((MC_NULL == pHandle) || (MC_NULL == phForcedMecSpeedUnit)) + { + /* Nothing to do */ + } + else + { +#endif + int16_t hEstimatedSpeedUnit; + int16_t hUpperThreshold; + int16_t hLowerThreshold; + int32_t wAux; + int32_t wtemp; + + if (true == pHandle->ForceConvergency2) + { + *phForcedMecSpeedUnit = pHandle->_Super.hAvrMecSpeedUnit; + } + + if (true == pHandle->ForceConvergency) + { + bAux = true; + pHandle->IsAlgorithmConverged = true; + pHandle->_Super.bSpeedErrorNumber = 0U; + } + else + { + hEstimatedSpeedUnit = pHandle->_Super.hAvrMecSpeedUnit; + + wtemp = ((int32_t)hEstimatedSpeedUnit) * ((int32_t)*phForcedMecSpeedUnit); + + if (wtemp > 0) + { + if (hEstimatedSpeedUnit < 0) + { + hEstimatedSpeedUnit = -hEstimatedSpeedUnit; + } + + if (*phForcedMecSpeedUnit < 0) + { + *phForcedMecSpeedUnit = -*phForcedMecSpeedUnit; + } + wAux = ((int32_t)*phForcedMecSpeedUnit) * + ((int16_t)pHandle->SpeedValidationBand_H); + hUpperThreshold = (int16_t)(wAux / ((int32_t)16)); + + wAux = ((int32_t)*phForcedMecSpeedUnit) * + ((int16_t)pHandle->SpeedValidationBand_L); + hLowerThreshold = (int16_t)(wAux / ((int32_t)16)); + + /* If the variance of the estimated speed is low enough...*/ + if (true == pHandle->IsSpeedReliable) + { + if ((uint16_t)hEstimatedSpeedUnit > pHandle->MinStartUpValidSpeed) + { + /*...and the estimated value is quite close to the expected + * value... */ + if (hEstimatedSpeedUnit >= hLowerThreshold) + { + if (hEstimatedSpeedUnit <= hUpperThreshold) + { + pHandle->ConsistencyCounter++; + + /*... for hConsistencyThreshold consecutive times... */ + if (pHandle->ConsistencyCounter >= + pHandle->StartUpConsistThreshold) + { + /* the algorithm converged.*/ + bAux = true; + pHandle->IsAlgorithmConverged = true; + pHandle->_Super.bSpeedErrorNumber = 0U; + } + } + else + { + pHandle->ConsistencyCounter = 0U; + } + } + else + { + pHandle->ConsistencyCounter = 0U; + } + } + else + { + pHandle->ConsistencyCounter = 0U; + } + } + else + { + pHandle->ConsistencyCounter = 0U; + } + } + } +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif + return (bAux); +} + +/** + * @brief Exports estimated Bemf alpha-beta from @p pHandle. + * + * @retval alphabeta_t Bemf alpha-beta. + */ +__weak alphabeta_t STO_PLL_GetEstimatedBemf(STO_PLL_Handle_t *pHandle) +{ + alphabeta_t vaux; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + vaux.alpha = 0; + vaux.beta = 0; + } + else + { +#endif + vaux.alpha = pHandle->hBemf_alfa_est; + vaux.beta = pHandle->hBemf_beta_est; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif + return (vaux); +} + + +/** + * @brief Exports from @p pHandle the stator current alpha-beta as estimated by state + * observer. + * + * @retval alphabeta_t State observer estimated stator current Ialpha-beta. + */ +__weak alphabeta_t STO_PLL_GetEstimatedCurrent(STO_PLL_Handle_t *pHandle) +{ + alphabeta_t iaux; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + iaux.alpha = 0; + iaux.beta = 0; + } + else + { +#endif +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + iaux.alpha = (int16_t)(pHandle->Ialfa_est >> pHandle->F1LOG); +#else + iaux.alpha = (int16_t)(pHandle->Ialfa_est / pHandle->hF1); +#endif + +#ifndef FULL_MISRA_C_COMPLIANCY_STO_PLL + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + iaux.beta = (int16_t)(pHandle->Ibeta_est >> pHandle->F1LOG); +#else + iaux.beta = (int16_t)(pHandle->Ibeta_est / pHandle->hF1); +#endif +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif + return (iaux); +} + +/** + * @brief Exports current observer gains from @p pHandle and to parameters @p phC2 and @p + * phC4. + * + */ +__weak void STO_PLL_GetObserverGains(STO_PLL_Handle_t *pHandle, int16_t *phC2, + int16_t *phC4) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if ((MC_NULL == pHandle) || (MC_NULL == phC2) || (MC_NULL == phC4)) + { + /* Nothing to do */ + } + else + { +#endif + *phC2 = pHandle->hC2; + *phC4 = pHandle->hC4; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Stores in @p pHandle the new values @p hhC1 and @p hhC2 for observer gains. + * + */ +__weak void STO_PLL_SetObserverGains(STO_PLL_Handle_t *pHandle, int16_t hhC1, + int16_t hhC2) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hC2 = hhC1; + pHandle->hC4 = hhC2; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Exports current PLL gains from @p pHandle to @p pPgain and @p pIgain. + * + */ +__weak void STO_GetPLLGains(STO_PLL_Handle_t *pHandle, int16_t *pPgain, int16_t *pIgain) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if ((MC_NULL == pHandle) || (MC_NULL == pPgain) || (MC_NULL == pIgain)) + { + /* Nothing to do */ + } + else + { +#endif + *pPgain = PID_GetKP(&pHandle->PIRegulator); + *pIgain = PID_GetKI(&pHandle->PIRegulator); +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + + +/** + * @brief Stores in @p pHandle the new values @p hPgain and @p hIgain for PLL gains. + * + */ +__weak void STO_SetPLLGains(STO_PLL_Handle_t *pHandle, int16_t hPgain, int16_t hIgain) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + PID_SetKP(&pHandle->PIRegulator, hPgain); + PID_SetKI(&pHandle->PIRegulator, hIgain); +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + + +/** + * @brief Empty function. Could be declared to set instantaneous information on rotor + * mechanical angle. + * + * Note: Mechanical angle management is not implemented in this + * version of State observer sensor class. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param hMecAngle: Instantaneous measure of rotor mechanical angle. + */ +// cstat !RED-func-no-effect +__weak void STO_PLL_SetMecAngle(STO_PLL_Handle_t *pHandle, int16_t hMecAngle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if ((MC_NULL == (void *)pHandle) || ((int16_t)0 == hMecAngle)) + { + /* Nothing to do */ + } + else + { + /* nothing to do */ + } +#endif +} + +/** + * @brief Resets the PLL integral term during on-the-fly startup. + * + * @param pHandle: Handler of the current instance of the STO component. + */ +__weak void STO_OTF_ResetPLL(STO_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + STO_PLL_Handle_t *pHdl = + (STO_PLL_Handle_t *)pHandle->_Super; // cstat !MISRAC2012-Rule-11.3 + PID_SetIntegralTerm(&pHdl->PIRegulator, (int32_t)0); +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__( ( section ( ".ccmram" ) ) ) +#endif +#endif +/** + * @brief Resets the PLL integral term. + * + * @param pHandle: Handler of the current instance of the STO component. + */ +__weak void STO_ResetPLL(STO_PLL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + PID_SetIntegralTerm(&pHandle->PIRegulator, (int32_t)0); +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Sends locking info for PLL. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param hElSpeedDpp: Estimated average electrical speed expressed in dpp. + * @param hElAngle: Estimated electrical angle expressed in s16Degrees. + */ +__weak void STO_SetPLL(STO_PLL_Handle_t *pHandle, int16_t hElSpeedDpp, int16_t hElAngle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + PID_SetIntegralTerm( + &pHandle->PIRegulator, + ((int32_t)hElSpeedDpp) * (int32_t)(PID_GetKIDivisor(&pHandle->PIRegulator))); + pHandle->_Super.hElAngle = hElAngle; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Exports estimated Bemf squared level stored in @p pHandle. + * + * @retval int32_t Magnitude of estimated Bemf Level squared based on speed measurement. + */ +__weak int32_t STO_PLL_GetEstimatedBemfLevel(STO_PLL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + return ((MC_NULL == pHandle) ? 0 : pHandle->Est_Bemf_Level); +#else + return (pHandle->Est_Bemf_Level); +#endif +} + +/** + * @brief Exports observed Bemf squared level stored in @p pHandle. + * + * @retval int32_t Magnitude of observed Bemf level squared. + */ +__weak int32_t STO_PLL_GetObservedBemfLevel(STO_PLL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + return ((MC_NULL == pHandle) ? 0 : pHandle->Obs_Bemf_Level); +#else + return (pHandle->Obs_Bemf_Level); +#endif +} + +/** + * @brief Enables/Disables additional reliability check based on observed Bemf. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param bSel Enable/Disable check. + */ +__weak void STO_PLL_BemfConsistencyCheckSwitch(STO_PLL_Handle_t *pHandle, bool bSel) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->EnableDualCheck = bSel; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Checks if the Bemf is consistent. + * + * @param pHandle: Handler of the current instance of the STO component. + * @retval bool True when observed Bemfs are consistent with expectation, false otherwise. + */ +__weak bool STO_PLL_IsBemfConsistent(STO_PLL_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + return ((MC_NULL == pHandle) ? false : pHandle->IsBemfConsistent); +#else + return (pHandle->IsBemfConsistent); +#endif +} + +/** + * @brief Checks the value of the variance. + * + * @param pHandle: Handler of the current instance of the STO component. + * @retval bool True if the speed measurement variance is lower than threshold + * VariancePercentage, false otherwise. + */ +__weak bool STO_PLL_IsVarianceTight(const STO_Handle_t *pHandle) +{ + bool tempStatus; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + tempStatus = false; + } + else + { +#endif + STO_PLL_Handle_t *pHdl = + (STO_PLL_Handle_t *)pHandle->_Super; // cstat !MISRAC2012-Rule-11.3 + tempStatus = pHdl->IsSpeedReliable; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif + return (tempStatus); +} + +/** + * @brief Forces the state-observer to declare convergency. + * + * @param pHandle: Handler of the current instance of the STO component. + */ +__weak void STO_PLL_ForceConvergency1(STO_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + STO_PLL_Handle_t *pHdl = + (STO_PLL_Handle_t *)pHandle->_Super; // cstat !MISRAC2012-Rule-11.3 + pHdl->ForceConvergency = true; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Forces the state-observer to declare convergency. + * + * @param pHandle: Handler of the current instance of the STO component. + */ +__weak void STO_PLL_ForceConvergency2(STO_Handle_t *pHandle) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + STO_PLL_Handle_t *pHdl = + (STO_PLL_Handle_t *)pHandle->_Super; // cstat !MISRAC2012-Rule-11.3 + pHdl->ForceConvergency2 = true; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Sets the Absolute value of minimum mechanical speed (expressed in + * the unit defined by #SPEED_UNIT) required to validate the start-up. + * + * @param pHandle: Handler of the current instance of the STO component. + * @param hMinStartUpValidSpeed: Absolute value of minimum mechanical speed. + */ +__weak void STO_SetMinStartUpValidSpeedUnit(STO_PLL_Handle_t *pHandle, + uint16_t hMinStartUpValidSpeed) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->MinStartUpValidSpeed = hMinStartUpValidSpeed; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + +/** + * @brief Sets the rotation @p direction in @p pHandle. + */ +__weak void STO_SetDirection(STO_PLL_Handle_t *pHandle, int8_t direction) +{ +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hForcedDirection = direction; +#ifdef NULL_PTR_STO_PLL_SPD_POS_FDB + } +#endif +} + + +/** + * @} + */ + +/** + * @} + */ + +/** @} */ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/sto_pll_speed_pos_fdbk.h b/src/firmware/motor/mcsdk/sto_pll_speed_pos_fdbk.h new file mode 100644 index 0000000000..ed24d83362 --- /dev/null +++ b/src/firmware/motor/mcsdk/sto_pll_speed_pos_fdbk.h @@ -0,0 +1,322 @@ +/** + ****************************************************************************** + * @file sto_pll_speed_pos_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * State Observer + PLL Speed & Position Feedback component of the Motor + * Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeednPosFdbk_STO_PLL + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STO_PLL_SPEEDNPOSFDBK_H +#define STO_PLL_SPEEDNPOSFDBK_H + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/pid_regulator.h" +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" +#include "firmware/motor/mcsdk/sto_speed_pos_fdbk.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup SpeednPosFdbk_STO_PLL + * @{ + */ + + +/** + * @brief Handle of the Speed and Position Feedback STO PLL component. + * + */ + +typedef struct +{ + SpeednPosFdbk_Handle_t _Super; /**< @brief Speed and torque component handler. */ + + int16_t hC1; /*!< @brief State observer constant @f$ C_1 @f$. + * + * Can be computed as : @f$ (F_1 × R_s) / (L_s × State Observer + * Execution Rate) @f$ \n + * @f$ F_1 @f$ in Hertz [**Hz**]. \n + * @f$ R_s @f$ in Ohm @f$[\Omega]@f$. \n + * @f$ L_s @f$ in Henry [**H**]. \n + * State Observer Execution Rate in Hertz [**Hz**]. + */ + int16_t hC2; /**< @brief State observer constant @f$ C_2 @f$. + * + * Can be computed as : @f$ (F_1 × K_1) / (State Observer Execution + * Rate) @f$ \n + * @f$ F_1 @f$ in Hertz [**Hz**]. \n + * @f$ K_1 @f$ being one of the two observer gains. \n + * State Observer Execution Rate in Hertz [**Hz**]. + */ + int16_t hC3; /**< @brief State observer constant @f$ C_3 @f$. + * + * Can be computed as : @f$ (F_1 × Max Application Speed × Motor Bemf + * Constant × √2) / (L_S × Max Measurable Current × State Observer + * Execution Rate) @f$ \n + * @f$ F_1 @f$ in Hertz [**Hz**]. \n + * Max Application Speed in Rotation per minute [**rpm**]. \n + * Motor Bemf Constant in Voltage line to line root mean square per + * kilo-rpm [**Vllrms/krpm**]. \n + * @f$ L_s @f$ in Henry [**H**]. \n + * Max Measurable Current in Ampere [**A**]. \n + * State Observer Execution Rate in Hertz [**Hz**]. + */ + int16_t + hC4; /**< @brief State Observer constant @f$ C_4 @f$. + * + * Can be computed as @f$ K_2 × Max Measurable Current / (Max Application + * Speed × Motor Bemf Constant × √2 × F_2 × State Observer Execution Rate) + * @f$ \n + * @f$ K_2 @f$ being one of the two observer gains. \n + * Max Measurable Current in Ampere [**A**]. \n + * Max Application Speed in Rotation per minute [**rpm**]. \n + * Motor Bemf Constant in Voltage line to line root mean square per kilo-rpm + * [**Vllrms/krpm**]. \n State Observer Execution Rate in Hertz [**Hz**]. + * \n + */ + int16_t hC5; /**< @brief State observer constant @f$ C_5 @f$. + * + * Can be computed as @f$ F_1 × Max Measurable Voltage / (2 × L_s × Max + * Measurable Current × State Observer Execution Rate) @f$ \n + * @f$ F_1 @f$ in Hertz [**Hz**]. \n + * Max Measurable Voltage in Volt [**V**]. \n + * @f$ L_s @f$ in Henry [**H**]. \n + * Max Measurable Current in Ampere [**A**]. \n + * State Observer Execution Rate in Hertz [**Hz**]. + */ + int16_t hC6; /**< @brief State observer constant @f$ C_6 @f$. Computed with a specific + procedure starting from the other constants. */ + + int16_t hF1; /**< @brief State observer scaling factor @f$ F_1 @f$. */ + int16_t hF2; /**< @brief State observer scaling factor @f$ F_2 @f$. */ + int16_t hF3; /**< @brief State observer scaling factor @f$ F_3 @f$. */ + uint16_t F3POW2; /**< @brief State observer scaling factor @f$ F_3 @f$ expressed as + * power of 2. + * + * E.g. If gain divisor is 512 the value must be 9 because @f$ 2^9 = + * 512 @f$. + */ + PID_Handle_t PIRegulator; /**< @brief PI regulator component handle, used for PLL + implementation */ + int32_t Ialfa_est; /**< @brief Estimated @f$ I_{alpha} @f$ current. */ + int32_t Ibeta_est; /**< @brief Estimated @f$ I_{beta} @f$ current. */ + int32_t wBemf_alfa_est; /**< @brief Estimated Bemf alpha. */ + int32_t wBemf_beta_est; /**< @brief Estimated Bemf beta. */ + int16_t hBemf_alfa_est; /**< @brief Estimated Bemf alpha in int16_t format. */ + int16_t hBemf_beta_est; /**< @brief Estimated Bemf beta in int16_t format. */ + int16_t Speed_Buffer[64]; /**< @brief Estimated speed FIFO, it contains latest + SpeedBufferSizeDpp speed measurements [**DPP**]. */ + uint8_t Speed_Buffer_Index; /**< @brief Index of latest estimated speed in buffer + Speed_Buffer[]. */ + bool IsSpeedReliable; /**< @brief Estimated speed reliability information. + * + * Updated during speed average computation in + * STO_PLL_CalcAvrgMecSpeedUnit, True if the speed + * measurement variance is lower than threshold + * VariancePercentage. + */ + uint8_t ConsistencyCounter; /**< @brief Counter of passed tests for start-up + validation. */ + uint8_t ReliabilityCounter; /**< @brief Counter for checking reliability of Bemf and + speed. */ + bool IsAlgorithmConverged; /**< @brief Observer convergence flag. */ + bool IsBemfConsistent; /**< @brief Reliability of estimated Bemf flag. + * + * Updated by STO_PLL_CalcAvrgMecSpeedUnit, set to true when + * observed Bemfs are consistent with expectation. + */ + int32_t Obs_Bemf_Level; /**< @brief Magnitude of observed Bemf level squared. */ + int32_t Est_Bemf_Level; /**< @brief Magnitude of estimated Bemf Level squared based on + speed measurement. */ + bool EnableDualCheck; /**< @brief Enable additional reliability check based on + observed Bemf. */ + int32_t DppBufferSum; /**< @brief Sum of speed buffer elements [**DPP**]. */ + int16_t SpeedBufferOldestEl; /**< @brief Oldest element of the speed buffer. */ + + uint8_t SpeedBufferSizeUnit; /**< @brief Depth of FIFO used to calculate the average + * estimated speed exported by SPD_GetAvrgMecSpeedUnit. + * Must be an integer number in range[1..64]. + */ + uint8_t SpeedBufferSizeDpp; /**< @brief Depth of FIFO used to calculate both average + * estimated speed exported by SPD_GetElSpeedDpp and state + * observer equations. Must be an integer number between + * 1 and SpeedBufferSizeUnit + */ + uint16_t + VariancePercentage; /**< @brief Maximum allowed variance of speed estimation. */ + + uint8_t SpeedValidationBand_H; /**< @brief Upper bound below which the estimated speed + * is still acceptable despite exceeding the force + * stator electrical frequency during start-up. The + * measurement unit is 1/16 of forced speed. + */ + uint8_t SpeedValidationBand_L; /**< @brief Lower bound above which the estimated speed + * is still acceptable despite subceeding the force + * stator electrical frequency during start-up. The + * measurement unit is 1/16 of forced speed. + */ + uint16_t + MinStartUpValidSpeed; /**< @brief Absolute value of minimum mechanical + * speed required to validate the start-up. + * Expressed in the unit defined by #SPEED_UNIT. + */ + uint8_t StartUpConsistThreshold; /**< @brief Number of consecutive tests on speed + * consistency to be passed before + * validating the start-up. + */ + uint8_t Reliability_hysteresys; /**< @brief Number of failed consecutive reliability + * tests before returning a speed check fault to + * _Super.bSpeedErrorNumber. + */ + uint8_t BemfConsistencyCheck; /**< @brief Degree of consistency of the observed Bemfs. + * \n Must be an integer number ranging from 1 (very + * high consistency) down to 64 (very poor consistency). + */ + uint8_t + BemfConsistencyGain; /**< @brief Gain to be applied when checking Bemfs + * consistency. \n Default value is 64 (neutral), max value + * 105 (x1.64 amplification), min value 1 (/64 attenuation). + */ + uint16_t MaxAppPositiveMecSpeedUnit; /**< @brief Maximum positive value of rotor + * speed. \n Expressed in the unit defined by + * #SPEED_UNIT. Can be x1.1 greater than max + * application speed. + */ + uint16_t F1LOG; /**< @brief @f$ F_1 @f$ gain divisor expressed as power of 2. + * + * E.g. if gain divisor is 512 the value must be 9 because @f$ 2^9 = + * 512 @f$. + */ + uint16_t F2LOG; /**< @brief @f$ F_2 @f$ gain divisor expressed as power of 2. + * + * E.g. if gain divisor is 512 the value must be 9 because @f$ 2^9 = + * 512 @f$. + */ + uint16_t + SpeedBufferSizeDppLOG; /**< @brief bSpeedBufferSizedpp expressed as power of 2. + * + * E.g. if gain divisor is 512 the value must be 9 because + * @f$ 2^9 = 512 @f$. + */ + bool ForceConvergency; /**< @brief Variable to force observer convergence. */ + bool ForceConvergency2; /**< @brief Variable to force observer convergence. */ + + int8_t hForcedDirection; /**< @brief Variable to force rotation direction. */ + +} STO_PLL_Handle_t; + + +/* Exported functions ------------------------------------------------------- */ + +/* Initializes the handler of STate Observer (STO) PLL component. */ +void STO_PLL_Init(STO_PLL_Handle_t *pHandle); + +/* Necessary empty return to implement fictitious IRQ_Handler. */ +void STO_PLL_Return(STO_PLL_Handle_t *pHandle, uint8_t flag); + +/* Clears state observer component by re-initializing private variables in the handler. */ +void STO_PLL_Clear(STO_PLL_Handle_t *pHandle); + +/* Calculates the estimated electrical angle. */ +int16_t STO_PLL_CalcElAngle(STO_PLL_Handle_t *pHandle, Observer_Inputs_t *pInputs); + +/* Computes and returns the average mechanical speed. */ +bool STO_PLL_CalcAvrgMecSpeedUnit(STO_PLL_Handle_t *pHandle, int16_t *pMecSpeedUnit); + +/* Resets the PLL integral term during on-the-fly startup. */ +void STO_OTF_ResetPLL(STO_Handle_t *pHandle); + +/* Resets the PLL integral term. */ +void STO_ResetPLL(STO_PLL_Handle_t *pHandle); + +/* Checks if the state observer algorithm converged. */ +bool STO_PLL_IsObserverConverged(STO_PLL_Handle_t *pHandle, + int16_t *phForcedMecSpeedUnit); + +/* Computes and updates the average electrical speed. */ +void STO_PLL_CalcAvrgElSpeedDpp(STO_PLL_Handle_t *pHandle); + +/* Exports estimated Bemf alpha-beta from the handler. */ +alphabeta_t STO_PLL_GetEstimatedBemf(STO_PLL_Handle_t *pHandle); + +/* Exports from the handler the stator current alpha-beta as estimated by state observer. + */ +alphabeta_t STO_PLL_GetEstimatedCurrent(STO_PLL_Handle_t *pHandle); + +/* Stores in the handler the new values for observer gains. */ +void STO_PLL_SetObserverGains(STO_PLL_Handle_t *pHandle, int16_t hhC1, int16_t hhC2); + +/* Exports current observer gains from the handler to parameters hhC2 and hhC4. */ +void STO_PLL_GetObserverGains(STO_PLL_Handle_t *pHandle, int16_t *phC2, int16_t *phC4); + +/* Exports the current PLL gains from the handler to parameters pPgain and pIgain. */ +void STO_GetPLLGains(STO_PLL_Handle_t *pHandle, int16_t *pPgain, int16_t *pIgain); + +/* Stores in the handler the new values for PLL gains. */ +void STO_SetPLLGains(STO_PLL_Handle_t *pHandle, int16_t hPgain, int16_t hIgain); + +/* Empty function. Could be declared to set instantaneous information on rotor mechanical + * angle. */ +void STO_PLL_SetMecAngle(STO_PLL_Handle_t *pHandle, int16_t hMecAngle); + +/* Sends locking info for PLL. */ +void STO_SetPLL(STO_PLL_Handle_t *pHandle, int16_t hElSpeedDpp, int16_t hElAngle); + +/* Exports estimated Bemf squared level stored in the handler. */ +int32_t STO_PLL_GetEstimatedBemfLevel(STO_PLL_Handle_t *pHandle); + +/* Exports observed Bemf squared level stored in the handler. */ +int32_t STO_PLL_GetObservedBemfLevel(STO_PLL_Handle_t *pHandle); + +/* Enables/Disables additional reliability check based on observed Bemf. */ +void STO_PLL_BemfConsistencyCheckSwitch(STO_PLL_Handle_t *pHandle, bool bSel); + +/* Checks if the Bemf is consistent. */ +bool STO_PLL_IsBemfConsistent(STO_PLL_Handle_t *pHandle); + +/* Checks the value of the variance. */ +bool STO_PLL_IsVarianceTight(const STO_Handle_t *pHandle); + +/* Forces the state-observer to declare convergency. */ +void STO_PLL_ForceConvergency1(STO_Handle_t *pHandle); + +/* Forces the state-observer to declare convergency. */ +void STO_PLL_ForceConvergency2(STO_Handle_t *pHandle); + +/* Sets the Absolute value of minimum mechanical speed required to validate the start-up. + */ +void STO_SetMinStartUpValidSpeedUnit(STO_PLL_Handle_t *pHandle, + uint16_t hMinStartUpValidSpeed); + +/* Sets the rotation direction in the handler. */ +__weak void STO_SetDirection(STO_PLL_Handle_t *pHandle, int8_t direction); + +/** + * @} + */ + +/** + * @} + */ + + +#endif /*STO_PLL_SPEEDNPOSFDBK_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/sto_speed_pos_fdbk.h b/src/firmware/motor/mcsdk/sto_speed_pos_fdbk.h new file mode 100644 index 0000000000..57ded84a89 --- /dev/null +++ b/src/firmware/motor/mcsdk/sto_speed_pos_fdbk.h @@ -0,0 +1,86 @@ +/** + ****************************************************************************** + * @file sto_speed_pos_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains definitions and functions prototypes common to all + * State Observer based Speed & Position Feedback components of the Motor + * Control SDK (the CORDIC and PLL implementations). + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup SpeednPosFdbk + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STO_SPEEDNPOSFDBK_H +#define STO_SPEEDNPOSFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "speed_pos_fdbk.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednPosFdbk + * @{ + */ + + + /** @brief PWM & Current Sensing component handle type */ + typedef struct STO_Handle STO_Handle_t; + + typedef void (*STO_ForceConvergency1_Cb_t)(STO_Handle_t *pHandle); + typedef void (*STO_ForceConvergency2_Cb_t)(STO_Handle_t *pHandle); + typedef void (*STO_OtfResetPLL_Cb_t)(STO_Handle_t *pHandle); + typedef bool (*STO_SpeedReliabilityCheck_Cb_t)(const STO_Handle_t *pHandle); + + /** + * @brief Handle of the Speed and Position Feedback STO component. + * + */ + struct STO_Handle + { + SpeednPosFdbk_Handle_t *_Super; /**< @brief Speed and torque component handler. */ + STO_ForceConvergency1_Cb_t + pFctForceConvergency1; /**< @brief Function to force observer convergence. */ + STO_ForceConvergency2_Cb_t + pFctForceConvergency2; /**< @brief Function to force observer convergence. */ + STO_OtfResetPLL_Cb_t + pFctStoOtfResetPLL; /**< @brief Function to reset on the fly start-up. */ + STO_SpeedReliabilityCheck_Cb_t + pFctSTO_SpeedReliabilityCheck; /**< @brief Function to check the speed + reliability. */ + }; + + /** + * @} + */ + + /** + * @} + */ + + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /*STO_SPEEDNPOSFDBK_H*/ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/trajectory_ctrl.c b/src/firmware/motor/mcsdk/trajectory_ctrl.c new file mode 100644 index 0000000000..70e1b7ac0c --- /dev/null +++ b/src/firmware/motor/mcsdk/trajectory_ctrl.c @@ -0,0 +1,501 @@ +/** + ****************************************************************************** + * @file trajectory_ctrl.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implements the Position Control + * component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup PositionControl + */ + +/* Includes ------------------------------------------------------------------*/ +#include "trajectory_ctrl.h" + +#include "speed_pos_fdbk.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** + * @defgroup PositionControl Position Control + * + * @brief Position Control component of the Motor Control SDK + + * The Position Control component allows to control the movement of the motor in two + different ways: + * + * * Trajectory control mode, implemented by the TC_MoveCommand() function: allows to + move the motor to a specified + * target mechanical position in a settled time (duration) following a programmed + trajectory composed of three phases: + * 1- acceleration, 2- rotation at constant speed and 3- deceleration. + * * Follow mode, implemented by the TC_FollowCommand() function: This mode is for + instance useful when the trajectory is + * computed by an external controller, or by an algorithm defined by the user. + * The user can send at fixed rate, different target positions according to a required + trajectory and the position control + * algorithm computes the intermediate points to reach (follow) the target with a smooth + movement. + * + * The position controller uses a PID (with a proportional, integral and derivative + action) to regulate the angular position. + * + * @{ + */ + +/** + * @brief Initializes the handle of position control. + * @param pHandle handler of the current instance of the Position Control component. + * @param pPIDPosReg pointer on the handler of the current instance of PID used for the + position regulation. + * @param pSTC pointer on the handler of the current instance of the SpeednTorqCtrl + component. + * @param pENC handler of the current instance of the EncAlignCtrl component. + + */ +void TC_Init(PosCtrl_Handle_t *pHandle, PID_Handle_t *pPIDPosReg, + SpeednTorqCtrl_Handle_t *pSTC, ENCODER_Handle_t *pENC) +{ + pHandle->MovementDuration = 0.0f; + pHandle->AngleStep = 0.0f; + pHandle->SubStep[0] = 0.0f; + pHandle->SubStep[1] = 0.0f; + pHandle->SubStep[2] = 0.0f; + pHandle->SubStep[3] = 0.0f; + pHandle->SubStep[4] = 0.0f; + pHandle->SubStep[5] = 0.0f; + + pHandle->SubStepDuration = 0; + + pHandle->Jerk = 0.0f; + pHandle->CruiseSpeed = 0.0f; + pHandle->Acceleration = 0.0f; + pHandle->Omega = 0.0f; + pHandle->OmegaPrev = 0.0f; + pHandle->Theta = 0.0f; + pHandle->ThetaPrev = 0.0f; + pHandle->ReceivedTh = 0.0f; + pHandle->TcTick = 0; + pHandle->ElapseTime = 0.0f; + + pHandle->PositionControlRegulation = DISABLE; + pHandle->PositionCtrlStatus = TC_READY_FOR_COMMAND; + + pHandle->pENC = pENC; + pHandle->pSTC = pSTC; + pHandle->PIDPosRegulator = pPIDPosReg; + + pHandle->MecAngleOffset = 0; +} + +/** + * @brief Configures the trapezoidal speed trajectory. + * @param pHandle handler of the current instance of the Position Control component. + * @param startingAngle Current mechanical position. + * @param angleStep Target mechanical position. + * @param movementDuration Duration to reach the final position (in seconds). + * @retval ConfigurationStatus set to true when Trajectory command is programmed + * otherwise not yet ready for a new trajectory configuration. + * + * This function implements the Trajectory Control mode. When fDuration is different from + * 0, the trajectory of the movement, and therefore its acceleration and speed, are + * computed. + * + */ +bool TC_MoveCommand(PosCtrl_Handle_t *pHandle, float startingAngle, float angleStep, + float movementDuration) +{ + bool RetConfigStatus = false; + float fMinimumStepDuration; + + if ((pHandle->PositionCtrlStatus == TC_FOLLOWING_ON_GOING) && (movementDuration > 0)) + { + /* Back to Move command as the movement duration is different from 0 */ + pHandle->PositionCtrlStatus = TC_READY_FOR_COMMAND; + } + + if ((pHandle->PositionCtrlStatus == TC_READY_FOR_COMMAND) && (movementDuration > 0)) + { + pHandle->PositionControlRegulation = ENABLE; + + fMinimumStepDuration = (9.0f * pHandle->SamplingTime); + + // WARNING: Movement duration value is rounded to the nearest valid value + // [(DeltaT/9) / SamplingTime]: shall be an integer value + pHandle->MovementDuration = + (float)((int)(movementDuration / fMinimumStepDuration)) * + fMinimumStepDuration; + + pHandle->StartingAngle = startingAngle; + pHandle->AngleStep = angleStep; + pHandle->FinalAngle = startingAngle + angleStep; + + // SubStep duration = DeltaT/9 (DeltaT represents the total duration of the + // programmed movement) + pHandle->SubStepDuration = pHandle->MovementDuration / 9.0f; + + // Sub step of acceleration phase + pHandle->SubStep[0] = + 1 * pHandle->SubStepDuration; /* Sub-step 1 of acceleration phase */ + pHandle->SubStep[1] = + 2 * pHandle->SubStepDuration; /* Sub-step 2 of acceleration phase */ + pHandle->SubStep[2] = + 3 * pHandle->SubStepDuration; /* Sub-step 3 of acceleration phase */ + + // Sub step of deceleration Phase + pHandle->SubStep[3] = + 6 * pHandle->SubStepDuration; /* Sub-step 1 of deceleration phase */ + pHandle->SubStep[4] = + 7 * pHandle->SubStepDuration; /* Sub-step 2 of deceleration phase */ + pHandle->SubStep[5] = + 8 * pHandle->SubStepDuration; /* Sub-step 3 of deceleration phase */ + + // Jerk (J) to be used by the trajectory calculator to integrate (step by step) + // the target position. J = DeltaTheta/(12 * A * A * A) => DeltaTheta = final + // position and A = Sub-Step duration + pHandle->Jerk = + pHandle->AngleStep / (12 * pHandle->SubStepDuration * + pHandle->SubStepDuration * pHandle->SubStepDuration); + + // Speed cruiser = 2*J*A*A) + pHandle->CruiseSpeed = + 2 * pHandle->Jerk * pHandle->SubStepDuration * pHandle->SubStepDuration; + + pHandle->ElapseTime = 0.0f; + + pHandle->Omega = 0.0f; + pHandle->Acceleration = 0.0f; + pHandle->Theta = startingAngle; + + pHandle->PositionCtrlStatus = + TC_MOVEMENT_ON_GOING; /* new trajectory has been programmed */ + + RetConfigStatus = true; + } + return (RetConfigStatus); +} + +/** + * @brief Follows an angular position command. + * @param pHandle handler of the current instance of the Position Control component. + * @param Angle Target mechanical position. + * + * This function implements the Follow mode. When the duration is set to zero, the user + * can send at fixed rate different target positions according to a required trajectory + * and the position control algorithm computes the intermediate points to reach (follow) + * the target with a smooth movement. This mode is for instance useful when the trajectory + * is computed by an external controller, or by an algorithm defined by the user and + * executed by the same microcontroller. + * + */ +void TC_FollowCommand(PosCtrl_Handle_t *pHandle, float Angle) +{ + float omega = 0, acceleration = 0, dt = 0; + + // Estimate speed + if (pHandle->ReceivedTh > 0) + { + // Calculate dt + dt = pHandle->TcTick * pHandle->SysTickPeriod; + pHandle->TcTick = 0; + if (dt > 0) + { + omega = (Angle - pHandle->ThetaPrev) / dt; + } + } + + // Estimated acceleration + if (pHandle->ReceivedTh > 1) + { + if (dt > 0) + { + acceleration = (omega - pHandle->OmegaPrev) / dt; + } + } + + // Update state variable + pHandle->ThetaPrev = Angle; + pHandle->OmegaPrev = omega; + if (pHandle->ReceivedTh < 2) + { + pHandle->ReceivedTh++; + } + + pHandle->Acceleration = acceleration; + pHandle->Omega = omega; + pHandle->Theta = Angle; + + pHandle->PositionCtrlStatus = + TC_FOLLOWING_ON_GOING; /* follow mode has been programmed */ + pHandle->MovementDuration = 0; + return; +} + +/** + * @brief Proceeds on the position control loop. + * @param pHandle: handler of the current instance of the Position Control component. + */ +void TC_PositionRegulation(PosCtrl_Handle_t *pHandle) +{ + int32_t wMecAngleRef; + int32_t wMecAngle; + int32_t wError; + int32_t hTorqueRef_Pos; + + if (pHandle->PositionCtrlStatus == TC_MOVEMENT_ON_GOING) + { + TC_MoveExecution(pHandle); + } + + if (pHandle->PositionCtrlStatus == TC_FOLLOWING_ON_GOING) + { + TC_FollowExecution(pHandle); + } + + if (pHandle->PositionControlRegulation == ENABLE) + { + wMecAngleRef = (int32_t)(pHandle->Theta * RADTOS16); + + wMecAngle = SPD_GetMecAngle(STC_GetSpeedSensor(pHandle->pSTC)); + wError = wMecAngleRef - wMecAngle; + hTorqueRef_Pos = PID_Controller(pHandle->PIDPosRegulator, wError); + + STC_SetControlMode(pHandle->pSTC, MCM_TORQUE_MODE); + STC_ExecRamp(pHandle->pSTC, hTorqueRef_Pos, 0); + } +} + +/** + * @brief Executes the programmed trajectory movement. + * @param pHandle handler of the current instance of the Position Control component. + */ +void TC_MoveExecution(PosCtrl_Handle_t *pHandle) +{ + float jerkApplied = 0; + + if (pHandle->ElapseTime < + pHandle->SubStep[0]) /* 1st Sub-Step interval time of acceleration phase */ + { + jerkApplied = pHandle->Jerk; + } + else if (pHandle->ElapseTime < + pHandle->SubStep[1]) /* 2nd Sub-Step interval time of acceleration phase */ + { + } + else if (pHandle->ElapseTime < + pHandle->SubStep[2]) /* 3rd Sub-Step interval time of acceleration phase */ + { + jerkApplied = -(pHandle->Jerk); + } + else if (pHandle->ElapseTime < + pHandle->SubStep[3]) /* Speed Cruise phase (after acceleration and before + deceleration phases) */ + { + pHandle->Acceleration = 0.0f; + pHandle->Omega = pHandle->CruiseSpeed; + } + else if (pHandle->ElapseTime < + pHandle->SubStep[4]) /* 1st Sub-Step interval time of deceleration phase */ + { + jerkApplied = -(pHandle->Jerk); + } + else if (pHandle->ElapseTime < + pHandle->SubStep[5]) /* 2nd Sub-Step interval time of deceleration phase */ + { + } + else if (pHandle->ElapseTime < + pHandle->MovementDuration) /* 3rd Sub-Step interval time of deceleration + phase */ + { + jerkApplied = pHandle->Jerk; + } + else + { + pHandle->Theta = pHandle->FinalAngle; + pHandle->PositionCtrlStatus = TC_TARGET_POSITION_REACHED; + } + + if (TC_MOVEMENT_ON_GOING == pHandle->PositionCtrlStatus) + { + pHandle->Acceleration += jerkApplied * pHandle->SamplingTime; + pHandle->Omega += pHandle->Acceleration * pHandle->SamplingTime; + pHandle->Theta += pHandle->Omega * pHandle->SamplingTime; + } + + pHandle->ElapseTime += pHandle->SamplingTime; + + if (TC_RampCompleted(pHandle)) + { + if (TC_ZERO_ALIGNMENT_START == pHandle->AlignmentStatus) + { + // Ramp is used to search the zero index, if completed there is no z signal + pHandle->AlignmentStatus = TC_ALIGNMENT_ERROR; + } + pHandle->ElapseTime = 0; + pHandle->PositionCtrlStatus = TC_READY_FOR_COMMAND; + } +} + +/** + * @brief Updates the angular position. + * @param pHandle handler of the current instance of the Position Control component. + */ +void TC_FollowExecution(PosCtrl_Handle_t *pHandle) +{ + pHandle->Omega += pHandle->Acceleration * pHandle->SamplingTime; + pHandle->Theta += pHandle->Omega * pHandle->SamplingTime; +} + +/** + * @brief Handles the alignment phase at starting before any position commands. + * @param pHandle: handler of the current instance of the Position Control component. + */ +void TC_EncAlignmentCommand(PosCtrl_Handle_t *pHandle) +{ + int32_t wMecAngleRef; + + if (TC_ALIGNMENT_COMPLETED == pHandle->AlignmentStatus) + { + pHandle->PositionCtrlStatus = TC_READY_FOR_COMMAND; + // Do nothing - EncAlignment must be done only one time after the power on + } + else + { + if (pHandle->AlignmentCfg == TC_ABSOLUTE_ALIGNMENT_SUPPORTED) + { + // If index is supported start the search of the zero + pHandle->EncoderAbsoluteAligned = false; + wMecAngleRef = SPD_GetMecAngle(STC_GetSpeedSensor(pHandle->pSTC)); + TC_MoveCommand(pHandle, (float)(wMecAngleRef) / RADTOS16, + Z_ALIGNMENT_NB_ROTATION, Z_ALIGNMENT_DURATION); + pHandle->AlignmentStatus = TC_ZERO_ALIGNMENT_START; + } + else + { + // If index is not supprted set the alignment angle as zero reference + pHandle->pENC->_Super.wMecAngle = 0; + pHandle->AlignmentStatus = TC_ALIGNMENT_COMPLETED; + pHandle->PositionCtrlStatus = TC_READY_FOR_COMMAND; + pHandle->PositionControlRegulation = ENABLE; + } + } +} + +/** + * @brief It controls if time allowed for movement is completed. + * @param pHandle: handler of the current instance of the Position Control component. + * @retval Status return true when the programmed trajectory movement is completed + * false when the trajectory movement execution is still ongoing. + */ +bool TC_RampCompleted(PosCtrl_Handle_t *pHandle) +{ + bool retVal = false; + + // Check that entire sequence (Acceleration - Cruise - Deceleration) is completed. + if (pHandle->ElapseTime > pHandle->MovementDuration + pHandle->SamplingTime) + { + retVal = true; + } + return (retVal); +} + +/** + * @brief Set the absolute zero mechanical position. + * @param pHandle: handler of the current instance of the Position Control component. + */ +void TC_EncoderReset(PosCtrl_Handle_t *pHandle) +{ + if ((!pHandle->EncoderAbsoluteAligned) && + (pHandle->AlignmentStatus == TC_ZERO_ALIGNMENT_START)) + { + pHandle->MecAngleOffset = pHandle->pENC->_Super.hMecAngle; + pHandle->pENC->_Super.wMecAngle = 0; + pHandle->EncoderAbsoluteAligned = true; + pHandle->AlignmentStatus = TC_ALIGNMENT_COMPLETED; + pHandle->PositionCtrlStatus = TC_READY_FOR_COMMAND; + pHandle->Theta = 0.0f; + ENC_SetMecAngle(pHandle->pENC, pHandle->MecAngleOffset); + } +} + +/** + * @brief Returns the current rotor mechanical angle, expressed in radiant. + * @param pHandle: handler of the current instance of the Position Control component. + * @retval current mechanical position + */ +float TC_GetCurrentPosition(PosCtrl_Handle_t *pHandle) +{ + return ((float)((SPD_GetMecAngle(STC_GetSpeedSensor(pHandle->pSTC))) / RADTOS16)); +} + +/** + * @brief Returns the target rotor mechanical angle, expressed in radiant. + * @param pHandle: handler of the current instance of the Position Control component. + * @retval Target mechanical position + */ +float TC_GetTargetPosition(PosCtrl_Handle_t *pHandle) +{ + return (pHandle->FinalAngle); +} + +/** + * @brief Returns the duration used to execute the movement, expressed in seconds. + * @param pHandle handler of the current instance of the Position Control component. + * @retval Duration of programmed movement + */ +float TC_GetMoveDuration(PosCtrl_Handle_t *pHandle) +{ + return (pHandle->MovementDuration); +} + +/** + * @brief Returns the status of the position control execution. + * @param pHandle: handler of the current instance of the Position Control component. + * @retval Position Control Status + */ +PosCtrlStatus_t TC_GetControlPositionStatus(PosCtrl_Handle_t *pHandle) +{ + return (pHandle->PositionCtrlStatus); +} + +/** + * @brief Returns the status after the rotor alignment phase. + * @param pHandle handler of the current instance of the Position Control component. + */ +AlignStatus_t TC_GetAlignmentStatus(PosCtrl_Handle_t *pHandle) +{ + return (pHandle->AlignmentStatus); +} + +/** + * @brief Increments Tick counter used in follow mode. + * @param pHandle handler of the current instance of the Position Control component. + */ +void TC_IncTick(PosCtrl_Handle_t *pHandle) +{ + pHandle->TcTick++; +} + + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/trajectory_ctrl.h b/src/firmware/motor/mcsdk/trajectory_ctrl.h new file mode 100644 index 0000000000..264b162a32 --- /dev/null +++ b/src/firmware/motor/mcsdk/trajectory_ctrl.h @@ -0,0 +1,187 @@ +/** + ****************************************************************************** + * @file trajectory_ctrl.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides all definitions and functions prototypes for the + * the Position Control component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup PositionControl + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef TRAJCTRL_H +#define TRAJCTRL_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "enc_align_ctrl.h" +#include "mc_type.h" +#include "speed_torq_ctrl.h" + +#define RADTOS16 10430.378350470452725f /* 2^15/Pi */ + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define Z_ALIGNMENT_DURATION 2 /* 2 seconds */ +#define Z_ALIGNMENT_NB_ROTATION \ + (2.0f * M_PI) /* 1 turn in 2 seconds allowed to find the "Z" signal */ + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup PositionControl + * @{ + */ + + typedef enum + { + TC_READY_FOR_COMMAND = 0, + TC_MOVEMENT_ON_GOING = 1, + TC_TARGET_POSITION_REACHED = 2, + TC_FOLLOWING_ON_GOING = 3 + } PosCtrlStatus_t; + + typedef enum + { + TC_AWAITING_FOR_ALIGNMENT = 0, + TC_ZERO_ALIGNMENT_START = 1, + TC_ALIGNMENT_COMPLETED = 2, + TC_ABSOLUTE_ALIGNMENT_NOT_SUPPORTED = + 3, /* Encoder sensor without "Z" output signal */ + TC_ABSOLUTE_ALIGNMENT_SUPPORTED = 4, + TC_ALIGNMENT_ERROR = 5, + } AlignStatus_t; + + /** + * @brief Handle of a Position Control component + */ + typedef struct + { + float MovementDuration; /**< @brief Total duration of the programmed movement */ + float StartingAngle; /**< @brief Current mechanical position */ + float + FinalAngle; /**< @brief Target mechanical position including start position */ + float AngleStep; /**< @brief Target mechanical position */ + float SubStep[6]; /**< @brief Sub step interval time of acceleration and + deceleration phases */ + float SubStepDuration; /**< @brief Sub step time duration of sequence : + acceleration / cruise / deceleration */ + float ElapseTime; /**< @brief Elapse time during trajectory movement execution */ + float SamplingTime; /**< @brief Sampling time at which the movement regulation is + called (at 1/MEDIUM_FREQUENCY_TASK_RATE) */ + float Jerk; /**< @brief Angular jerk, rate of change of the angular acceleration + with respect to time */ + float CruiseSpeed; /**< @brief Angular velocity during the time interval after + acceleration and before deceleration */ + float Acceleration; /**< @brief Angular acceleration in rad/s^2 */ + float Omega; /**< @brief Estimated angular speed in rad/s */ + float OmegaPrev; /**< @brief Previous estimated angular speed of frame (N-1) */ + float Theta; /**< @brief Current angular position */ + float ThetaPrev; /**< @brief Angular position of frame (N-1) */ + uint8_t ReceivedTh; /**< @brief At startup of follow mode, need to receive two + angles to compute the speed and acceleration */ + bool PositionControlRegulation; /**< @brief Flag to activate the position control + regulation */ + bool EncoderAbsoluteAligned; /**< @brief Flag to indicate that absolute zero + alignement is done */ + int16_t MecAngleOffset; /**< @brief Store rotor mechanical angle offset */ + uint32_t TcTick; /**< @brief Tick counter in follow mode */ + float SysTickPeriod; /**< @brief Time base of follow mode */ + + PosCtrlStatus_t PositionCtrlStatus; /**< @brief Trajectory execution status */ + AlignStatus_t AlignmentCfg; /**< @brief Indicates that zero index is supported for + absolute alignment */ + AlignStatus_t AlignmentStatus; /**< @brief Alignement procedure status */ + + ENCODER_Handle_t *pENC; /**< @brief Pointer on handler of the current instance of + the encoder component */ + SpeednTorqCtrl_Handle_t *pSTC; /**< @brief Speed and torque controller object used + by the Position Regulator */ + PID_Handle_t *PIDPosRegulator; /**< @brief PID controller object used by the + Position Regulator */ + } PosCtrl_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + + /* Initializes Trajectory Control component handler */ + void TC_Init(PosCtrl_Handle_t *pHandle, PID_Handle_t *pPIDPosReg, + SpeednTorqCtrl_Handle_t *pSTC, ENCODER_Handle_t *pENC); + + /* Configures the trapezoidal speed trajectory */ + bool TC_MoveCommand(PosCtrl_Handle_t *pHandle, float startingAngle, float angleStep, + float movementDuration); + + /* Follows an angular position command */ + void TC_FollowCommand(PosCtrl_Handle_t *pHandle, float Angle); + + /* Proceeds on the position control loop */ + void TC_PositionRegulation(PosCtrl_Handle_t *pHandle); + + /* Executes the programmed trajectory movement */ + void TC_MoveExecution(PosCtrl_Handle_t *pHandle); + + /* Updates the angular position */ + void TC_FollowExecution(PosCtrl_Handle_t *pHandle); + + /* Handles the alignment phase at starting before any position commands */ + void TC_EncAlignmentCommand(PosCtrl_Handle_t *pHandle); + + /* Checks if time allowed for movement is completed */ + bool TC_RampCompleted(PosCtrl_Handle_t *pHandle); + + /* Sets the absolute zero mechanical position */ + void TC_EncoderReset(PosCtrl_Handle_t *pHandle); + + /* Returns the current rotor mechanical angle, expressed in radiant */ + float TC_GetCurrentPosition(PosCtrl_Handle_t *pHandle); + + /* Returns the target rotor mechanical angle, expressed in radiant */ + float TC_GetTargetPosition(PosCtrl_Handle_t *pHandle); + + /* Returns the duration used to execute the movement, expressed in seconds */ + float TC_GetMoveDuration(PosCtrl_Handle_t *pHandle); + + /* Returns the status of the position control execution */ + PosCtrlStatus_t TC_GetControlPositionStatus(PosCtrl_Handle_t *pHandle); + + /* Returns the status after the rotor alignment phase */ + AlignStatus_t TC_GetAlignmentStatus(PosCtrl_Handle_t *pHandle); + + /* Increments Tick counter used in follow mode */ + void TC_IncTick(PosCtrl_Handle_t *pHandle); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* TRAJCTRL_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/usart_aspep_driver.h b/src/firmware/motor/mcsdk/usart_aspep_driver.h new file mode 100644 index 0000000000..5b5b8470d7 --- /dev/null +++ b/src/firmware/motor/mcsdk/usart_aspep_driver.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * @file usart_aspep_driver.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * uart driver for the aspep protocol. + * + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +#ifndef usart_aspep_driver_h +#define usart_aspep_driver_h + +#include +#include + +/* To be removed no protocol awarness at this level */ + +typedef struct +{ + USART_TypeDef *USARTx; + DMA_TypeDef *rxDMA; + DMA_TypeDef *txDMA; + uint32_t rxChannel; + uint32_t txChannel; +} UASPEP_Handle_t; + +bool UASPEP_SEND_PACKET(void *pHWHandle, void *data, uint16_t length); +void UASPEP_RECEIVE_BUFFER(void *pHWHandle, void *buffer, uint16_t length); +void UASPEP_INIT(void *pHWHandle); +void UASPEP_IDLE_ENABLE(void *pHWHandle); + +#endif +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/virtual_bus_voltage_sensor.c b/src/firmware/motor/mcsdk/virtual_bus_voltage_sensor.c new file mode 100644 index 0000000000..c3c53ffb18 --- /dev/null +++ b/src/firmware/motor/mcsdk/virtual_bus_voltage_sensor.c @@ -0,0 +1,86 @@ +/** + ****************************************************************************** + * @file virtual_bus_voltage_sensor.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Virtual Bus Voltage Sensor component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup VirtualBusVoltageSensor + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/virtual_bus_voltage_sensor.h" + +#include "firmware/motor/common_defs.h" + + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup BusVoltageSensor + * @{ + */ + +/** @defgroup VirtualBusVoltageSensor Virtual Bus Voltage Sensor + * @brief Virtual Bus Voltage Sensor implementation. + * + * @{ + */ + +/** + * @brief It initializes bus voltage conversion for virtual bus voltage sensor + * (latest value and averaged value) with expected VBus value + * @param pHandle related Handle of VirtualBusVoltageSensor_Handle_t + * @retval none + */ +__weak void VVBS_Init(VirtualBusVoltageSensor_Handle_t *pHandle) +{ + pHandle->_Super.FaultState = MC_NO_ERROR; + pHandle->_Super.LatestConv = pHandle->ExpectedVbus_d; + pHandle->_Super.AvBusVoltage_d = pHandle->ExpectedVbus_d; +} + +/** + * @brief Empty function (no process and no returned value) + * @param pHandle related Handle of VirtualBusVoltageSensor_Handle_t + * @retval none + */ +__weak void VVBS_Clear(VirtualBusVoltageSensor_Handle_t *pHandle) +{ + return; +} + +/** + * @brief It returns MC_NO_ERROR + * @param pHandle related Handle of VirtualBusVoltageSensor_Handle_t + * @retval uint16_t Fault code error: MC_NO_ERROR + */ +__weak uint16_t VVBS_NoErrors(VirtualBusVoltageSensor_Handle_t *pHandle) +{ + return (MC_NO_ERROR); +} + +/** + * @} + */ + +/** + * @} + */ + +/** @} */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/virtual_bus_voltage_sensor.h b/src/firmware/motor/mcsdk/virtual_bus_voltage_sensor.h new file mode 100644 index 0000000000..4010cab5c5 --- /dev/null +++ b/src/firmware/motor/mcsdk/virtual_bus_voltage_sensor.h @@ -0,0 +1,81 @@ +/** + ****************************************************************************** + * @file virtual_bus_voltage_sensor.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Virtual Bus Voltage Sensor component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup VirtualBusVoltageSensor + */ + + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef VIRTUAL_BUSVOLTAGESENSOR_H +#define VIRTUAL_BUSVOLTAGESENSOR_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "bus_voltage_sensor.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup BusVoltageSensor + * @{ + */ + + /** @addtogroup VirtualBusVoltageSensor + * @{ + */ + + /** + * @brief Virtual Vbus sensor class parameters definition + */ + typedef struct + { + BusVoltageSensor_Handle_t _Super; /*!< Bus voltage sensor component handle. */ + + uint16_t ExpectedVbus_d; /*!< Expected Vbus voltage expressed in + digital value + hOverVoltageThreshold(digital value)= + Over Voltage Threshold (V) * 65536 + / 500 */ + } VirtualBusVoltageSensor_Handle_t; + + /* Exported functions ------------------------------------------------------- */ + void VVBS_Init(VirtualBusVoltageSensor_Handle_t *pHandle); + void VVBS_Clear(VirtualBusVoltageSensor_Handle_t *pHandle); + uint16_t VVBS_NoErrors(VirtualBusVoltageSensor_Handle_t *pHandle); + +/** + * @} + */ + +/** + * @} + */ + +/** @} */ +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* VIRTUAL_BUSVOLTAGESENSOR_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/virtual_speed_sensor.c b/src/firmware/motor/mcsdk/virtual_speed_sensor.c new file mode 100644 index 0000000000..22e66e549f --- /dev/null +++ b/src/firmware/motor/mcsdk/virtual_speed_sensor.c @@ -0,0 +1,623 @@ +/** + ****************************************************************************** + * @file virtual_speed_sensor.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the features + * of the Virtual Speed Sensor component of the Motor Control SDK. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup VirtualSpeedSensor + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/virtual_speed_sensor.h" + +#include "firmware/motor/common_defs.h" + + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup SpeednPosFdbk + * @{ + */ + +/** @defgroup VirtualSpeedSensor Virtual Speed & Position Feedback + * @brief Virtual Speed Speed & Position Feedback implementation + * + * This component provides a "virtual" implementation of the speed and position feedback + * features. This implementation provides a theoretical estimation of the speed and + * position of the rotor of the motor based on a mechanical acceleration and an initial + * angle set by the application. + * + * This component is used during the @ref RevUpCtrl "Rev-Up Control" phases of the motor + * or in an + * @ref OpenLoop "Open Loop Control" configuration in a sensorless subsystem. + * + * + * @{ + */ + +/** + * @brief Software initialization of VirtualSpeedSensor component. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @retval none + * + * - Calls VSS_Clear. + * - Called at initialization of the whole MC core. + */ +__weak void VSS_Init(VirtualSpeedSensor_Handle_t *pHandle) +{ + VSS_Clear(pHandle); +} + +/** + * @brief Software initialization of VSS object to be performed at each restart + * of the motor. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @retval none + */ +__weak void VSS_Clear(VirtualSpeedSensor_Handle_t *pHandle) +{ +#ifdef NULL_PTR_VIR_SPD_SEN + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->_Super.bSpeedErrorNumber = 0U; + pHandle->_Super.hElAngle = 0; + pHandle->_Super.hMecAngle = 0; + pHandle->_Super.hAvrMecSpeedUnit = 0; + pHandle->_Super.hElSpeedDpp = 0; + pHandle->_Super.hMecAccelUnitP = 0; + pHandle->_Super.bSpeedErrorNumber = 0U; + + pHandle->wElAccDppP32 = 0; + pHandle->wElSpeedDpp32 = 0; + pHandle->hRemainingStep = 0U; + pHandle->hElAngleAccu = 0; + + pHandle->bTransitionStarted = false; + pHandle->bTransitionEnded = false; + pHandle->hTransitionRemainingSteps = pHandle->hTransitionSteps; + pHandle->bTransitionLocked = false; + + pHandle->bCopyObserver = false; +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section(".ccmram"))) +#endif +#endif +/** + * @brief Updates the rotor electrical angle integrating the last settled + * instantaneous electrical speed express in [dpp](measurement_units.md). + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @retval int16_t Measured electrical angle in s16degree format. + * + * - Systematically called after #SPD_GetElAngle that retrieves last computed rotor + * electrical angle. + */ +__weak int16_t VSS_CalcElAngle(VirtualSpeedSensor_Handle_t *pHandle, + int16_t *pInputVars_str) +{ + int16_t hRetAngle; +#ifdef NULL_PTR_VIR_SPD_SEN + if ((MC_NULL == pHandle) || (MC_NULL == pInputVars_str)) + { + hRetAngle = 0; + } + else + { +#endif + int16_t hAngleDiff; + int32_t wAux; + int16_t hAngleCorr; + int16_t hSignCorr = 1; + + if (true == pHandle->bCopyObserver) + { + hRetAngle = *(int16_t *)pInputVars_str; + } + else + { + pHandle->hElAngleAccu += pHandle->_Super.hElSpeedDpp; + pHandle->_Super.hMecAngle += + (pHandle->_Super.hElSpeedDpp / (int16_t)pHandle->_Super.bElToMecRatio); + + if (true == pHandle->bTransitionStarted) + { + if (0 == pHandle->hTransitionRemainingSteps) + { + hRetAngle = *(int16_t *)pInputVars_str; + pHandle->bTransitionEnded = true; + pHandle->_Super.bSpeedErrorNumber = 0U; + } + else + { + pHandle->hTransitionRemainingSteps--; + + if (pHandle->_Super.hElSpeedDpp >= 0) + { + hAngleDiff = *(int16_t *)pInputVars_str - pHandle->hElAngleAccu; + } + else + { + hAngleDiff = pHandle->hElAngleAccu - *(int16_t *)pInputVars_str; + hSignCorr = -1; + } + + wAux = (int32_t)hAngleDiff * pHandle->hTransitionRemainingSteps; + hAngleCorr = (int16_t)(wAux / pHandle->hTransitionSteps); + hAngleCorr *= hSignCorr; + + if (hAngleDiff >= 0) + { + pHandle->bTransitionLocked = true; + hRetAngle = *(int16_t *)pInputVars_str - hAngleCorr; + } + else + { + if (false == pHandle->bTransitionLocked) + { + hRetAngle = pHandle->hElAngleAccu; + } + else + { + hRetAngle = *(int16_t *)pInputVars_str + hAngleCorr; + } + } + } + } + else + { + hRetAngle = pHandle->hElAngleAccu; + } + } + + pHandle->_Super.hElAngle = hRetAngle; +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif + return (hRetAngle); +} + +/** + * @brief Computes and stores rotor instantaneous electrical speed (express + * in [dpp](measurement_units.md) considering the measurement frequency) in order + * to provide it to #SPD_GetElAngle. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @param hMecSpeedUnit pointer to int16_t, used to return the rotor average + * mechanical speed [SPEED_UNIT](measurement_units.md). + * @retval bool true = sensor information is reliable and false = sensor information is + * not reliable. + * + * - Stores and returns through parameter hMecSpeedUnit the rotor average mechanical + * speed, expressed in the unit defined by [SPEED_UNIT](measurement_units.md). + * - Returns the reliability state of the sensor (always true). + * - Called with the same periodicity on which speed control is executed, precisely during + * START and SWITCH_OVER states of the MC tasks state machine or in its RUM state in @ref + * OpenLoop "Open Loop Control" configuration into TSK_MediumFrequencyTask. + */ +__weak bool VSS_CalcAvrgMecSpeedUnit(VirtualSpeedSensor_Handle_t *pHandle, + int16_t *hMecSpeedUnit) +{ + bool SpeedSensorReliability; +#ifdef NULL_PTR_VIR_SPD_SEN + if ((MC_NULL == pHandle) || (MC_NULL == hMecSpeedUnit)) + { + SpeedSensorReliability = false; + } + else + { +#endif + if (pHandle->hRemainingStep > 1u) + { + pHandle->wElSpeedDpp32 += pHandle->wElAccDppP32; +#ifndef FULL_MISRA_C_COMPLIANCY_VIRT_SPD_SENS + // cstat !MISRAC2012-Rule-1.3_n !ATH-shift-neg !MISRAC2012-Rule-10.1_R6 + pHandle->_Super.hElSpeedDpp = (int16_t)(pHandle->wElSpeedDpp32 >> 16); +#else + pHandle->_Super.hElSpeedDpp = (int16_t)(pHandle->wElSpeedDpp32 / 65536); +#endif + + /* Convert dpp into MecUnit */ + *hMecSpeedUnit = (int16_t)((((int32_t)pHandle->_Super.hElSpeedDpp) * + ((int32_t)pHandle->_Super.hMeasurementFrequency) * + SPEED_UNIT) / + (((int32_t)pHandle->_Super.DPPConvFactor) * + ((int32_t)pHandle->_Super.bElToMecRatio))); + pHandle->_Super.hAvrMecSpeedUnit = *hMecSpeedUnit; + pHandle->hRemainingStep--; + } + else if (1U == pHandle->hRemainingStep) + { + *hMecSpeedUnit = pHandle->hFinalMecSpeedUnit; + pHandle->_Super.hAvrMecSpeedUnit = *hMecSpeedUnit; + pHandle->_Super.hElSpeedDpp = + (int16_t)((((int32_t)*hMecSpeedUnit) * + ((int32_t)pHandle->_Super.DPPConvFactor)) / + (((int32_t)SPEED_UNIT) * + ((int32_t)pHandle->_Super.hMeasurementFrequency))); + pHandle->_Super.hElSpeedDpp *= ((int16_t)pHandle->_Super.bElToMecRatio); + pHandle->hRemainingStep = 0U; + } + else + { + *hMecSpeedUnit = pHandle->_Super.hAvrMecSpeedUnit; + } + /* If the transition is not done yet, we already know that speed is not reliable + */ + if (false == pHandle->bTransitionEnded) + { + pHandle->_Super.bSpeedErrorNumber = pHandle->_Super.bMaximumSpeedErrorsNumber; + SpeedSensorReliability = false; + } + else + { + SpeedSensorReliability = + SPD_IsMecSpeedReliable(&pHandle->_Super, hMecSpeedUnit); + } +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif + return (SpeedSensorReliability); +} + +/** + * @brief Sets instantaneous information on VSS mechanical and electrical angle. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @param hMecAngle: instantaneous measure of rotor mechanical angle. + * @retval none + * + * - Called during @ref RevUpCtrl "Rev-Up Control" and + * @ref EncAlignCtrl "Encoder Alignment Controller procedure" initialization. + */ +__weak void VSS_SetMecAngle(VirtualSpeedSensor_Handle_t *pHandle, int16_t hMecAngle) +{ +#ifdef NULL_PTR_VIR_SPD_SEN + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hElAngleAccu = hMecAngle; + pHandle->_Super.hMecAngle = + pHandle->hElAngleAccu / ((int16_t)pHandle->_Super.bElToMecRatio); + pHandle->_Super.hElAngle = hMecAngle; +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif +} + +/** + * @brief Sets the mechanical acceleration of virtual speed sensor. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @param hFinalMecSpeedUnit mechanical speed assumed by + * the virtual speed sensor at the end of the duration. Expressed in the unit + * defined by [SPEED_UNIT](measurement_units.md). + * @param hDurationms: Duration expressed in ms. It can be 0 to apply + * instantaneous the final speed. + * @retval none + * + * - This acceleration is defined starting from current mechanical speed, final mechanical + * speed expressed in [SPEED_UNIT](measurement_units.md) and duration expressed in + * milliseconds. + * - Called during @ref RevUpCtrl "Rev-Up Control" and + * @ref EncAlignCtrl "Encoder Alignment Controller procedure" initialization. + */ +__weak void VSS_SetMecAcceleration(VirtualSpeedSensor_Handle_t *pHandle, + int16_t hFinalMecSpeedUnit, uint16_t hDurationms) +{ +#ifdef NULL_PTR_VIR_SPD_SEN + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + int32_t wMecAccDppP32; + uint16_t hNbrStep; + int16_t hCurrentMecSpeedDpp; + int16_t hFinalMecSpeedDpp; + + if (false == pHandle->bTransitionStarted) + { + if (0U == hDurationms) + { + pHandle->_Super.hAvrMecSpeedUnit = hFinalMecSpeedUnit; + + pHandle->_Super.hElSpeedDpp = + (int16_t)((((int32_t)hFinalMecSpeedUnit) * + ((int32_t)pHandle->_Super.DPPConvFactor)) / + (((int32_t)SPEED_UNIT) * + ((int32_t)pHandle->_Super.hMeasurementFrequency))); + + pHandle->_Super.hElSpeedDpp *= ((int16_t)pHandle->_Super.bElToMecRatio); + + pHandle->hRemainingStep = 0U; + + pHandle->hFinalMecSpeedUnit = hFinalMecSpeedUnit; + } + else + { + hNbrStep = (uint16_t)((((uint32_t)hDurationms) * + ((uint32_t)pHandle->hSpeedSamplingFreqHz)) / + 1000U); + hNbrStep++; + pHandle->hRemainingStep = hNbrStep; + hCurrentMecSpeedDpp = pHandle->_Super.hElSpeedDpp / + ((int16_t)pHandle->_Super.bElToMecRatio); + hFinalMecSpeedDpp = + (int16_t)((((int32_t)hFinalMecSpeedUnit) * + ((int32_t)pHandle->_Super.DPPConvFactor)) / + (((int32_t)SPEED_UNIT) * + ((int32_t)pHandle->_Super.hMeasurementFrequency))); + + if (0U == hNbrStep) + { + /* Nothing to do */ + } + else + { + wMecAccDppP32 = + ((((int32_t)hFinalMecSpeedDpp) - ((int32_t)hCurrentMecSpeedDpp)) * + ((int32_t)65536)) / + ((int32_t)hNbrStep); + + pHandle->wElAccDppP32 = + wMecAccDppP32 * ((int16_t)pHandle->_Super.bElToMecRatio); + } + + pHandle->hFinalMecSpeedUnit = hFinalMecSpeedUnit; + + pHandle->wElSpeedDpp32 = + ((int32_t)pHandle->_Super.hElSpeedDpp) * ((int32_t)65536); + } + } +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif +} + +/** + * @brief Checks if the ramp executed after a #VSS_SetMecAcceleration command + * has been completed by checking zero value of the Number of steps remaining to + * reach the final speed. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @retval bool: true if the ramp is completed, otherwise false. + * + * - Not used into current implementation. + */ +__weak bool VSS_RampCompleted(VirtualSpeedSensor_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_VIR_SPD_SEN + if (MC_NULL == pHandle) + { + /* nothing to do */ + } + else + { +#endif + if (0U == pHandle->hRemainingStep) + { + retVal = true; + } + else + { + /* Nothing to do */ + } +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif + return (retVal); +} + +/** + * @brief Gets the final speed of last settled ramp of virtual speed sensor expressed + in [SPEED_UNIT](measurement_units.md). + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @retval none + * + * - Will be call for future dual motor implementation into START state of MC tasks state + machine into TSK_MediumFrequencyTask. + */ +__weak int16_t VSS_GetLastRampFinalSpeed(VirtualSpeedSensor_Handle_t *pHandle) +{ +#ifdef NULL_PTR_VIR_SPD_SEN + return ((MC_NULL == pHandle) ? 0 : pHandle->hFinalMecSpeedUnit); +#else + return (pHandle->hFinalMecSpeedUnit); +#endif +} + +/** + * @brief Sets the command to Start the transition phase from Virtual Speed Sensor + * to other Speed Sensor. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @param bool: true to Start the transition phase, false has no effect. + * @retval bool: true if Transition phase is enabled (started or not), false if + * transition has been triggered but it's actually disabled + * (parameter #hTransitionSteps = 0). + * + * - Transition is to be considered ended when Sensor information is + * declared 'Reliable' or if function returned value is false. + * - Called into START state of MC tasks state machine into TSK_MediumFrequencyTask. + */ +__weak bool VSS_SetStartTransition(VirtualSpeedSensor_Handle_t *pHandle, bool bCommand) +{ + bool bAux = true; +#ifdef NULL_PTR_VIR_SPD_SEN + if (MC_NULL == pHandle) + { + /* nothing to do */ + } + else + { +#endif + if (true == bCommand) + { + pHandle->bTransitionStarted = true; + + if (0 == pHandle->hTransitionSteps) + { + pHandle->bTransitionEnded = true; + pHandle->_Super.bSpeedErrorNumber = 0U; + bAux = false; + } + } +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif + return (bAux); +} + +/** + * @brief Returns the status of the transition phase by checking the status of the two + * parameters + * @ref VirtualSpeedSensor_Handle_t::bTransitionStarted "bTransitionStarted" and + * @ref VirtualSpeedSensor_Handle_t::bTransitionEnded "bTransitionEnded". + * @param pHandle: handler of the current instance of the VirtualSpeedSensor components + * @retval bool: true if Transition phase is ongoing, false otherwise. + * + * - Not used into current implementation. + */ +__weak bool VSS_IsTransitionOngoing(VirtualSpeedSensor_Handle_t *pHandle) +{ + bool retVal = false; +#ifdef NULL_PTR_VIR_SPD_SEN + if (MC_NULL == pHandle) + { + /* nothing to do */ + } + else + { +#endif + uint16_t hTS = 0U; + uint16_t hTE = 0U; + uint16_t hAux; + + if (true == pHandle->bTransitionStarted) + { + hTS = 1U; + } + if (true == pHandle->bTransitionEnded) + { + hTE = 1U; + } + hAux = hTS ^ hTE; + if (hAux != 0U) + { + retVal = true; + } +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif + return (retVal); +} + +/** + * @brief Returns the ending status of the transition phase by checking the parameter + * @ref VirtualSpeedSensor_Handle_t::bTransitionEnded "bTransitionEnded". + * @param pHandle: handler of the current instance of the VirtualSpeedSensor components + * @retval bool: true if Transition phase ended, false otherwise. + * + * - Called into SWITCH_OVER state of MC tasks state machine into TSK_MediumFrequencyTask. + */ +__weak bool VSS_TransitionEnded(VirtualSpeedSensor_Handle_t *pHandle) +{ +#ifdef NULL_PTR_VIR_SPD_SEN + return ((MC_NULL == pHandle) ? false : pHandle->bTransitionEnded); +#else + return (pHandle->bTransitionEnded); +#endif +} + +/** + * @brief Sets instantaneous information on rotor electrical angle same as copied by + * state observer. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @retval none + * + * - Not used into current implementation. + */ +__weak void VSS_SetCopyObserver(VirtualSpeedSensor_Handle_t *pHandle) +{ +#ifdef NULL_PTR_VIR_SPD_SEN + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->bCopyObserver = true; +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif +} + +/** + * @brief Sets instantaneous information on rotor electrical angle. + * @param pHandle: handler of the current instance of the VirtualSpeedSensor component. + * @param hElAngle instantaneous measure of rotor electrical angle in + * [s16degrees](measurement_units.md). + * @retval none + * + * - Not used into current implementation. + */ +__weak void VSS_SetElAngle(VirtualSpeedSensor_Handle_t *pHandle, int16_t hElAngle) +{ +#ifdef NULL_PTR_VIR_SPD_SEN + if (MC_NULL == pHandle) + { + /* Nothing to do */ + } + else + { +#endif + pHandle->hElAngleAccu = hElAngle; + pHandle->_Super.hElAngle = hElAngle; +#ifdef NULL_PTR_VIR_SPD_SEN + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mcsdk/virtual_speed_sensor.h b/src/firmware/motor/mcsdk/virtual_speed_sensor.h new file mode 100644 index 0000000000..e58a8275ed --- /dev/null +++ b/src/firmware/motor/mcsdk/virtual_speed_sensor.h @@ -0,0 +1,142 @@ +/** + ****************************************************************************** + * @file virtual_speed_sensor.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * Virtual Speed Sensor component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup VirtualSpeedSensor + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef VIRTUALSPEEDSENSOR_H +#define VIRTUALSPEEDSENSOR_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/speed_pos_fdbk.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup SpeednPosFdbk + * @{ + */ + + /** @addtogroup VirtualSpeedSensor + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief This structure is used to handle an instance of the Virtual Speed + * sensor component. + */ + typedef struct + { + SpeednPosFdbk_Handle_t _Super; + int32_t wElAccDppP32; /*!< Delta electrical speed expressed in + [dpp](measurement_units.md) per speed sampling period to + be applied each time is called SPD_calcAvrgMecSpeedUnit + multiplied by scaling factor of 65536. */ + int32_t + wElSpeedDpp32; /*!< Electrical speed expressed in [dpp](measurement_units.md) + multiplied by scaling factor 65536. */ + uint16_t hRemainingStep; /*!< Number of steps remaining to reach the final + speed. */ + int16_t hFinalMecSpeedUnit; /*!< Backup of hFinalMecSpeedUnit to be applied in + the last step.*/ + bool bTransitionStarted; /*!< Retaining information about started Transition + status.*/ + bool bTransitionEnded; /*!< Retaining information about ended transition status.*/ + int16_t hTransitionRemainingSteps; /*!< Number of steps remaining to end + transition from Virtual Speed Sensor + module to other speed sensor modules */ + int16_t hElAngleAccu; /*!< Electrical angle accumulator */ + bool bTransitionLocked; /*!< Transition acceleration started */ + bool bCopyObserver; /*!< Command to set Virtual Speed Sensor module output same as + state observer */ + + uint16_t hSpeedSamplingFreqHz; /*!< Frequency (Hz) at which motor speed is to + be computed. It must be equal to the frequency + at which function SPD_calcAvrgMecSpeedUnit + is called. */ + int16_t + hTransitionSteps; /*< Number of steps to perform the transition phase + from from Virtual Speed Sensor module to other speed + sensor modules. If the Transition PHase should last + TPH milliseconds, and the FOC Execution Frequency is + set to FEF kHz, then #hTransitionSteps = TPH * FEF */ + } VirtualSpeedSensor_Handle_t; + + /* It initializes the Virtual Speed Sensor component */ + void VSS_Init(VirtualSpeedSensor_Handle_t *pHandle); + + /* It clears Virtual Speed Sensor by re-initializing private variables*/ + void VSS_Clear(VirtualSpeedSensor_Handle_t *pHandle); + + /* It compute a theorical speed and update the theorical electrical angle. */ + int16_t VSS_CalcElAngle(VirtualSpeedSensor_Handle_t *pHandle, + int16_t *pInputVars_str); + + /* Computes the rotor average theoretical mechanical speed in the unit defined by + * SPEED_UNIT and returns it in pMecSpeedUnit. */ + bool VSS_CalcAvrgMecSpeedUnit(VirtualSpeedSensor_Handle_t *pHandle, + int16_t *hMecSpeedUnit); + + /* It set istantaneous information on VSS mechanical and electrical angle.*/ + void VSS_SetMecAngle(VirtualSpeedSensor_Handle_t *pHandle, int16_t hMecAngle); + + /* Set the mechanical acceleration of virtual sensor. */ + void VSS_SetMecAcceleration(VirtualSpeedSensor_Handle_t *pHandle, + int16_t hFinalMecSpeedUnit, uint16_t hDurationms); + /* Checks if the ramp executed after a VSPD_SetMecAcceleration command has been + * completed*/ + bool VSS_RampCompleted(VirtualSpeedSensor_Handle_t *pHandle); + + /* Get the final speed of last setled ramp of virtual sensor expressed in 0.1Hz*/ + int16_t VSS_GetLastRampFinalSpeed(VirtualSpeedSensor_Handle_t *pHandle); + + /* Set the command to Start the transition phase from VirtualSpeedSensor to other + * SpeedSensor.*/ + bool VSS_SetStartTransition(VirtualSpeedSensor_Handle_t *pHandle, bool bCommand); + + /* Return the status of the transition phase.*/ + bool VSS_IsTransitionOngoing(VirtualSpeedSensor_Handle_t *pHandle); + + bool VSS_TransitionEnded(VirtualSpeedSensor_Handle_t *pHandle); + + /* It set istantaneous information on rotor electrical angle copied by state observer + */ + void VSS_SetCopyObserver(VirtualSpeedSensor_Handle_t *pHandle); + + /* It set istantaneous information on rotor electrical angle */ + void VSS_SetElAngle(VirtualSpeedSensor_Handle_t *pHandle, int16_t hElAngle); + + /** @} */ + /** @} */ + /** @} */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* VIRTUALSPEEDSENSOR_H */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/mdv6_firmware.ld b/src/firmware/motor/mdv6_firmware.ld new file mode 100644 index 0000000000..17d04252bd --- /dev/null +++ b/src/firmware/motor/mdv6_firmware.ld @@ -0,0 +1,185 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** @brief : Linker script for STM32F031C6Tx Device from STM32F0 series +** 32KBytes FLASH +** 4KBytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2025 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x80; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 32K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .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 into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _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" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/src/firmware/motor/motorcontrol.c b/src/firmware/motor/motorcontrol.c new file mode 100644 index 0000000000..f876a860ef --- /dev/null +++ b/src/firmware/motor/motorcontrol.c @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * @file motorcontrol.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief Motor Control Subsystem initialization functions. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCInterface + */ +#include "firmware/motor/motorcontrol.h" + +// cstat -MISRAC2012-Rule-21.1 +#include "firmware/motor/main.h" +// cstat +MISRAC2012-Rule-21.1 +#include "firmware/motor/mc_interface.h" +#include "firmware/motor/mc_tasks.h" + + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup MCInterface + * @{ + */ + +MCI_Handle_t* pMCI[NBR_OF_MOTORS]; + +/** + * @brief Initializes and configures the Motor Control Subsystem + * + * This function initializes and configures all the structures and components needed + * for the Motor Control subsystem required by the Application. It expects that + * all the peripherals needed for Motor Control purposes are already configured but + * that their interrupts are not enabled yet. + * + * CubeMX calls this function after all peripherals initializations and + * before the NVIC is configured + */ +__weak void MX_MotorControl_Init(void) +{ + /* Reconfigure the SysTick interrupt to fire every 500 us. */ + (void)HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / SYS_TICK_FREQUENCY); + HAL_NVIC_SetPriority(SysTick_IRQn, uwTickPrio, 0U); + + /* Initialize the Motor Control Subsystem */ + MCboot(pMCI); + mc_lock_pins(); +} + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/motorcontrol.h b/src/firmware/motor/motorcontrol.h new file mode 100644 index 0000000000..0c40d96bfb --- /dev/null +++ b/src/firmware/motor/motorcontrol.h @@ -0,0 +1,60 @@ +/** + ****************************************************************************** + * @file motorcontrol.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief Motor Control Subsystem initialization functions. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup MCInterface + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef MOTORCONTROL_H +#define MOTORCONTROL_H + +#include "firmware/motor/mc_api.h" +#include "firmware/motor/mc_config.h" +#include "firmware/motor/parameters_conversion.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup MCInterface + * @{ + */ + + /* Initializes the Motor Control Subsystem */ + void MX_MotorControl_Init(void); + +/* Do not remove the definition of this symbol. */ +#define MC_HAL_IS_USED + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* MOTORCONTROL_H */ +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/parameters_conversion.h b/src/firmware/motor/parameters_conversion.h new file mode 100644 index 0000000000..328d088ad1 --- /dev/null +++ b/src/firmware/motor/parameters_conversion.h @@ -0,0 +1,217 @@ + +/** + ****************************************************************************** + * @file parameters_conversion.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file includes the proper Parameter conversion on the base + * of stdlib for the first drive + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef PARAMETERS_CONVERSION_H +#define PARAMETERS_CONVERSION_H + +#include "drive_parameters.h" +#include "mc_math.h" +#include "parameters_conversion_f0xx.h" +#include "pmsm_motor_parameters.h" +#include "power_stage_parameters.h" + +/* Current conversion from Ampere unit to 16Bit Digit */ +#define CURRENT_CONV_FACTOR \ + (uint16_t)((65536.0 * RSHUNT * AMPLIFICATION_GAIN) / ADC_REFERENCE_VOLTAGE) +#define CURRENT_CONV_FACTOR_INV \ + (1.0 / ((65536.0 * RSHUNT * AMPLIFICATION_GAIN) / ADC_REFERENCE_VOLTAGE)) + +/* Current conversion from Ampere unit to 16Bit Digit */ + +#define NOMINAL_CURRENT (NOMINAL_CURRENT_A * CURRENT_CONV_FACTOR) +#define ADC_REFERENCE_VOLTAGE 3.3 +#define M1_MAX_READABLE_CURRENT \ + (ADC_REFERENCE_VOLTAGE / (2 * RSHUNT * AMPLIFICATION_GAIN)) + +/************************* CONTROL FREQUENCIES & DELAIES **********************/ +#define TF_REGULATION_RATE \ + (uint32_t)((uint32_t)(PWM_FREQUENCY) / (REGULATION_EXECUTION_RATE)) + +/* TF_REGULATION_RATE_SCALED is TF_REGULATION_RATE divided by PWM_FREQ_SCALING to allow + * more dynamic */ +#define TF_REGULATION_RATE_SCALED \ + (uint16_t)((uint32_t)(PWM_FREQUENCY) / (REGULATION_EXECUTION_RATE * PWM_FREQ_SCALING)) + +/* DPP_CONV_FACTOR is introduce to compute the right DPP with TF_REGULATOR_SCALED */ +#define DPP_CONV_FACTOR (65536 / PWM_FREQ_SCALING) + +/* Current conversion from Ampere unit to 16Bit Digit */ +#define ID_DEMAG (ID_DEMAG_A * CURRENT_CONV_FACTOR) +#define IQMAX (IQMAX_A * CURRENT_CONV_FACTOR) + +#define DEFAULT_TORQUE_COMPONENT (DEFAULT_TORQUE_COMPONENT_A * CURRENT_CONV_FACTOR) +#define DEFAULT_FLUX_COMPONENT (DEFAULT_FLUX_COMPONENT_A * CURRENT_CONV_FACTOR) +#define REP_COUNTER (uint16_t)((REGULATION_EXECUTION_RATE * 2u) - 1u) +#define SYS_TICK_FREQUENCY (uint16_t)2000 +#define UI_TASK_FREQUENCY_HZ 10U +#define PHASE1_FINAL_CURRENT (PHASE1_FINAL_CURRENT_A * CURRENT_CONV_FACTOR) +#define PHASE2_FINAL_CURRENT (PHASE2_FINAL_CURRENT_A * CURRENT_CONV_FACTOR) +#define PHASE3_FINAL_CURRENT (PHASE3_FINAL_CURRENT_A * CURRENT_CONV_FACTOR) +#define PHASE4_FINAL_CURRENT (PHASE4_FINAL_CURRENT_A * CURRENT_CONV_FACTOR) +#define PHASE5_FINAL_CURRENT (PHASE5_FINAL_CURRENT_A * CURRENT_CONV_FACTOR) +#define MEDIUM_FREQUENCY_TASK_RATE (uint16_t) SPEED_LOOP_FREQUENCY_HZ +#define MF_TASK_OCCURENCE_TICKS (SYS_TICK_FREQUENCY / SPEED_LOOP_FREQUENCY_HZ) - 1u +#define UI_TASK_OCCURENCE_TICKS (SYS_TICK_FREQUENCY / UI_TASK_FREQUENCY_HZ) - 1u +#define SERIALCOM_TIMEOUT_OCCURENCE_TICKS \ + (SYS_TICK_FREQUENCY / SERIAL_COM_TIMEOUT_INVERSE) - 1u +#define SERIALCOM_ATR_TIME_TICKS \ + (uint16_t)(((SYS_TICK_FREQUENCY * SERIAL_COM_ATR_TIME_MS) / 1000u) - 1u) + +#define MAX_APPLICATION_SPEED_UNIT ((MAX_APPLICATION_SPEED_RPM * SPEED_UNIT) / U_RPM) +#define MIN_APPLICATION_SPEED_UNIT ((MIN_APPLICATION_SPEED_RPM * SPEED_UNIT) / U_RPM) + +#define MAX_APPLICATION_SPEED_UNIT2 ((MAX_APPLICATION_SPEED_RPM2 * SPEED_UNIT) / U_RPM) +#define MIN_APPLICATION_SPEED_UNIT2 ((MIN_APPLICATION_SPEED_RPM2 * SPEED_UNIT) / U_RPM) + +/************************** VOLTAGE CONVERSIONS Motor 1 *************************/ +#define OVERVOLTAGE_THRESHOLD_d \ + (uint16_t)(OV_VOLTAGE_THRESHOLD_V * 65535 / \ + (ADC_REFERENCE_VOLTAGE / VBUS_PARTITIONING_FACTOR)) +#define OVERVOLTAGE_THRESHOLD_LOW_d \ + (uint16_t)(OV_VOLTAGE_THRESHOLD_V * 65535 / \ + (ADC_REFERENCE_VOLTAGE / VBUS_PARTITIONING_FACTOR)) +#define UNDERVOLTAGE_THRESHOLD_d \ + (uint16_t)((UD_VOLTAGE_THRESHOLD_V * 65535) / \ + ((uint16_t)(ADC_REFERENCE_VOLTAGE / VBUS_PARTITIONING_FACTOR))) +#define INT_SUPPLY_VOLTAGE (uint16_t)(65536 / ADC_REFERENCE_VOLTAGE) +#define DELTA_TEMP_THRESHOLD (OV_TEMPERATURE_THRESHOLD_C - T0_C) +#define DELTA_V_THRESHOLD (dV_dT * DELTA_TEMP_THRESHOLD) +#define OV_TEMPERATURE_THRESHOLD_d ((V0_V + DELTA_V_THRESHOLD) * INT_SUPPLY_VOLTAGE) +#define DELTA_TEMP_HYSTERESIS (OV_TEMPERATURE_HYSTERESIS_C) +#define DELTA_V_HYSTERESIS (dV_dT * DELTA_TEMP_HYSTERESIS) +#define OV_TEMPERATURE_HYSTERESIS_d (DELTA_V_HYSTERESIS * INT_SUPPLY_VOLTAGE) + +/*************** Timer for PWM generation & currenst sensing parameters ******/ +#define PWM_PERIOD_CYCLES \ + (uint16_t)( \ + ((uint32_t)ADV_TIM_CLK_MHz * (uint32_t)1000000u / ((uint32_t)(PWM_FREQUENCY))) & \ + (uint16_t)0xFFFE) + +#define DEADTIME_NS SW_DEADTIME_NS +#define DEAD_TIME_ADV_TIM_CLK_MHz (ADV_TIM_CLK_MHz * TIM_CLOCK_DIVIDER) +#define DEAD_TIME_COUNTS_1 (DEAD_TIME_ADV_TIM_CLK_MHz * DEADTIME_NS / 1000uL) +#if (DEAD_TIME_COUNTS_1 <= 255) +#define DEAD_TIME_COUNTS (uint16_t) DEAD_TIME_COUNTS_1 +#elif (DEAD_TIME_COUNTS_1 <= 508) +#define DEAD_TIME_COUNTS \ + (uint16_t)(((DEAD_TIME_ADV_TIM_CLK_MHz * DEADTIME_NS / 2) / 1000uL) + 128) +#elif (DEAD_TIME_COUNTS_1 <= 1008) +#define DEAD_TIME_COUNTS \ + (uint16_t)(((DEAD_TIME_ADV_TIM_CLK_MHz * DEADTIME_NS / 8) / 1000uL) + 320) +#elif (DEAD_TIME_COUNTS_1 <= 2015) +#define DEAD_TIME_COUNTS \ + (uint16_t)(((DEAD_TIME_ADV_TIM_CLK_MHz * DEADTIME_NS / 16) / 1000uL) + 384) +#else +#define DEAD_TIME_COUNTS 510 +#endif +#define DTCOMPCNT (uint16_t)((DEADTIME_NS * ADV_TIM_CLK_MHz) / 2000) +#define TON_NS 500 +#define TOFF_NS 500 +#define TON (uint16_t)((TON_NS * ADV_TIM_CLK_MHz) / 2000) +#define TOFF (uint16_t)((TOFF_NS * ADV_TIM_CLK_MHz) / 2000) + +/**********************/ +/* MOTOR 1 ADC Timing */ +/**********************/ +/* In ADV_TIMER CLK cycles*/ +#define SAMPLING_TIME ((ADC_SAMPLING_CYCLES * ADV_TIM_CLK_MHz) / ADC_CLK_MHz) + +#define TRISE ((TRISE_NS * ADV_TIM_CLK_MHz) / 1000uL) +#define TDEAD ((uint16_t)((DEADTIME_NS * ADV_TIM_CLK_MHz) / 1000)) +#define TNOISE ((uint16_t)((TNOISE_NS * ADV_TIM_CLK_MHz) / 1000)) +#define TMAX_TNTR ((uint16_t)((MAX_TNTR_NS * ADV_TIM_CLK_MHz) / 1000uL)) +#define TAFTER ((uint16_t)(TDEAD + TMAX_TNTR)) +#define TBEFORE \ + ((uint16_t)(((ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) * \ + ADV_TIM_CLK_MHz) / \ + ADC_CLK_MHz) + \ + 1U) +#define TMIN ((uint16_t)(TAFTER + TBEFORE)) +#define HTMIN ((uint16_t)(TMIN >> 1)) +#define CHTMIN ((uint16_t)(TMIN / (REGULATION_EXECUTION_RATE * 2))) +#if (TRISE > SAMPLING_TIME) +#define MAX_TRTS (2 * TRISE) +#else +#define MAX_TRTS (2 * SAMPLING_TIME) +#endif + +/* USER CODE BEGIN temperature */ +#define M1_VIRTUAL_HEAT_SINK_TEMPERATURE_VALUE 25u +#define M1_TEMP_SW_FILTER_BW_FACTOR 250u +/* USER CODE END temperature */ + +#define PQD_CONVERSION_FACTOR \ + (float_t)(((1.732 * ADC_REFERENCE_VOLTAGE) / (RSHUNT * AMPLIFICATION_GAIN)) / \ + 65536.0f) + +/****** Prepares the UI configurations according the MCconfxx settings ********/ +#define DAC_ENABLE +#define DAC_OP_ENABLE + +/* Motor 1 settings */ +#define FW_ENABLE + +#define DIFFTERM_ENABLE + +/* Sensors setting */ +#define MAIN_SCFG UI_SCODE_HALL +#define AUX_SCFG 0x0 +#define PLLTUNING_ENABLE + +#define UI_CFGOPT_PFC_ENABLE + +/******************************************************************************* + * UI configurations settings. It can be manually overwritten if special + * configuartion is required. + *******************************************************************************/ +/* Specific options of UI */ +#define UI_CONFIG_M1 \ + (UI_CFGOPT_NONE DAC_OP_ENABLE FW_ENABLE DIFFTERM_ENABLE | \ + (MAIN_SCFG << MAIN_SCFG_POS) | (AUX_SCFG << AUX_SCFG_POS) | \ + UI_CFGOPT_SETIDINSPDMODE PLLTUNING_ENABLE UI_CFGOPT_PFC_ENABLE | \ + UI_CFGOPT_PLLTUNING) +#define UI_CONFIG_M2 +#define DIN_ACTIVE_LOW Bit_RESET +#define DIN_ACTIVE_HIGH Bit_SET +#define DOUT_ACTIVE_HIGH DOutputActiveHigh +#define DOUT_ACTIVE_LOW DOutputActiveLow + +/********** HALL TIMER MOTOR 1 *************/ +#define M1_HALL_TIM_PERIOD 65535 +#define M1_HALL_IC_FILTER_LL LL_TIM_IC_FILTER_FDIV8_N6 +#define M1_HALL_IC_FILTER LL_TIM_IC_FILTER_FDIV8_N6 +#define SPD_TIM_M1_IRQHandler TIM2_IRQHandler + +#define LPF_FILT_CONST ((int16_t)(32767 * 0.5)) + +/* MMI Table Motor 1 MAX_MODULATION_100_PER_CENT */ +#define MAX_MODULE (uint16_t)((100 * 32767) / 100) + +#define SAMPLING_CYCLE_CORRECTION 0.5 /* Add half cycle required by STM32F031C6Tx ADC */ +#define LL_ADC_SAMPLINGTIME_1CYCLES_5 LL_ADC_SAMPLINGTIME_1CYCLE_5 + +// cstat !MISRAC2012-Rule-20.10 !DEFINE-hash-multiple +#define LL_ADC_SAMPLING_CYCLE(CYCLE) LL_ADC_SAMPLINGTIME_##CYCLE##CYCLES_5 + +#endif /*PARAMETERS_CONVERSION_H*/ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/parameters_conversion_f0xx.h b/src/firmware/motor/parameters_conversion_f0xx.h new file mode 100644 index 0000000000..048f426faa --- /dev/null +++ b/src/firmware/motor/parameters_conversion_f0xx.h @@ -0,0 +1,56 @@ + +/** + ****************************************************************************** + * @file parameters_conversion_f0xx.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains the definitions needed to convert MC SDK parameters + * so as to target the STM32F0 Family. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __PARAMETERS_CONVERSION_F0XX_H +#define __PARAMETERS_CONVERSION_F0XX_H + +/************************* CPU & ADC PERIPHERAL CLOCK CONFIG ******************/ +#define SYSCLK_FREQ 48000000uL +#define TIM_CLOCK_DIVIDER 1 +#define ADV_TIM_CLK_MHz 48 +#define ADC_CLK_MHz 14uL /* Maximum ADC Clock Frequency expressed in MHz */ +#define HALL_TIM_CLK 48000000uL +#define ADC1_2 ADC1 +#define REF_TIM_CLK 48000000uL +#define REF_TIM_CLK_MHz 48 + +/************************* IRQ Handler Mapping *********************/ +#define CURRENT_REGULATION_IRQHandler DMA1_Channel1_IRQHandler +#define DMAx_R1_M1_IRQHandler DMA1_Channel4_5_IRQHandler +#define TIMx_UP_BRK_M1_IRQHandler TIM1_BRK_UP_TRG_COM_IRQHandler + +/********** AUXILIARY TIMER (SINGLE SHUNT) *************/ + +#define R1_PWM_AUX_TIM TIM3 + +/* Referred to Maximum value indicated in the Datasheet Table 50 if ADC clock = HSI14 + * converted in number of cycle*/ +/* 4 Cycles at 14Mhz = 285 ns - Table mentions 259 ns */ +#define ADC_TRIG_CONV_LATENCY_CYCLES 4 +#define ADC_SAR_CYCLES 12.5 + +#define M1_VBUS_SW_FILTER_BW_FACTOR 10u + +#endif /*__PARAMETERS_CONVERSION_F0XX_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/pmsm_motor_parameters.h b/src/firmware/motor/pmsm_motor_parameters.h new file mode 100644 index 0000000000..976caebd60 --- /dev/null +++ b/src/firmware/motor/pmsm_motor_parameters.h @@ -0,0 +1,75 @@ +/** + ****************************************************************************** + * @file pmsm_motor_parameters.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains the parameters needed for the Motor Control SDK + * in order to configure the motor to drive. + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef PMSM_MOTOR_PARAMETERS_H +#define PMSM_MOTOR_PARAMETERS_H + +/************************ + *** Motor Parameters *** + ************************/ + +/***************** MOTOR ELECTRICAL PARAMETERS ******************************/ +#define POLE_PAIR_NUM 8 /* Number of motor pole pairs */ +#define RS 0.64 /* Stator resistance , ohm*/ +#define LS \ + 0.00027 /* Stator inductance, H \ + For I-PMSM it is equal to Lq */ + +/* When using Id = 0, NOMINAL_CURRENT is utilized to saturate the output of the + PID for speed regulation (i.e. reference torque). + Transformation of real currents (A) into int16_t format must be done accordingly with + formula: + Phase current (int16_t 0-to-peak) = (Phase current (A 0-to-peak)* 32767 * Rshunt * + *Amplifying network gain)/(MCU supply voltage/2) +*/ + +#define MOTOR_MAX_SPEED_RPM 4840 /*!< Maximum rated speed */ +#define MOTOR_VOLTAGE_CONSTANT 3.8 /*!< Volts RMS ph-ph /kRPM */ +#define NOMINAL_CURRENT_A 9.5 + +#define ID_DEMAG_A -9.5 /*!< Demagnetization current */ + +/***************** MOTOR SENSORS PARAMETERS ******************************/ +/* Motor sensors parameters are always generated but really meaningful only + if the corresponding sensor is actually present in the motor */ + +/*** Hall sensors ***/ +#define HALL_SENSORS_PLACEMENT \ + DEGREES_120 /*!
© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef POWER_STAGE_PARAMETERS_H +#define POWER_STAGE_PARAMETERS_H + +/************************ + *** Motor Parameters *** + ************************/ + +/************* PWM Driving signals section **************/ +#define HW_DEAD_TIME_NS \ + 700 /*!< Dead-time inserted \ + by HW if low side signals \ + are not used */ +/*********** Bus voltage sensing section ****************/ +#define VBUS_PARTITIONING_FACTOR \ + 0.070883075842697 /*!< It expresses how \ + much the Vbus is attenuated \ + before being converted into \ + digital value */ +#define NOMINAL_BUS_VOLTAGE_V 24 +/******** Current reading parameters section ******/ +/*** Topology ***/ +#define SINGLE_SHUNT + +#define RSHUNT 0.025 + +/* ICSs gains in case of isolated current sensors, + amplification gain for shunts based sensing */ +#define AMPLIFICATION_GAIN 3.33 + +/*** Noise parameters ***/ +#define TNOISE_NS 1200 +#define TRISE_NS 1200 +#define MAX_TNTR_NS TRISE_NS + +/************ Temperature sensing section ***************/ +/* V[V]=V0+dV/dT[V/Celsius]*(T-T0)[Celsius]*/ +#define V0_V 0.290 /*!< in Volts */ +#define T0_C 25 /*!< in Celsius degrees */ +#define dV_dT 0.025 /*!< V/Celsius degrees */ +#define T_MAX \ + 70 /*!< Sensor measured \ + temperature at maximum \ + power stage working \ + temperature, Celsius degrees */ + +#endif /*POWER_STAGE_PARAMETERS_H*/ +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/r1_ps_pwm_curr_fdbk.c b/src/firmware/motor/r1_ps_pwm_curr_fdbk.c new file mode 100644 index 0000000000..e8fba3149a --- /dev/null +++ b/src/firmware/motor/r1_ps_pwm_curr_fdbk.c @@ -0,0 +1,1451 @@ + +/** + ****************************************************************************** + * @file r1_ps_pwm_curr_fdbk.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the following features + * of the CCC component of the Motor Control SDK: + * + initializes MCU peripheral for 1 shunt topology and F3 family + * + performs PWM duty cycle computation and generation + * + performs current sensing + * + + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/r1_ps_pwm_curr_fdbk.h" + +#include "firmware/motor/common_defs.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/mcsdk/pwm_common.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup pwm_curr_fdbk + * @{ + */ + +/** + * @defgroup r1_ps_pwm_curr_fdbk R1 F30x PWM & Current Feedback + * + * @brief STM32F3, 1-Shunt with phase shift PWM & Current Feedback implementation + * + * This component is used in applications based on an STM32F3 MCU + * and using a single shunt resistor current sensing topology. + * + * @todo: TODO: complete documentation. + * @{ + */ + +/* Constant values -----------------------------------------------------------*/ +#define TIMxCCER_MASK_CH123 \ + (TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC1NE | TIM_CCER_CC2NE | \ + TIM_CCER_CC3NE) + +#define DMA_CFG \ + (LL_DMA_PERIPH_NOINCREMENT | LL_DMA_MEMORY_INCREMENT | LL_DMA_PDATAALIGN_HALFWORD | \ + LL_DMA_DIRECTION_MEMORY_TO_PERIPH | LL_DMA_MDATAALIGN_HALFWORD | \ + LL_DMA_PRIORITY_VERYHIGH | LL_DMA_MODE_CIRCULAR) + +#define DMA_TRANSFER_LENGTH_CCR 6u +#define DMA_TRANSFER_LENGTH_SAMPLING_POINT 3u +#define DMA_TRANSFER_LENGTH_ADC 2u +#define IA_OK 0x01 +#define IB_OK 0x02 +#define IC_OK 0x04 + +static const int8_t ALFLAG[3] = {IA_OK, IB_OK, IC_OK}; +/* Private typedef -----------------------------------------------------------*/ + +/* Private function prototypes -----------------------------------------------*/ +static void R1_HFCurrentsCalibration(PWMC_Handle_t *pHdl, ab_t *pStator_Currents); +static void R1_1ShuntMotorVarsInit(PWMC_Handle_t *pHdl); +static void R1_TIMxInit(TIM_TypeDef *TIMx, PWMC_R1_Handle_t *pHdl); +static uint16_t R1_SetADCSampPointPolarization(PWMC_Handle_t *pHdl); + +/** + * @brief It initializes TIMx, ADC, GPIO, DMA1 and NVIC for current reading + * in ICS configuration using STM32F103x High Density + * @param pHandle: handler of the current instance of the PWM component + */ +void R1_Init(PWMC_R1_Handle_t *pHandle) +{ + TIM_TypeDef *TIMx = pHandle->pParams_str->TIMx; + ADC_TypeDef *ADCx = pHandle->pParams_str->ADCx; + DMA_TypeDef *DMAx = pHandle->pParams_str->DMAx; + + R1_1ShuntMotorVarsInit(&pHandle->_Super); + + /********************************************************************************************/ + /* TIM Initialization */ + /********************************************************************************************/ + R1_TIMxInit(TIMx, pHandle); + + /********************************************************************************************/ + /* DMA Initialization */ + /********************************************************************************************/ + LL_DMA_ConfigTransfer(DMAx, pHandle->pParams_str->DMAChannelX, + DMA_CFG); /* To be removed should be done by cubeMX */ + + LL_TIM_ConfigDMABurst(TIMx, LL_TIM_DMABURST_BASEADDR_CCR1, + LL_TIM_DMABURST_LENGTH_3TRANSFERS); + + /* cfg dma source and dest address */ + LL_DMA_SetMemoryAddress(DMAx, pHandle->pParams_str->DMAChannelX, + (uint32_t)&pHandle->DmaBuffCCR[0]); + LL_DMA_SetPeriphAddress(DMAx, pHandle->pParams_str->DMAChannelX, + (uint32_t)&TIMx->DMAR); + /* cfg dma transfer size */ + LL_DMA_SetDataLength(DMAx, pHandle->pParams_str->DMAChannelX, + DMA_TRANSFER_LENGTH_CCR); + + /* DMA dedicated to TIMx CC register modification of the ADC sampling point */ + LL_DMA_ConfigTransfer(DMAx, pHandle->pParams_str->DMASamplingPtChannelX, + DMA_CFG); /* To be removed should be done by cubeMX */ + /* Set dma source and dest address for TIMx CC register modification on the fly */ + LL_DMA_SetMemoryAddress(DMAx, pHandle->pParams_str->DMASamplingPtChannelX, + (uint32_t)&pHandle->DmaBuffCCR_ADCTrig[0]); + LL_DMA_SetPeriphAddress(DMAx, pHandle->pParams_str->DMASamplingPtChannelX, + (uint32_t)&TIMx->CCR4); + /* Set dma transfer size */ + LL_DMA_SetDataLength(DMAx, pHandle->pParams_str->DMASamplingPtChannelX, + DMA_TRANSFER_LENGTH_SAMPLING_POINT); + LL_DMA_EnableIT_TC(DMAx, pHandle->pParams_str->DMAChannelX); + + /* DMA dedicated to ADC conversion */ + LL_DMA_SetMemoryAddress(DMAx, pHandle->pParams_str->DMA_ADC_DR_ChannelX, + (uint32_t)pHandle->CurConv); + LL_DMA_SetPeriphAddress(DMAx, pHandle->pParams_str->DMA_ADC_DR_ChannelX, + (uint32_t)&ADCx->DR); + LL_DMA_SetDataLength(DMAx, pHandle->pParams_str->DMA_ADC_DR_ChannelX, + DMA_TRANSFER_LENGTH_ADC); + + /********************************************************************************************/ + /* ADC Initialization */ + /********************************************************************************************/ + + /* disable IT and flags in case of LL driver usage + * workaround for unwanted interrupt enabling done by LL driver */ + LL_ADC_DisableIT_EOC(ADCx); + LL_ADC_ClearFlag_EOC(ADCx); + LL_ADC_DisableIT_EOS(ADCx); + LL_ADC_ClearFlag_EOS(ADCx); + + /* Start calibration of ADC1 */ + LL_ADC_StartCalibration(ADC1); + while ((LL_ADC_IsCalibrationOnGoing(ADC1) == SET) || + (LL_ADC_REG_IsConversionOngoing(ADC1) == SET) || + (LL_ADC_REG_IsStopConversionOngoing(ADC1) == SET) || + (LL_ADC_IsDisableOngoing(ADC1) == SET)) + { + /* wait */ + } + /* Enable ADC */ + LL_ADC_Enable(ADC1); + /* Enable ADC DMA request*/ + LL_ADC_REG_SetTriggerSource(ADCx, LL_ADC_REG_TRIG_SOFTWARE); + LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_LIMITED); + + /* Wait ADC Ready */ + while (LL_ADC_IsActiveFlag_ADRDY(ADC1) == RESET) + { + } + + LL_ADC_REG_SetTriggerSource(ADCx, LL_ADC_REG_TRIG_EXT_TIM1_TRGO); + LL_ADC_REG_SetSequencerChannels( + ADCx, __LL_ADC_DECIMAL_NB_TO_CHANNEL(pHandle->pParams_str->IChannel)); + + /* Clear the flags */ + LL_TIM_EnableCounter(TIM1); + + pHandle->ADCRegularLocked = + false; /* We allow ADC usage for regular conversion on Systick */ +} + +/** + * @brief It initializes TIMx peripheral for PWM generation + * @param TIMx: Timer to be initialized + * @param pHandle: handler of the current instance of the PWM component + */ +void R1_TIMxInit(TIM_TypeDef *TIMx, PWMC_R1_Handle_t *pHandle) +{ + /* Freeze timer for the debug */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_DBGMCU); + LL_DBGMCU_APB1_GRP2_FreezePeriph(LL_DBGMCU_APB1_GRP2_TIM1_STOP); + /* disable main TIM counter to ensure + * a synchronous start by TIM2 trigger */ + LL_TIM_DisableCounter(TIMx); + + /* Update CC interrupt flag only during up counting */ + LL_TIM_SetCounterMode(TIMx, TIM_CR1_CMS_1); + + /* Disable ADC trigger */ + LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_RESET); + + /* Disable preload register to be able to update CC registers + twice per PWM cycle with DMA for phase shifting */ + LL_TIM_OC_DisablePreload(TIMx, LL_TIM_CHANNEL_CH1); + LL_TIM_OC_DisablePreload(TIMx, LL_TIM_CHANNEL_CH2); + LL_TIM_OC_DisablePreload(TIMx, LL_TIM_CHANNEL_CH3); + LL_TIM_OC_DisablePreload(TIMx, LL_TIM_CHANNEL_CH4); + LL_TIM_CC_EnableChannel(TIMx, LL_TIM_CHANNEL_CH4); + + /* Update event generation at each overflow/underflow to update + CC register twice per PWM cycle with DMA for phase shifting */ + LL_TIM_SetRepetitionCounter(TIMx, 0); + + /* Always enable BKIN for safety feature */ + LL_TIM_ClearFlag_BRK(TIMx); + LL_TIM_EnableIT_BRK(TIMx); + + /* Enable drive of TIMx CHy and CHyN by TIMx CHyRef*/ + LL_TIM_CC_EnableChannel(TIMx, TIMxCCER_MASK_CH123); +} + +/** + * @brief First initialization of the handler + * @param pHdl: handler of the current instance of the PWM component + */ +void R1_1ShuntMotorVarsInit(PWMC_Handle_t *pHdl) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + + /* Init motor vars */ + pHandle->iflag = 0; + pHandle->FOCDurationFlag = false; + pHandle->Half_PWMPeriod = (pHandle->_Super.PWMperiod / 2u); + + pHandle->CntSmp1 = + ((uint32_t)(pHandle->Half_PWMPeriod) >> 1) - + (uint32_t)(pHandle->pParams_str->hTADConv + pHandle->pParams_str->TSample); + pHandle->CntSmp2 = + ((uint32_t)(pHandle->Half_PWMPeriod) >> 1) + + (uint32_t)(pHandle->pParams_str->hTADConv + pHandle->pParams_str->TSample); + + pHandle->_Super.CntPhA = pHandle->Half_PWMPeriod >> 1; + pHandle->_Super.CntPhB = pHandle->Half_PWMPeriod >> 1; + pHandle->_Super.CntPhC = pHandle->Half_PWMPeriod >> 1; + + /* initialize buffer with the default duty cycle value */ + pHandle->DmaBuffCCR[0] = + pHandle->_Super.CntPhA; /* CCR1 value overwritten during first half PWM period */ + pHandle->DmaBuffCCR_latch[0] = + pHandle->_Super.CntPhA; /* CCR1 value overwritten during first half PWM period */ + pHandle->DmaBuffCCR[1] = + pHandle->_Super.CntPhB; /* CCR2 value overwritten during first half PWM period */ + pHandle->DmaBuffCCR_latch[1] = + pHandle->_Super.CntPhB; /* CCR2 value overwritten during first half PWM period */ + pHandle->DmaBuffCCR[2] = + pHandle->_Super.CntPhC; /* CCR3 value overwritten during first half PWM period */ + pHandle->DmaBuffCCR_latch[2] = + pHandle->_Super.CntPhC; /* CCR3 value overwritten during first half PWM period */ + + pHandle->DmaBuffCCR[3] = + pHandle->_Super.CntPhA; /* CCR1 value overwritten during second half PWM period */ + pHandle->DmaBuffCCR_latch[3] = + pHandle->_Super.CntPhA; /* CCR1 value overwritten during second half PWM period */ + pHandle->DmaBuffCCR[4] = + pHandle->_Super.CntPhB; /* CCR2 value overwritten during second half PWM period */ + pHandle->DmaBuffCCR_latch[4] = + pHandle->_Super.CntPhB; /* CCR2 value overwritten during second half PWM period */ + pHandle->DmaBuffCCR[5] = + pHandle->_Super.CntPhC; /* CCR3 value overwritten during second half PWM period */ + pHandle->DmaBuffCCR_latch[5] = + pHandle->_Super.CntPhC; /* CCR3 value overwritten during second half PWM period */ + + /* initialize buffer with default sampling value */ + pHandle->DmaBuffCCR_ADCTrig[0] = pHandle->CntSmp2; + pHandle->DmaBuffCCR_ADCTrig[1] = pHandle->Half_PWMPeriod - 1u; + pHandle->DmaBuffCCR_ADCTrig[2] = pHandle->CntSmp1; + + pHandle->_Super.BrakeActionLock = false; +} + +/** + * @brief It sets the calibrated offsets + * @param pHdl: handler of the current instance of the PWM component + * @param offsets: pointer to the structure that contains the offsets + */ +__weak void R1_SetOffsetCalib(PWMC_Handle_t *pHdl, PolarizationOffsets_t *offsets) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; // cstat !MISRAC2012-Rule-11.3 + + pHandle->PhaseOffset = offsets->phaseAOffset; + + pHdl->offsetCalibStatus = true; +} + +/** + * @brief It reads the calibrated offsets + * @param pHdl: handler of the current instance of the PWM component + * @param offsets: pointer to the structure that will contain the offsets + */ +__weak void R1_GetOffsetCalib(PWMC_Handle_t *pHdl, PolarizationOffsets_t *offsets) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; // cstat !MISRAC2012-Rule-11.3 + + offsets->phaseAOffset = pHandle->PhaseOffset; +} + +/** + * @brief It stores into pHandle the offset voltage read onchannels when no + * current is flowing into the motor + * @param pHdl: handler of the current instance of the PWM component + */ +__weak void R1_CurrentReadingCalibration(PWMC_Handle_t *pHdl) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + TIM_TypeDef *TIMx = pHandle->pParams_str->TIMx; + + if (false == pHandle->_Super.offsetCalibStatus) + { + pHandle->PhaseOffset = 0u; + pHandle->Index = 0u; + + /* It forces inactive level on TIMx CHy and CHyN */ + LL_TIM_CC_DisableChannel(TIMx, TIMxCCER_MASK_CH123); + + /* Offset calibration */ + /* Change function to be executed in ADCx_ISR */ + pHandle->_Super.pFctGetPhaseCurrents = &R1_HFCurrentsCalibration; + pHandle->_Super.pFctSetADCSampPointSectX = &R1_SetADCSampPointPolarization; + + R1_SwitchOnPWM(&pHandle->_Super); + + /* Wait for NB_CONVERSIONS to be executed */ + waitForPolarizationEnd(TIMx, &pHandle->_Super.SWerror, + pHandle->pParams_str->RepetitionCounter, &pHandle->Index); + + R1_SwitchOffPWM(&pHandle->_Super); + + pHandle->PhaseOffset >>= 4u; + if (0U == pHandle->_Super.SWerror) + { + pHandle->_Super.offsetCalibStatus = true; + } + else + { + /* nothing to do */ + } + + /* Change back function to be executed in ADCx_ISR */ + pHandle->_Super.pFctGetPhaseCurrents = &R1_GetPhaseCurrents; + pHandle->_Super.pFctSetADCSampPointSectX = &R1_CalcDutyCycles; + } + else + { + /* Nothing to do */ + } + + /* It over write TIMx CCRy wrongly written by FOC during calibration so as to + force 50% duty cycle on the three inverer legs */ + /* Disable TIMx preload */ + LL_TIM_OC_SetCompareCH1(TIMx, pHandle->Half_PWMPeriod >> 1u); + LL_TIM_OC_SetCompareCH2(TIMx, pHandle->Half_PWMPeriod >> 1u); + LL_TIM_OC_SetCompareCH3(TIMx, pHandle->Half_PWMPeriod >> 1u); + /* generate COM event to apply new CC values */ + LL_TIM_GenerateEvent_COM(TIMx); + + /* It re-enable drive of TIMx CHy and CHyN by TIMx CHyRef */ + LL_TIM_CC_EnableChannel(TIMx, TIMxCCER_MASK_CH123); + + R1_1ShuntMotorVarsInit(&pHandle->_Super); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section (".ccmram"))) +#endif +#endif +/** + * @brief It computes and return latest converted motor phase currents motor + * @param pHdl: handler of the current instance of the PWM component + * @retval Ia and Ib current in Curr_Components format + */ +__weak void R1_GetPhaseCurrents(PWMC_Handle_t *pHdl, ab_t *pStator_Currents) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + TIM_TypeDef *TIMx = pHandle->pParams_str->TIMx; + int32_t wAux1; + int32_t wAux2; + int16_t hCurrA = 0; + int16_t hCurrB = 0; + int16_t hCurrC = 0; + + /* Clear flag used for FOC duration check */ + pHandle->FOCDurationFlag = false; + + /* Disabling the External triggering for ADCx */ + LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_RESET); + /* First sampling point */ + wAux1 = (int32_t)pHandle->CurConv[0]; + wAux1 -= (int32_t)(pHandle->PhaseOffset); + + /* Check saturation */ + if (wAux1 > -INT16_MAX) + { + if (wAux1 < INT16_MAX) + { + } + else + { + wAux1 = INT16_MAX; + } + } + else + { + wAux1 = -INT16_MAX; + } + /* Second sampling point */ + wAux2 = (int32_t)pHandle->CurConv[1]; + wAux2 -= (int32_t)(pHandle->PhaseOffset); + + /* Check saturation */ + if (wAux2 > -INT16_MAX) + { + if (wAux2 < INT16_MAX) + { + } + else + { + wAux2 = INT16_MAX; + } + } + else + { + wAux2 = -INT16_MAX; + } + + switch (pHandle->_Super.Sector) + { + case SECTOR_1: + { + if ((pHandle->iflag & (IA_OK | IC_OK)) == + (IA_OK | IC_OK)) /* iA and -iC are available to be sampled */ + { + hCurrA = (int16_t)wAux2; + wAux1 = -wAux1; + hCurrC = (int16_t)wAux1; + hCurrB = -hCurrA - hCurrC; + } + else + { + if ((pHandle->iflag & (IA_OK | IC_OK)) != + 0x00) /* iA or -iC is available to be sampled */ + { + if (pHandle->_Super.AlignFlag == + 0x01) /* START Position Aligning_angle=30 degree */ + { + if ((pHandle->iflag & (IA_OK | IC_OK)) == + IA_OK) /* iA is available to be sampled and not iC */ + { + hCurrA = (int16_t)wAux2; + hCurrB = 0; + hCurrC = -hCurrA; + } + else /* 0x04 -ic is available */ + { + wAux1 = -wAux1; + hCurrC = (int16_t)wAux1; + hCurrA = -hCurrC; + hCurrB = 0; + } + } + else /* Not START Position */ + { + if ((pHandle->iflag & (IA_OK | IC_OK)) == + IA_OK) /* iA, is available to be sampled */ + { + hCurrA = (int16_t)wAux2; + hCurrB = pHandle->_Super.IbEst; + } + else /* 0x04 -ic is available */ + { + wAux1 = -wAux1; + hCurrC = (int16_t)wAux1; + hCurrB = pHandle->_Super.IbEst; + hCurrA = -hCurrB - hCurrC; + } + } + } + else + { + hCurrA = pHandle->_Super.IaEst; + hCurrC = pHandle->_Super.IcEst; + hCurrB = -hCurrA - hCurrC; + } + } + break; + } + + case SECTOR_2: + { + if ((pHandle->iflag & (IB_OK | IC_OK)) == + (IB_OK | IC_OK)) /* iB,-iC are available to be sampled */ + { + hCurrB = (int16_t)wAux2; + wAux1 = -wAux1; + hCurrC = (int16_t)wAux1; + hCurrA = -hCurrB - hCurrC; + } + else + { + if ((pHandle->iflag & (IB_OK | IC_OK)) != + 0x00) /* iB, or -iC is available to be sampled */ + { + if (pHandle->_Super.AlignFlag == + 0x01) /* START Position Aligning_angle=90 degree */ + { + if ((pHandle->iflag & (IB_OK | IC_OK)) == + IB_OK) /* iB, is available to be sampled */ + { + hCurrB = (int16_t)wAux2; + hCurrA = 0; + } + else /* 0x04 -ic */ + { + wAux1 = -wAux1; + hCurrC = (int16_t)wAux1; + hCurrA = 0; + hCurrB = -hCurrC; + } + } + else /* Not START Position */ + { + if ((pHandle->iflag & (IB_OK | IC_OK)) == + IB_OK) /* iB, is available to be sampled */ + { + hCurrB = (int16_t)wAux2; + hCurrA = pHandle->_Super.IaEst; + } + else /* 0x04 -ic */ + { + wAux1 = -wAux1; + hCurrC = (int16_t)wAux1; + hCurrA = pHandle->_Super.IaEst; + hCurrB = -hCurrA - hCurrC; + } + } + } + else + { + hCurrB = pHandle->_Super.IbEst; + hCurrC = pHandle->_Super.IcEst; + hCurrA = -hCurrB - hCurrC; + } + } + break; + } + + case SECTOR_3: + { + if ((pHandle->iflag & (IA_OK | IB_OK)) == + (IA_OK | IB_OK)) /* iB,-iA are available to be sampled */ + { + hCurrB = (int16_t)wAux2; + wAux1 = -wAux1; + hCurrA = (int16_t)wAux1; + } + else + { + if ((pHandle->iflag & (IA_OK | IB_OK)) != + 0x00) /* iB, or -iA is available to be sampled */ + { + if (pHandle->_Super.AlignFlag == + 0x01) /* START Position Aligning_angle=150 degree */ + { + if ((pHandle->iflag & (IA_OK | IB_OK)) == + IB_OK) /* iB, is available to be sampled */ + { + hCurrB = (int16_t)wAux2; + hCurrA = -hCurrB; + } + else /* 0x01 -ia */ + { + wAux1 = -wAux1; + hCurrA = (int16_t)wAux1; + hCurrB = -hCurrA; + } + } + else /* Not START Position */ + { + if ((pHandle->iflag & (IA_OK | IB_OK)) == + IB_OK) /* iB, is available to be sampled */ + { + hCurrB = (int16_t)wAux2; + hCurrA = pHandle->_Super.IaEst; + } + else /* 0x01 -ia */ + { + wAux1 = -wAux1; + hCurrA = (int16_t)wAux1; + hCurrB = pHandle->_Super.IbEst; + } + } + } + else + { + hCurrB = pHandle->_Super.IbEst; + hCurrA = pHandle->_Super.IaEst; + } + } + break; + } + + case SECTOR_4: + { + if ((pHandle->iflag & (IA_OK | IC_OK)) == + (IA_OK | IC_OK)) /* iC,-iA are available to be sampled */ + { + hCurrC = (int16_t)wAux2; + wAux1 = -wAux1; + hCurrA = (int16_t)wAux1; + hCurrB = -hCurrA - hCurrC; + } + else + { + if ((pHandle->iflag & (IA_OK | IC_OK)) != + 0x00) /* iC, or -iA is available to be sampled */ + { + if (pHandle->_Super.AlignFlag == + 0x01) /* START Position Aligning_angle=210 degree */ + { + if ((pHandle->iflag & (IA_OK | IC_OK)) == + IC_OK) /* iC, is available to be sampled */ + { + hCurrC = (int16_t)wAux2; + hCurrA = -hCurrC; + hCurrB = 0; + } + else /* 0x01 -ia */ + { + wAux1 = -wAux1; + hCurrA = (int16_t)wAux1; + hCurrB = 0; + } + } + else /* Not START Position */ + { + if ((pHandle->iflag & (IA_OK | IC_OK)) == + IC_OK) /* iC, is available to be sampled */ + { + hCurrC = (int16_t)wAux2; + hCurrB = pHandle->_Super.IbEst; + hCurrA = -hCurrB - hCurrC; + } + else /* 0x01 -ia */ + { + wAux1 = -wAux1; + hCurrA = (int16_t)wAux1; + hCurrB = pHandle->_Super.IbEst; + } + } + } + else + { + hCurrC = pHandle->_Super.IcEst; + hCurrA = pHandle->_Super.IaEst; + hCurrB = -hCurrA - hCurrC; + } + } + break; + } + + case SECTOR_5: + { + if ((pHandle->iflag & (IB_OK | IC_OK)) == + (IB_OK | IC_OK)) /* iC,-iB are available to be sampled */ + { + hCurrC = (int16_t)wAux2; + wAux1 = -wAux1; + hCurrB = (int16_t)wAux1; + hCurrA = -hCurrB - hCurrC; + } + else + { + if ((pHandle->iflag & (IB_OK | IC_OK)) != + 0x00) /* iC, or -iB is available to be sampled */ + { + if (pHandle->_Super.AlignFlag == + 0x01) /* START Position Aligning_angle=270 degree */ + { + if ((pHandle->iflag & (IB_OK | IC_OK)) == + IC_OK) /* iC, is available to be sampled */ + { + hCurrC = (int16_t)wAux2; + hCurrA = 0; + hCurrB = -hCurrC; + } + else /* 0x02 -ib */ + { + wAux1 = -wAux1; + hCurrB = (int16_t)wAux1; + hCurrA = 0; + } + } + else /* Not START Position */ + { + if ((pHandle->iflag & (IB_OK | IC_OK)) == + IC_OK) /* iC, is available to be sampled */ + { + hCurrC = (int16_t)wAux2; + hCurrA = pHandle->_Super.IaEst; + hCurrB = -hCurrA - hCurrC; + } + else /* 0x02 -ib */ + { + wAux1 = -wAux1; + hCurrB = (int16_t)wAux1; + hCurrA = pHandle->_Super.IaEst; + } + } + } + else + { + hCurrC = pHandle->_Super.IcEst; + hCurrB = pHandle->_Super.IbEst; + hCurrA = -hCurrB - hCurrC; + } + } + break; + } + + case SECTOR_6: + { + if ((pHandle->iflag & (IA_OK | IB_OK)) == + (IA_OK | IB_OK)) /* iA,-iB are available to be sampled */ + { + hCurrA = (int16_t)wAux2; + wAux1 = -wAux1; + hCurrB = (int16_t)wAux1; + } + else + { + if ((pHandle->iflag & (IA_OK | IB_OK)) != + 0x00) /* iA, or -iB is available to be sampled */ + { + if (pHandle->_Super.AlignFlag == + 0x01) /* START Position Aligning_angle=330 degree */ + { + if ((pHandle->iflag & (IA_OK | IB_OK)) == + IA_OK) /* iA, is available to be sampled */ + { + hCurrA = (int16_t)wAux2; + hCurrB = -hCurrA; + } + else /* 0x02 -ib */ + { + wAux1 = -wAux1; + hCurrB = (int16_t)wAux1; + hCurrA = -hCurrB; + } + } + else /* Not START Position */ + { + if ((pHandle->iflag & (IA_OK | IB_OK)) == + IA_OK) /* iA, is available to be sampled */ + { + hCurrA = (int16_t)wAux2; + hCurrB = pHandle->_Super.IbEst; + } + else /* 0x02 -ib */ + { + wAux1 = -wAux1; + hCurrB = (int16_t)wAux1; + hCurrA = pHandle->_Super.IaEst; + } + } + } + else + { + hCurrA = pHandle->_Super.IaEst; + hCurrB = pHandle->_Super.IbEst; + } + } + break; + } + + default: + break; + } + + pHandle->CurrAOld = hCurrA; + pHandle->CurrBOld = hCurrB; + + pStator_Currents->a = hCurrA; + pStator_Currents->b = hCurrB; +} + +/** + * @brief Implementaion of PWMC_GetPhaseCurrents to be performed during + * calibration. It sum up injected conversion data into wPhaseCOffset + * to compute the offset introduced in the current feedback + * network. It is requied to proper configure ADC input before to enable + * the offset computation. + * @param pHdl: handler of the current instance of the PWM component + * @retval It always returns {0,0} in Curr_Components format + */ +static void R1_HFCurrentsCalibration(PWMC_Handle_t *pHdl, ab_t *pStator_Currents) +{ + /* Derived class members container */ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + TIM_TypeDef *TIMx = pHandle->pParams_str->TIMx; + /* Clear flag used for FOC duration check */ + pHandle->FOCDurationFlag = false; + + /* Disabling the External triggering for ADCx */ + LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_RESET); + if (pHandle->Index < NB_CONVERSIONS) + { + pHandle->PhaseOffset += pHandle->CurConv[1]; + pHandle->Index++; + } + + /* During offset calibration no current is flowing in the phases */ + pStator_Currents->a = 0; + pStator_Currents->b = 0; +} + +static uint16_t R1_SetADCSampPointPolarization(PWMC_Handle_t *pHdl) +{ + /* Derived class members container */ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + + uint16_t hAux; + pHandle->CntSmp1 = + ((uint32_t)(pHandle->Half_PWMPeriod) >> 1) - + (uint32_t)(pHandle->pParams_str->hTADConv + pHandle->pParams_str->TSample); + pHandle->CntSmp2 = + ((uint32_t)(pHandle->Half_PWMPeriod) >> 1) + + (uint32_t)(pHandle->pParams_str->hTADConv + pHandle->pParams_str->TSample); + LL_ADC_REG_SetSequencerChannels( + ADC1, __LL_ADC_DECIMAL_NB_TO_CHANNEL(pHandle->pParams_str->IChannel)); + LL_ADC_SetSamplingTimeCommonChannels(ADC1, pHandle->pParams_str->ISamplingTime); + LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_EXT_TIM1_CH4); + + /* Check software error */ + if (pHandle->FOCDurationFlag == true) + { + hAux = MC_DURATION; + } + else + { + hAux = MC_NO_ERROR; + } + if (pHandle->_Super.SWerror == 1u) + { + hAux = MC_DURATION; + pHandle->_Super.SWerror = 0u; + } + else + { + /* Nothing to do */ + } + return (hAux); +} + +/** + * @brief It turns on low sides switches. This function is intended to be + * used for charging boot capacitors of driving section. It has to be + * called each motor start-up when using high voltage drivers + * @param pHdl: handler of the current instance of the PWM component + */ +__weak void R1_TurnOnLowSides(PWMC_Handle_t *pHdl, uint32_t ticks) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + TIM_TypeDef *TIMx = pHandle->pParams_str->TIMx; + + pHandle->_Super.TurnOnLowSidesAction = true; + /* Turn on the three low side switches */ + LL_TIM_OC_SetCompareCH1(TIMx, ticks); + LL_TIM_OC_SetCompareCH2(TIMx, ticks); + LL_TIM_OC_SetCompareCH3(TIMx, ticks); + + /* Clear Update Flag */ + LL_TIM_ClearFlag_UPDATE(TIMx); + + /* Wait until next update */ + while (LL_TIM_IsActiveFlag_UPDATE(TIMx) == RESET) + { + /* Nothing to do */ + } + + /* Main PWM Output Enable */ + LL_TIM_EnableAllOutputs(TIMx); + + if ((pHandle->_Super.LowSideOutputs) == ES_GPIO) + { + LL_GPIO_SetOutputPin(pHandle->_Super.pwm_en_u_port, pHandle->_Super.pwm_en_u_pin); + LL_GPIO_SetOutputPin(pHandle->_Super.pwm_en_v_port, pHandle->_Super.pwm_en_v_pin); + LL_GPIO_SetOutputPin(pHandle->_Super.pwm_en_w_port, pHandle->_Super.pwm_en_w_pin); + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief It enables PWM generation on the proper Timer peripheral acting on MOE + * bit + * @param pHdl: handler of the current instance of the PWM component + */ +__weak void R1_SwitchOnPWM(PWMC_Handle_t *pHdl) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + TIM_TypeDef *TIMx = pHandle->pParams_str->TIMx; + ADC_TypeDef *ADCx = pHandle->pParams_str->ADCx; + DMA_TypeDef *DMAx = pHandle->pParams_str->DMAx; + pHandle->CntSmp1 = + ((uint32_t)(pHandle->Half_PWMPeriod) >> 1) - + (uint32_t)(pHandle->pParams_str->hTADConv + pHandle->pParams_str->TSample); + pHandle->CntSmp2 = + ((uint32_t)(pHandle->Half_PWMPeriod) >> 1) + + (uint32_t)(pHandle->pParams_str->hTADConv + pHandle->pParams_str->TSample); + + pHandle->_Super.TurnOnLowSidesAction = false; + + pHandle->DmaBuffCCR_ADCTrig[0] = pHandle->CntSmp2; + pHandle->DmaBuffCCR_ADCTrig[2] = pHandle->CntSmp1; + LL_TIM_OC_SetCompareCH4(TIMx, (uint32_t)(pHandle->Half_PWMPeriod + 1)); + + /* Set all duty to 50% */ + LL_TIM_OC_SetCompareCH1(TIMx, (uint32_t)(pHandle->Half_PWMPeriod >> 1)); + LL_TIM_OC_SetCompareCH2(TIMx, (uint32_t)(pHandle->Half_PWMPeriod >> 1)); + LL_TIM_OC_SetCompareCH3(TIMx, (uint32_t)(pHandle->Half_PWMPeriod >> 1)); + + /* Main PWM Output Enable */ + LL_TIM_EnableAllOutputs(TIMx); + + if ((pHandle->_Super.LowSideOutputs) == ES_GPIO) + { + if ((TIMx->CCER & TIMxCCER_MASK_CH123) != 0u) + { + LL_GPIO_SetOutputPin(pHandle->_Super.pwm_en_u_port, + pHandle->_Super.pwm_en_u_pin); + LL_GPIO_SetOutputPin(pHandle->_Super.pwm_en_v_port, + pHandle->_Super.pwm_en_v_pin); + LL_GPIO_SetOutputPin(pHandle->_Super.pwm_en_w_port, + pHandle->_Super.pwm_en_w_pin); + } + else + { + /* It is executed during calibration phase the EN signal shall stay off */ + LL_GPIO_ResetOutputPin(pHandle->_Super.pwm_en_u_port, + pHandle->_Super.pwm_en_u_pin); + LL_GPIO_ResetOutputPin(pHandle->_Super.pwm_en_v_port, + pHandle->_Super.pwm_en_v_pin); + LL_GPIO_ResetOutputPin(pHandle->_Super.pwm_en_w_port, + pHandle->_Super.pwm_en_w_pin); + } + } + else + { + /* Nothing to do */ + } + + /* Wait for second half PWM cycle to enable dma request */ + if (LL_TIM_COUNTERDIRECTION_UP == LL_TIM_GetDirection(TIMx)) + { + while (LL_TIM_COUNTERDIRECTION_UP == LL_TIM_GetDirection(TIMx)) + { + /* TIMx is upcounting */ + } + } + else + { + while (LL_TIM_COUNTERDIRECTION_DOWN == LL_TIM_GetDirection(TIMx)) + { + /* TIMx is downcounting */ + } + while (LL_TIM_COUNTERDIRECTION_UP == LL_TIM_GetDirection(TIMx)) + { + /* TIMx is upcounting */ + } + } + + /* At this point we are down counting */ + + /* Clear peripheral flags */ + LL_DMA_ClearFlag_TC(DMAx, pHandle->pParams_str->DMAChannelX); + LL_DMA_ClearFlag_HT(DMAx, pHandle->pParams_str->DMAChannelX); + + LL_DMA_ClearFlag_TC(DMAx, pHandle->pParams_str->DMASamplingPtChannelX); + LL_DMA_ClearFlag_HT(DMAx, pHandle->pParams_str->DMASamplingPtChannelX); + + LL_TIM_ClearFlag_UPDATE(TIMx); + + pHandle->TCCnt = 0; + pHandle->TCDoneFlag = false; + pHandle->FOCDurationFlag = false; + + /* Start DMA that modifies CC register of CH1,2 and 3 in order to create the + phase shifting */ + LL_DMA_SetDataLength(DMAx, pHandle->pParams_str->DMAChannelX, + DMA_TRANSFER_LENGTH_CCR); + LL_DMA_EnableChannel(DMAx, pHandle->pParams_str->DMAChannelX); + LL_TIM_EnableDMAReq_UPDATE(TIMx); + + /* Enable DMA related to sampling */ + LL_TIM_EnableDMAReq_CC4(TIMx); + + LL_DMA_SetDataLength(DMAx, pHandle->pParams_str->DMASamplingPtChannelX, 3); + LL_DMA_EnableChannel(DMAx, pHandle->pParams_str->DMASamplingPtChannelX); + /* Set CCR4 to the very first sampling point + when CNT matches CCR4 value (first sampling point), it raises CH4 signal: + - it triggers the first ADC injected conversion + - it triggers a DMA transfer to load CCR4 with the second sampling value + which lowers CH4 signal. + when CNT matches CCR4 value (second sampling point value) it raises CH4 signal + - it triggers the second ADC injected conversion + - it triggers a DMA to transfer to load 0 into CCR4 register which makes CH4 + stay high until next PWM cycle + when CNT matches CCR4 value (0 i.e start of a new PWM cycle) it lowers CH4 signal + - it triggers a DMA to transfer to load CCR4 with the first sampling point value */ + LL_TIM_OC_SetCompareCH4(TIMx, (uint32_t)(pHandle->Half_PWMPeriod + 1)); + + LL_DMA_DisableChannel(DMAx, pHandle->pParams_str->DMA_ADC_DR_ChannelX); + LL_DMA_SetDataLength(DMAx, pHandle->pParams_str->DMA_ADC_DR_ChannelX, + DMA_TRANSFER_LENGTH_ADC); + LL_DMA_EnableChannel(DMAx, pHandle->pParams_str->DMA_ADC_DR_ChannelX); + LL_ADC_REG_SetSequencerChannels( + ADCx, __LL_ADC_DECIMAL_NB_TO_CHANNEL(pHandle->pParams_str->IChannel)); + LL_ADC_SetSamplingTimeCommonChannels(ADC1, pHandle->pParams_str->ISamplingTime); + LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_LIMITED); + LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_EXT_TIM1_CH4); + LL_ADC_REG_StartConversion(ADC1); + + /* Enable ADC trigger */ + LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_OC4REF); + + /* Reset flag for FOC duration detection */ + pHandle->FOCDurationFlag = false; + + /* Lock ADC */ + pHandle->ADCRegularLocked = true; + + /* Enable peripheral interrupt */ + LL_DMA_EnableIT_TC(DMAx, pHandle->pParams_str->DMAChannelX); + LL_DMA_EnableIT_TC(DMAx, pHandle->pParams_str->DMA_ADC_DR_ChannelX); + + LL_TIM_ClearFlag_UPDATE(TIMx); + while ((LL_TIM_IsActiveFlag_UPDATE(TIMx) == RESET) || + (LL_TIM_GetDirection(TIMx) == LL_TIM_COUNTERDIRECTION_DOWN)) + { + /* TIMx is downcounting */ + } + LL_TIM_EnableIT_UPDATE(TIM1); + LL_TIM_OC_SetCompareCH4(TIMx, (uint32_t)pHandle->CntSmp1); +} + +/** + * @brief It disables PWM generation on the proper Timer peripheral acting on + * MOE bit + * @param pHdl: handler of the current instance of the PWM component + */ +__weak void R1_SwitchOffPWM(PWMC_Handle_t *pHdl) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + TIM_TypeDef *TIMx = pHandle->pParams_str->TIMx; + DMA_TypeDef *DMAx = pHandle->pParams_str->DMAx; + pHandle->CntSmp1 = + ((uint32_t)(pHandle->Half_PWMPeriod) >> 1) - + (uint32_t)(pHandle->pParams_str->hTADConv + pHandle->pParams_str->TSample); + pHandle->CntSmp2 = + ((uint32_t)(pHandle->Half_PWMPeriod) >> 1) + + (uint32_t)(pHandle->pParams_str->hTADConv + pHandle->pParams_str->TSample); + + /* This allow to control cycles during next sequence */ + LL_TIM_DisableIT_UPDATE(TIMx); + + /* Synchronize the disable of the DMA and all settings with the douwn counting */ + if (LL_TIM_COUNTERDIRECTION_UP == LL_TIM_GetDirection(TIMx)) + { + while (LL_TIM_COUNTERDIRECTION_UP == LL_TIM_GetDirection(TIMx)) + { + /* TIMx is upcounting */ + } + } + else + { + while (LL_TIM_COUNTERDIRECTION_DOWN == LL_TIM_GetDirection(TIMx)) + { + /* TIMx is downcounting */ + } + while (LL_TIM_COUNTERDIRECTION_UP == LL_TIM_GetDirection(TIMx)) + { + /* TIMx is upcounting */ + } + } + + LL_DMA_DisableIT_TC(DMAx, pHandle->pParams_str->DMAChannelX); + LL_DMA_DisableIT_HT(DMAx, pHandle->pParams_str->DMAChannelX); + + pHandle->_Super.TurnOnLowSidesAction = false; + + /* Main PWM Output Disable */ + LL_TIM_DisableAllOutputs(TIMx); + if (pHandle->_Super.BrakeActionLock == true) + { + /* Nothing to do */ + } + else + { + if ((pHandle->_Super.LowSideOutputs) == ES_GPIO) + { + LL_GPIO_ResetOutputPin(pHandle->_Super.pwm_en_u_port, + pHandle->_Super.pwm_en_u_pin); + LL_GPIO_ResetOutputPin(pHandle->_Super.pwm_en_v_port, + pHandle->_Super.pwm_en_v_pin); + LL_GPIO_ResetOutputPin(pHandle->_Super.pwm_en_w_port, + pHandle->_Super.pwm_en_w_pin); + } + } + + /* Disable DMA channel related to ADC current sampling */ + LL_DMA_DisableChannel(DMAx, pHandle->pParams_str->DMA_ADC_DR_ChannelX); + LL_DMA_ClearFlag_GI1(DMAx); + LL_DMA_ClearFlag_TC1(DMAx); + LL_DMA_ClearFlag_HT1(DMAx); + + /* Disable DMA related to phase shift */ + LL_DMA_DisableChannel(DMAx, pHandle->pParams_str->DMAChannelX); + LL_TIM_DisableDMAReq_UPDATE(TIMx); + + /* Disable DMA related to sampling */ + LL_DMA_DisableChannel(DMAx, pHandle->pParams_str->DMASamplingPtChannelX); + LL_TIM_DisableDMAReq_CC4(TIMx); + + pHandle->DmaBuffCCR_ADCTrig[0] = pHandle->CntSmp2; + pHandle->DmaBuffCCR_ADCTrig[2] = pHandle->CntSmp1; + LL_TIM_OC_SetCompareCH4(TIMx, (uint32_t)(pHandle->Half_PWMPeriod + 1)); + + /* Disable ADC trigger */ + LL_TIM_SetTriggerOutput(TIMx, LL_TIM_TRGO_RESET); + + /* Clear potential ADC Ongoing conversion */ + if (LL_ADC_REG_IsConversionOngoing(ADC1)) + { + LL_ADC_REG_StopConversion(ADC1); + while (LL_ADC_REG_IsConversionOngoing(ADC1)) + { + /* Nothing to do */ + } + } + + LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE); + + /* We allow ADC usage for regular conversion on Systick */ + pHandle->ADCRegularLocked = false; + + R1_1ShuntMotorVarsInit(&pHandle->_Super); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section (".ccmram"))) +#endif +#endif +/** + * @brief Implementation of the single shunt algorithm to setup the + * TIM1 register and DMA buffers values for the next PWM period. + * @param pHandle related object of class CPWMC + * @retval uint16_t It returns MC_DURATION if the TIMx update occurs + * before the end of FOC algorithm else returns MC_NO_ERROR + */ +__weak uint16_t R1_CalcDutyCycles(PWMC_Handle_t *pHdl) +{ + PWMC_R1_Handle_t *pHandle = (PWMC_R1_Handle_t *)pHdl; + DMA_TypeDef *DMAx = pHandle->pParams_str->DMAx; + int16_t submax_mid; + int16_t submax_mid_deltmin; + int16_t submid_min; + int16_t submid_min_deltmin; + int16_t aCCRval[3]; /* CCR setting values */ + int16_t SamplePoint1; + int16_t SamplePoint2; + uint16_t hAux; + uint8_t maxVal; + uint8_t midVal; + uint8_t minVal; + uint8_t max_bad_flag; + uint8_t min_bad_flag; + + aCCRval[0] = (int16_t)pHandle->_Super.CntPhA; + aCCRval[1] = (int16_t)pHandle->_Super.CntPhB; + aCCRval[2] = (int16_t)pHandle->_Super.CntPhC; + + maxVal = (uint8_t)pHandle->_Super.highDuty; + midVal = (uint8_t)pHandle->_Super.midDuty; + minVal = (uint8_t)pHandle->_Super.lowDuty; + pHandle->iflag = 0x00; + + /* Phase-shift and set iflag */ + submax_mid = aCCRval[maxVal] - aCCRval[midVal]; + submax_mid_deltmin = submax_mid - (int16_t)pHandle->pParams_str->TMin; + submid_min = aCCRval[midVal] - aCCRval[minVal]; + submid_min_deltmin = submid_min - (int16_t)pHandle->pParams_str->TMin; + pHandle->aShiftval[0] = 0; + pHandle->aShiftval[1] = 0; + pHandle->aShiftval[2] = 0; + max_bad_flag = 0; + min_bad_flag = 0; + + if (submax_mid_deltmin > 0) + { + pHandle->iflag |= ALFLAG[maxVal]; + } + else + { + if ((1 - submax_mid_deltmin + aCCRval[maxVal] + + (int16_t)pHandle->pParams_str->hTADConv) > + (int16_t)(pHandle->Half_PWMPeriod)) + { + pHandle->iflag &= ~ALFLAG[maxVal]; + max_bad_flag = 1U; + } + else + { + pHandle->iflag |= ALFLAG[maxVal]; + pHandle->aShiftval[maxVal] = 1U - (uint16_t)submax_mid_deltmin; + } + } + + if (submid_min_deltmin > 0) + { + pHandle->iflag |= ALFLAG[minVal]; + } + else + { + if ((submid_min_deltmin - 1 + aCCRval[minVal]) < 0) + { + pHandle->iflag &= ~ALFLAG[minVal]; + min_bad_flag = 1; + } + else + { + pHandle->iflag |= ALFLAG[minVal]; + pHandle->aShiftval[minVal] = (uint16_t)submid_min_deltmin - 1U; + } + } + + if ((0U == max_bad_flag) && (0U == min_bad_flag)) + { + SamplePoint1 = (int16_t)aCCRval[midVal] - (int16_t)pHandle->pParams_str->TSample; + SamplePoint2 = aCCRval[midVal] + (int16_t)pHandle->pParams_str->TMin - + (int16_t)pHandle->pParams_str->TSample; + } + else if ((1U == max_bad_flag) && (1U == min_bad_flag)) + { + SamplePoint1 = (int16_t)pHandle->Half_PWMPeriod / 2; + SamplePoint2 = SamplePoint1 + (int16_t)pHandle->pParams_str->TSample + + (int16_t)pHandle->pParams_str->hTADConv; + } + else if (1U == max_bad_flag) + { + SamplePoint1 = aCCRval[midVal] - (int16_t)pHandle->pParams_str->TSample; + SamplePoint2 = aCCRval[midVal] + (int16_t)pHandle->pParams_str->hTADConv; + } + else + { + SamplePoint2 = aCCRval[midVal] + (int16_t)pHandle->pParams_str->TMin - + (int16_t)pHandle->pParams_str->TSample; + SamplePoint1 = aCCRval[midVal]; + } + + if ((SamplePoint2 - SamplePoint1) < (int16_t)pHandle->pParams_str->hTADConv) + { + pHandle->iflag &= ALFLAG[maxVal]; + pHandle->iflag &= ~ALFLAG[minVal]; + SamplePoint1 = (int16_t)pHandle->Half_PWMPeriod / 2; + SamplePoint2 = SamplePoint1 + (int16_t)pHandle->pParams_str->TSample + + (int16_t)pHandle->pParams_str->hTADConv; + } + else + { + /* Nothing to do */ + } + + /* Saturate sampling point */ + if ((SamplePoint2 >= (int16_t)(pHandle->Half_PWMPeriod)) || (SamplePoint2 <= 0)) + { + pHandle->iflag &= ALFLAG[maxVal]; + SamplePoint2 = aCCRval[midVal] + (int16_t)pHandle->pParams_str->hTADConv; + } + else + { + /* Nothing to do */ + } + if ((SamplePoint1 >= (int16_t)pHandle->Half_PWMPeriod) || (SamplePoint1 <= 0)) + { + pHandle->iflag &= ~ALFLAG[minVal]; + SamplePoint1 = aCCRval[midVal]; + } + else + { + /* Nothing to do */ + } + + pHandle->CntSmp1 = SamplePoint1; + pHandle->CntSmp2 = SamplePoint2; + + /* Critical section start */ + LL_DMA_DisableIT_TC(DMAx, pHandle->pParams_str->DMAChannelX); + + pHandle->DmaBuffCCR_latch[0] = pHandle->_Super.CntPhA + pHandle->aShiftval[0]; + pHandle->DmaBuffCCR_latch[1] = pHandle->_Super.CntPhB + pHandle->aShiftval[1]; + pHandle->DmaBuffCCR_latch[2] = pHandle->_Super.CntPhC + pHandle->aShiftval[2]; + /* Second half PWM period CCR value transfered by DMA */ + pHandle->DmaBuffCCR_latch[3] = pHandle->_Super.CntPhA - pHandle->aShiftval[0]; + pHandle->DmaBuffCCR_latch[4] = pHandle->_Super.CntPhB - pHandle->aShiftval[1]; + pHandle->DmaBuffCCR_latch[5] = pHandle->_Super.CntPhC - pHandle->aShiftval[2]; + + if (pHandle->TCDoneFlag == true) + { + /* First half PWM period CCR value transfered by DMA */ + pHandle->DmaBuffCCR[0] = pHandle->DmaBuffCCR_latch[0]; + pHandle->DmaBuffCCR[1] = pHandle->DmaBuffCCR_latch[1]; + pHandle->DmaBuffCCR[2] = pHandle->DmaBuffCCR_latch[2]; + /* Second half PWM period CCR value transfered by DMA */ + pHandle->DmaBuffCCR[3] = pHandle->DmaBuffCCR_latch[3]; + pHandle->DmaBuffCCR[4] = pHandle->DmaBuffCCR_latch[4]; + pHandle->DmaBuffCCR[5] = pHandle->DmaBuffCCR_latch[5]; + + /* Reset first sampling as it has already been written by DMA */ + LL_TIM_OC_SetCompareCH4(TIM1, (uint32_t)pHandle->CntSmp1); + } + else + { + /* Do nothing, it will be applied during DMA transfer complete IRQ */ + } + /* Critical section end */ + LL_DMA_EnableIT_TC(DMAx, pHandle->pParams_str->DMAChannelX); + + LL_ADC_REG_SetSequencerChannels( + ADC1, __LL_ADC_DECIMAL_NB_TO_CHANNEL(pHandle->pParams_str->IChannel)); + LL_ADC_SetSamplingTimeCommonChannels(ADC1, pHandle->pParams_str->ISamplingTime); + LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_EXT_TIM1_CH4); + + pHandle->DmaBuffCCR_ADCTrig[0] = SamplePoint2; + pHandle->DmaBuffCCR_ADCTrig[2] = SamplePoint1; + + /* Check software error */ + if (pHandle->FOCDurationFlag == true) + { + hAux = MC_DURATION; + } + else + { + hAux = MC_NO_ERROR; + } + if (pHandle->_Super.SWerror == 1u) + { + hAux = MC_DURATION; + pHandle->_Super.SWerror = 0u; + } + else + { + /* Nothing to do */ + } + + return (hAux); +} + +/** + * @brief It contains the TIMx Update event interrupt + * @param pHdl: handler of the current instance of the PWM component + */ +__weak void *R1_TIM1_UP_IRQHandler(PWMC_R1_Handle_t *pHandle) +{ + if (pHandle->TCDoneFlag == true) + { + LL_ADC_REG_StartConversion(ADC1); + LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_OC4REF); + pHandle->FOCDurationFlag = true; + pHandle->TCDoneFlag = false; + } + else + { + /* Nothing to do */ + } + + return (&(pHandle->_Super.Motor)); +} + +/** + * @brief It contains the TIMx Update event interrupt + * @param pHdl: handler of the current instance of the PWM component + */ +__weak void *R1_TIM8_UP_IRQHandler(PWMC_R1_Handle_t *pHandle) +{ + return (&(pHandle->_Super.Motor)); +} + +/** + * @brief This function handles motor DMAx TC interrupt request. + * Required only for R1 with rep rate > 1 + * @param pHdl: handler of the current instance of the PWM component + */ +__weak void *R1_DMAx_TC_IRQHandler(PWMC_R1_Handle_t *pHandle) +{ + DMA_TypeDef *DMAx = pHandle->pParams_str->DMAx; + + LL_DMA_ClearFlag_HT(DMAx, pHandle->pParams_str->DMAChannelX); + pHandle->TCCnt++; + if (pHandle->TCCnt == (pHandle->pParams_str->RepetitionCounter + 1) >> 1) + { + /* First half PWM period CCR value transfered by DMA */ + pHandle->DmaBuffCCR[0] = pHandle->DmaBuffCCR_latch[0]; + pHandle->DmaBuffCCR[1] = pHandle->DmaBuffCCR_latch[1]; + pHandle->DmaBuffCCR[2] = pHandle->DmaBuffCCR_latch[2]; + /* Second half PWM period CCR value transfered by DMA */ + pHandle->DmaBuffCCR[3] = pHandle->DmaBuffCCR_latch[3]; + pHandle->DmaBuffCCR[4] = pHandle->DmaBuffCCR_latch[4]; + pHandle->DmaBuffCCR[5] = pHandle->DmaBuffCCR_latch[5]; + + pHandle->TCCnt = 0; + pHandle->TCDoneFlag = true; + } + else + { + } + + return (&(pHandle->_Super.Motor)); +} + +__weak void *R1_DMAx_HT_IRQHandler(PWMC_R1_Handle_t *pHandle) +{ + return (&(pHandle->_Super.Motor)); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/r1_ps_pwm_curr_fdbk.h b/src/firmware/motor/r1_ps_pwm_curr_fdbk.h new file mode 100644 index 0000000000..157f6eb0ba --- /dev/null +++ b/src/firmware/motor/r1_ps_pwm_curr_fdbk.h @@ -0,0 +1,262 @@ +/** + ****************************************************************************** + * @file r1_ps_pwm_curr_fdbk.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * r1_ps_pwm_curr_fdbk component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup r1_pwm_curr_fdbk + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef R1_PS_PWMCURRFDBK_H +#define R1_PS_PWMCURRFDBK_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/pwm_curr_fdbk.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup pwm_curr_fdbk + * @{ + */ + +/** @addtogroup r1_ps_pwm_curr_fdbk + * @{ + */ + +/* Exported constants --------------------------------------------------------*/ +#define NONE ((uint8_t)(0x00)) +#define EXT_MODE ((uint8_t)(0x01)) +#define INT_MODE ((uint8_t)(0x02)) + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief Paamters structure of the r1_ps_pwm_curr_fdbk Component. + * + */ + typedef struct + { + /* HW IP involved -----------------------------*/ + ADC_TypeDef *ADCx; /*!< First ADC peripheral to be used.*/ + TIM_TypeDef *TIMx; /*!< timer used for PWM generation.*/ + DMA_TypeDef *DMAx; /*!< timer used for PWM generation.*/ + GPIO_TypeDef *pwm_en_u_port; /*!< Channel 1N (low side) GPIO output */ + GPIO_TypeDef *pwm_en_v_port; /*!< Channel 2N (low side) GPIO output*/ + GPIO_TypeDef *pwm_en_w_port; /*!< Channel 3N (low side) GPIO output */ + uint32_t DMAChannelX; /*!< DMA channel used to modify CCR on the fly */ + uint32_t DMASamplingPtChannelX; /*!< DMA channel used to modify sampling point on + the fly */ + uint32_t AdcExtTrigger; /*!< ADC trigger */ + uint32_t DMA_ADC_DR_ChannelX; /*!< DMA channel used to transfer ADC data to memory + buffer */ + uint16_t pwm_en_u_pin; /*!< Channel 1N (low side) GPIO output pin */ + uint16_t pwm_en_v_pin; /*!< Channel 2N (low side) GPIO output pin */ + uint16_t pwm_en_w_pin; /*!< Channel 3N (low side) GPIO output pin */ + + /* PWM generation parameters --------------------------------------------------*/ + + uint16_t TMin; + uint16_t TSample; + uint16_t hTADConv; + + /* DAC settings --------------------------------------------------------------*/ + /* PWM Driving signals initialization ----------------------------------------*/ + LowSideOutputsFunction_t LowSideOutputs; /*!< Low side or enabling signals + generation method are defined + here.*/ + uint8_t IChannel; + uint8_t ISamplingTime; + uint8_t RepetitionCounter; /*!< It expresses the number of PWM + periods to be elapsed before compare + registers are updated again. In + particular: + RepetitionCounter= (2* #PWM periods)-1*/ + /* Emergency input (BKIN2) signal initialization -----------------------------*/ + FunctionalState EmergencyStop; /*!< It enable/disable the management of + an emergency input instantaneously + stopping PWM generation. It must be + either equal to ENABLE or DISABLE */ + /* Internal COMP settings ----------------------------------------------------*/ + /* Dual MC parameters --------------------------------------------------------*/ + uint8_t FreqRatio; /*!< It is used in case of dual MC to + synchronize TIM1 and TIM8. It has + effect only on the second instanced + object and must be equal to the + ratio between the two PWM frequencies + (higher/lower). Supported values are + 1, 2 or 3 */ + uint8_t IsHigherFreqTim; /*!< When bFreqRatio is greather than 1 + this param is used to indicate if this + instance is the one with the highest + frequency. Allowed value are: HIGHER_FREQ + or LOWER_FREQ */ + + } R1_Params_t; + + /** + * @brief Handle structure of the r1_ps_pwm_curr_fdbk Component + */ + typedef struct + { + PWMC_Handle_t _Super; /*!< Offset of current sensing network */ + uint16_t DmaBuffCCR[6]; /*!< Buffer used for PWM phase shift points */ + uint16_t DmaBuffCCR_latch[6]; /*!< Buffer used to latch PWM phase shift points */ + uint32_t PhaseOffset; /*!< Offset of Phase current sensing network */ + uint32_t AdcExtTrigger; /*!< external ADC trigger */ + uint16_t aShiftval[3]; /*!< shift value to be applied */ + uint16_t DmaBuffCCR_ADCTrig[3]; /*!< Buffer used to store sampling point values */ + uint16_t CurConv[2]; /*!< Buffer used to store sampled currents */ + uint16_t Half_PWMPeriod; /* Half PWM Period in timer clock counts */ + uint16_t CntSmp1; /*!< First sampling point express in timer counts*/ + uint16_t CntSmp2; /*!< Second sampling point express in timer counts*/ + uint8_t sampCur1; /*!< Current sampled in the first sampling point*/ + uint8_t sampCur2; /*!< Current sampled in the second sampling point*/ + int16_t CurrAOld; /*!< Previous measured value of phase A current*/ + int16_t CurrBOld; /*!< Previous measured value of phase B current*/ + volatile uint8_t Index; /*!< Number of conversions performed during the + calibration phase*/ + uint8_t iflag; + uint8_t TCCnt; + + bool UpdateFlagBuffer; /*!< buffered version of Timer update IT flag */ + bool OverCurrentFlag; /*!< This flag is set when an overcurrent occurs.*/ + bool OverVoltageFlag; /*!< This flag is set when an overvoltage occurs.*/ + bool BrakeActionLock; /*!< This flag is set to avoid that brake action is + interrupted.*/ + bool FOCDurationFlag; /*!< This flag is used to detect FOC duration error.*/ + bool TCDoneFlag; /*!< This flag is used to indicate that last DMA TC of the period + is done.*/ + bool ADCRegularLocked; + R1_Params_t const *pParams_str; + + } PWMC_R1_Handle_t; + + /** + * It performs the initialization of the MCU peripherals required for + * the PWM generation and current sensing. this initialization is dedicated + * to one shunt topology and F3 family + */ + void R1_Init(PWMC_R1_Handle_t *pHandle); + + /** + * It disables PWM generation on the proper Timer peripheral acting on + * MOE bit + */ + void R1_SwitchOffPWM(PWMC_Handle_t *pHdl); + + /** + * It enables PWM generation on the proper Timer peripheral acting on MOE + * bit + */ + void R1_SwitchOnPWM(PWMC_Handle_t *pHdl); + + /** + * It turns on low sides switches. This function is intended to be + * used for charging boot capacitors of driving section. It has to be + * called each motor start-up when using high voltage drivers + */ + void R1_TurnOnLowSides(PWMC_Handle_t *pHdl, uint32_t ticks); + + /** + * It computes and return latest converted motor phase currents motor + */ + void R1_GetPhaseCurrents(PWMC_Handle_t *pHdl, ab_t *pStator_Currents); + + /** + * It contains the TIMx Break2 event interrupt + */ + void *R1_BRK2_IRQHandler(PWMC_R1_Handle_t *pHdl); + + /** + * It contains the TIMx Break1 event interrupt + */ + void *R1_BRK_IRQHandler(PWMC_R1_Handle_t *pHdl); + + /** + * It stores into pHandle the offset voltage read onchannels when no + * current is flowing into the motor + */ + void R1_CurrentReadingCalibration(PWMC_Handle_t *pHdl); + + /** + * Implementation of the single shunt algorithm to setup the + * TIM1 register and DMA buffers values for the next PWM period. + */ + uint16_t R1_CalcDutyCycles(PWMC_Handle_t *pHdl); + + /** + * It is used to check if an overcurrent occurred since last call. + */ + uint16_t R1_IsOverCurrentOccurred(PWMC_Handle_t *pHdl); + + /** + * This function handles motor DMAx TC interrupt request. + */ + void *R1_DMAx_TC_IRQHandler(PWMC_R1_Handle_t *pHandle); + + /** + * This function handles motor DMAx HT interrupt request. + */ + void *R1_DMAx_HT_IRQHandler(PWMC_R1_Handle_t *pHandle); + + /** + * It contains the TIM1 Update event interrupt + */ + void *R1_TIM1_UP_IRQHandler(PWMC_R1_Handle_t *pHandle); + + /** + * It contains the TIM8 Update event interrupt + */ + void *R1_TIM8_UP_IRQHandler(PWMC_R1_Handle_t *pHandle); + + /** + * It sets the calibrated offset. In single, only Phase A member is used + * to set the offset. + */ + void R1_SetOffsetCalib(PWMC_Handle_t *pHdl, PolarizationOffsets_t *offsets); + + /** + * It reads the calibrated offsets.In single, offset is written + * in phase A member. + */ + void R1_GetOffsetCalib(PWMC_Handle_t *pHdl, PolarizationOffsets_t *offsets); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /*__R1_PS_F30X_PWMCURRFDBK_H*/ + +/******************* (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/regular_conversion_manager.c b/src/firmware/motor/regular_conversion_manager.c new file mode 100644 index 0000000000..9758a7bbb3 --- /dev/null +++ b/src/firmware/motor/regular_conversion_manager.c @@ -0,0 +1,691 @@ + +/** + ****************************************************************************** + * @file regular_conversion_manager.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file provides firmware functions that implement the following features + * of the regular_conversion_manager component of the Motor Control SDK: + * Register conversion with or without callback + * Execute regular conv directly from Temperature and VBus sensors + * Execute user regular conversion scheduled by medium frequency task + * Manage user conversion state machine + * + + * + + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "regular_conversion_manager.h" + +#include "mc_config.h" +#include "mcsdk/mc_type.h" + +/** @addtogroup MCSDK + * @{ + */ + +/** @defgroup RCM Regular Conversion Manager + * @brief Regular Conversion Manager component of the Motor Control SDK + * + * MotorControl SDK makes an extensive usage of ADCs. Some conversions are timing critical + * like current reading, and some have less constraints. If an ADC offers both Injected + * and Regular, channels, critical conversions will be systematically done on Injected + * channels, because they interrupt any ongoing regular conversion so as to be executed + * without delay. Others conversions, mainly Bus voltage, and Temperature sensing are + * performed with regular channels. If users wants to perform ADC conversions with an ADC + * already used by MC SDK, they must use regular conversions. It is forbidden to use + * Injected channel on an ADC that is already in use for current reading. As usera and + * MC-SDK may share ADC regular scheduler, this component intents to manage all the + * regular conversions. + * + * If users wants to execute their own conversion, they first have to register it through + * the RCM_RegisterRegConv_WithCB() or RCM_RegisterRegConv() APIs. Multiple conversions + * can be registered, but only one can be scheduled at a time . + * + * A requested user regular conversion will be executed by the medium frequency task after + * the MC-SDK regular safety conversions: Bus voltage and Temperature. + * + * If a callback is registered, particular care must be taken with the code executed + * inside the CB. The callback code is executed under Medium frequency task IRQ context + * (Systick). + * + * If the Users do not register a callback, they must poll the RCM state machine to know + * if a conversion is ready to be read, scheduled, or free to be scheduled. This is + * performed through the RCM_GetUserConvState() API. + * + * If the state is #RCM_USERCONV_IDLE, a conversion is ready to be scheduled. + * if a conversion is already scheduled, the returned value is #RCM_USERCONV_REQUESTED. + * if a conversion is ready to be read, the returned value is #RCM_USERCONV_EOC. + * In #RCM_USERCONV_EOC state, a call to RCM_GetUserConv will consume the value, and set + * the state machine back to #RCM_USERCONV_IDLE state. It implies that a second call + * without new conversion performed, will send back 0xffff which is an error value meaning + * that the data is not available. If a conversion request is executed, but the previous + * conversion has not been completed, nor consumed, the request is discarded and the + * RCM_RequestUserConv() return false. + * + * If a callback is registered, the data read is sent back to the callback parameters, and + * therefor consumed. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/** + * @brief Document as stated in template.h + * + * ... + */ +typedef enum +{ + notvalid, + ongoing, + valid +} RCM_status_t; + +typedef struct +{ + bool enable; + RCM_status_t status; + uint16_t value; + uint8_t prev; + uint8_t next; +} RCM_NoInj_t; + +typedef struct +{ + RCM_exec_cb_t cb; + void *data; +} RCM_callback_t; + +/* Private defines -----------------------------------------------------------*/ +/** + * @brief Number of regular conversion allowed By default. + * + * In single drive configuration, it is defined to 4. 2 of them are consumed by + * Bus voltage and temperature reading. This leaves 2 handles available for + * user conversions + * + * In dual drives configuration, it is defined to 6. 2 of them are consumed by + * Bus voltage and temperature reading for each motor. This leaves 2 handles + * available for user conversion. + * + * Defined to 4 here. + */ +#define RCM_MAX_CONV 4U + +/* Global variables ----------------------------------------------------------*/ + +static RegConv_t *RCM_handle_array[RCM_MAX_CONV]; +static RCM_callback_t RCM_CB_array[RCM_MAX_CONV]; + +static RCM_NoInj_t RCM_NoInj_array[RCM_MAX_CONV]; +static uint8_t RCM_currentHandle; +static uint16_t RCM_UserConvValue; +static RCM_UserConvState_t RCM_UserConvState; +static uint8_t RCM_UserConvHandle; + +/* Private function prototypes -----------------------------------------------*/ + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief Registers a regular conversion, and attaches a callback. + * + * This function registers a regular ADC conversion that can be later scheduled for + * execution. It returns a handle that uniquely identifies the conversion. This handle is + * used in the other API of the Regular Converion Manager to reference the registered + * conversion. + * + * A regular conversion is defined by an ADC + ADC channel pair. If a registration already + * exists for the requested ADC + ADC channel pair, the same handle will be reused. + * + * The regular conversion is registered along with a callback that is executed each time + * the conversion has completed. The callback is invoked with two parameters: + * + * - the handle of the regular conversion + * - a data pointer, supplied by uthe users at registration time. + * + * The registration may fail if there is no space left for additional conversions. The + * maximum number of regular conversion that can be registered is defined by + * #RCM_MAX_CONV. + * + * @note Users who do not want a callback to be executed at the end of the conversion, + * should use RCM_RegisterRegConv() instead. + * + * @param regConv Pointer to the regular conversion parameters. + * Contains ADC, Channel and sampling time to be used. + * + * @param fctCB Function called once the regular conversion is executed. + * + * @param data Used to save a user context. this parameter will be send back by + * the fctCB function. @b Note: This parameter can be NULL if not used. + * + * @retval the handle of the registered conversion or 255 if the registration failed + */ +uint8_t RCM_RegisterRegConv_WithCB(RegConv_t *regConv, RCM_exec_cb_t fctCB, void *data) +{ + uint8_t handle; + handle = RCM_RegisterRegConv(regConv); + if (handle < RCM_MAX_CONV) + { + RCM_CB_array[handle].cb = fctCB; + RCM_CB_array[handle].data = data; + } + else + { + /* Nothing to do */ + } + return handle; +} + +/** + * @brief Registers a regular conversion. + * + * This function registers a regular ADC conversion that can be later scheduled for + * execution. It returns a handle that uniquely identifies the conversion. This handle is + * used in the other API of the Regular Converion Manager to reference the registered + * conversion. + * + * A regular conversion is defined by an ADC + ADC channel pair. If a registration already + * exists for the requested ADC + ADC channel pair, the same handle will be reused. + * + * The registration may fail if there is no space left for additional conversions. The + * maximum number of regular conversion that can be registered is defined by + * #RCM_MAX_CONV. + * + * @note Users who do not want a callback to be executed at the end of the conversion, + * should use RCM_RegisterRegConv() instead. + * + * @param regConv Pointer to the regular conversion parameters. + * Contains ADC, Channel and sampling time to be used. + * + * @retval the handle of the registered conversion or 255 if the registration failed + */ +uint8_t RCM_RegisterRegConv(RegConv_t *regConv) +{ + uint8_t handle = 255U; +#ifdef NULL_PTR_REG_CON_MNG + if (MC_NULL == regConv) + { + handle = 0U; + } + else + { +#endif + uint8_t i = 0; + + /* Parse the array to be sure that same + * conversion does not already exist*/ + while (i < RCM_MAX_CONV) + { + if ((0 == RCM_handle_array[i]) && (handle > RCM_MAX_CONV)) + { + handle = i; /* First location available, but still looping to check that + this config does not already exist*/ + } + else + { + /* Nothing to do */ + } + /* Ticket 64042 : If RCM_handle_array [i] is null access to data member will + * cause Memory Fault. */ + if (RCM_handle_array[i] != 0) + { + if ((RCM_handle_array[i]->channel == regConv->channel) && + (RCM_handle_array[i]->regADC == regConv->regADC)) + { + handle = i; /* Reuse the same handle */ + i = RCM_MAX_CONV; /* we can skip the rest of the loop*/ + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do */ + } + i++; + } + if (handle < RCM_MAX_CONV) + { + RCM_handle_array[handle] = regConv; + RCM_CB_array[handle].cb = + NULL; /* if a previous callback was attached, it is cleared*/ + if (0U == LL_ADC_IsEnabled(regConv->regADC)) + { + LL_ADC_StartCalibration(regConv->regADC); + while (1U == LL_ADC_IsCalibrationOnGoing(regConv->regADC)) + { + /* Nothing to do */ + } + LL_ADC_Enable(regConv->regADC); + } + else + { + /* Nothing to do */ + } + /* conversion handler is created, will be enabled by the first call to + * RCM_ExecRegularConv*/ + RCM_NoInj_array[handle].enable = false; + RCM_NoInj_array[handle].next = handle; + RCM_NoInj_array[handle].prev = handle; + } + else + { + /* Nothing to do handle is already set to error value : 255 */ + } +#ifdef NULL_PTR_REG_CON_MNG + } +#endif + return (handle); +} + +/* + * This function is used to read the result of a regular conversion. + * Depending of the MC state machine, this function can poll on the ADC end of conversion + * or not. If the ADC is already in use for currents sensing, the regular conversion can + * not be executed instantaneously but have to be scheduled in order to be executed after + * currents sensing inside HF task. This function takes care of inserting the handle into + * the scheduler. If it is possible to execute the conversion instantaneously, it will be + * executed, and result returned. Otherwise, the latest stored conversion result will be + * returned. + * + * NOTE: This function is not part of the public API and users should not call it. + */ +uint16_t RCM_ExecRegularConv(uint8_t handle) +{ + uint16_t retVal; + uint8_t formerNext; + uint8_t i = 0; + uint8_t LastEnable = RCM_MAX_CONV; + + if (false == RCM_NoInj_array[handle].enable) + { + /* find position in the list */ + while (i < RCM_MAX_CONV) + { + if (true == RCM_NoInj_array[i].enable) + { + if (RCM_NoInj_array[i].next > handle) + /* We found a previous reg conv to link with */ + { + formerNext = RCM_NoInj_array[i].next; + RCM_NoInj_array[handle].next = formerNext; + RCM_NoInj_array[handle].prev = i; + RCM_NoInj_array[i].next = handle; + RCM_NoInj_array[formerNext].prev = handle; + i = RCM_MAX_CONV; /* stop the loop, handler inserted*/ + } + else + { /* We found an enabled regular conv, + * but do not know yet if it is the one we have to be linked to. */ + LastEnable = i; + } + } + else + { + /* nothing to do */ + } + i++; + if (RCM_MAX_CONV == i) + /* We reach end of the array without handler inserted*/ + { + if (LastEnable != RCM_MAX_CONV) + /* we find a regular conversion with smaller position to be linked with */ + { + formerNext = RCM_NoInj_array[LastEnable].next; + RCM_NoInj_array[handle].next = formerNext; + RCM_NoInj_array[handle].prev = LastEnable; + RCM_NoInj_array[LastEnable].next = handle; + RCM_NoInj_array[formerNext].prev = handle; + } + else + { /* the current handle is the only one in the list */ + /* previous and next are already pointing to itself (done at + * registerRegConv) */ + RCM_currentHandle = handle; + } + } + else + { + /* Nothing to do we are parsing the array, nothing inserted yet*/ + } + } + /* The handle is now linked with others, we can set the enable flag */ + RCM_NoInj_array[handle].enable = true; + RCM_NoInj_array[handle].status = notvalid; + if (RCM_NoInj_array[RCM_currentHandle].status != ongoing) + { /* select the new conversion to be the next scheduled only if a conversion is + not ongoing*/ + RCM_currentHandle = handle; + } + else + { + /* Nothing to do */ + } + } + else + { + /* Nothing to do the current handle is already scheduled */ + } + if (false == PWM_Handle_M1.ADCRegularLocked) + /* The ADC is free to be used asynchronously*/ + { + LL_ADC_REG_SetDMATransfer(RCM_handle_array[handle]->regADC, + LL_ADC_REG_DMA_TRANSFER_NONE); + + /* ADC STOP condition requested to write CHSELR is true because of the ADCSTOP is + set by hardware at the end of A/D conversion if the external Trigger of ADC is + disabled.*/ + + /*By default it is ADSTART = 0, then at the first time the CFGR1 can be written. + */ + + /* Disabling External Trigger of ADC */ + LL_ADC_REG_SetTriggerSource(RCM_handle_array[handle]->regADC, + LL_ADC_REG_TRIG_SOFTWARE); + + /* Set Sampling time and channel */ + LL_ADC_SetSamplingTimeCommonChannels(RCM_handle_array[handle]->regADC, + RCM_handle_array[handle]->samplingTime); + LL_ADC_REG_SetSequencerChannels( + RCM_handle_array[handle]->regADC, + __LL_ADC_DECIMAL_NB_TO_CHANNEL(RCM_handle_array[handle]->channel)); + + /* Clear EOC */ + LL_ADC_ClearFlag_EOC(RCM_handle_array[handle]->regADC); + + /* Start ADC conversion */ + LL_ADC_REG_StartConversion(RCM_handle_array[handle]->regADC); + + /* Wait EOC */ + while (0U == LL_ADC_IsActiveFlag_EOC(RCM_handle_array[handle]->regADC)) + { + /* Nothing to do */ + } + + /* Read the "Regular" conversion (Not related to current sampling) */ + RCM_NoInj_array[handle].value = + LL_ADC_REG_ReadConversionData12(RCM_handle_array[handle]->regADC); + LL_ADC_REG_SetDMATransfer(RCM_handle_array[RCM_currentHandle]->regADC, + LL_ADC_REG_DMA_TRANSFER_LIMITED); + RCM_currentHandle = RCM_NoInj_array[handle].next; + RCM_NoInj_array[handle].status = valid; + } + else + { + /* Nothing to do */ + } + retVal = RCM_NoInj_array[handle].value; + return retVal; +} + +/** + * @brief Schedules a regular conversion for execution. + * + * This function requests the execution of the user-defined regular conversion identified + * by @p handle. All user defined conversion requests must be performed inside routines + * with the same priority level. If a previous regular conversion request is pending this + * function has no effect, for this reason is better to call RCM_GetUserConvState() and + * check if the state is #RCM_USERCONV_IDLE before calling RCM_RequestUserConv(). + * + * @param handle used for the user conversion. + * + * @return true if the regular conversion could be scheduled and false otherwise. + */ +bool RCM_RequestUserConv(uint8_t handle) +{ + bool retVal = false; + if (RCM_USERCONV_IDLE == RCM_UserConvState) + { + RCM_UserConvHandle = handle; + /* must be done last so that RCM_UserConvHandle already has the right value */ + RCM_UserConvState = RCM_USERCONV_REQUESTED; + retVal = true; + } + else + { + /* Nothing to do */ + } + return retVal; +} + +/** + * @brief Returns the last user-defined regular conversion that was executed. + * + * This function returns a valid result if the state returned by + * RCM_GetUserConvState is #RCM_USERCONV_EOC. + * + * @retval uint16_t The converted value or 0xFFFF in case of conversion error. + */ +uint16_t RCM_GetUserConv(void) +{ + uint16_t hRetVal = 0xFFFFu; + if (RCM_USERCONV_EOC == RCM_UserConvState) + { + hRetVal = RCM_UserConvValue; + RCM_UserConvState = RCM_USERCONV_IDLE; + } + else + { + /* Nothing to do */ + } + return hRetVal; +} + +/* + * This function must be scheduled by mc_task. + * It executes the current user conversion that has been selected by the + * latest call to RCM_RequestUserConv + * + * NOTE: This function is not part of the public API and users should not call it. + */ +void RCM_ExecUserConv() +{ + if (RCM_USERCONV_REQUESTED == RCM_UserConvState) + { + RCM_UserConvValue = RCM_ExecRegularConv(RCM_UserConvHandle); + /* Regular conversion is read from RCM_NoInj_array but we must take care that + * first conversion is done*/ + /* status could also be ongoing, but decision is taken to provide previous + * conversion */ + /* instead of waiting for RCM_NoInj_array [RCM_UserConvHandle].status == valid */ + if (RCM_NoInj_array[RCM_UserConvHandle].status != notvalid) + { + RCM_UserConvState = RCM_USERCONV_EOC; + } + else + { + /* Nothing to do */ + } + if (RCM_CB_array[RCM_UserConvHandle].cb != NULL) + { + RCM_UserConvState = RCM_USERCONV_IDLE; + RCM_CB_array[RCM_UserConvHandle].cb(RCM_UserConvHandle, RCM_UserConvValue, + RCM_CB_array[RCM_UserConvHandle].data); + } + else + { + /* Nothing to do */ + } + } +} + +/** + * @brief Returns the status of the last requested regular conversion. + * + * It can be one of the following values: + + * - UDRC_STATE_IDLE no regular conversion request pending. + * - UDRC_STATE_REQUESTED regular conversion has been requested and not completed. + * - UDRC_STATE_EOC regular conversion has been completed but not readed from the user. + * + * @retval The state of the last user-defined regular conversion. + */ +RCM_UserConvState_t RCM_GetUserConvState(void) +{ + return (RCM_UserConvState); +} + +/** + * @brief Un-schedules a regular conversion + * + * This function does not poll ADC read and is meant to be used when + * ADCs do not support injected channels. + * + * In such configurations, once a regular conversion has been executed once, + * It is continuously scheduled in HF task after current reading. + * + * This function remove the handle from the scheduling. + * + * @note Note that even though, in such configurations, regular conversions are + * continuously scheduled after having been requested once, the results of + * subsequent conversions are not made available unless the users invoke + * RCM_RequestUserConv() again. + * + */ +bool RCM_PauseRegularConv(uint8_t handle) +{ + bool retVal; + uint8_t Prev; + uint8_t Next; + + if (handle < RCM_MAX_CONV) + { + retVal = true; + if (true == RCM_NoInj_array[handle].enable) + { + RCM_NoInj_array[handle].enable = false; + RCM_NoInj_array[handle].status = notvalid; + Prev = RCM_NoInj_array[handle].prev; + Next = RCM_NoInj_array[handle].next; + RCM_NoInj_array[Prev].next = RCM_NoInj_array[handle].next; + RCM_NoInj_array[Next].prev = RCM_NoInj_array[handle].prev; + } + else + { + /* Nothing to do */ + } + } + else + { + retVal = false; + } + return (retVal); +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section (".ccmram"))) +#endif +#endif +/* + * Starts the next scheduled regular conversion + * + * This function does not poll on ADC read and is foreseen to be used inside + * high frequency task where ADC are shared between currents reading + * and user conversion. + * + * NOTE: This function is not part of the public API and users should not call it. + */ +void RCM_ExecNextConv(void) +{ + if (true == RCM_NoInj_array[RCM_currentHandle].enable) + { + /* When this function is called, the ADC conversions triggered by External + event for current reading has been completed. + ADC is therefore ready to be started because already stopped.*/ + + /* Clear EOC */ + LL_ADC_ClearFlag_EOC(RCM_handle_array[RCM_currentHandle]->regADC); + /* Disabling ADC DMA request */ + LL_ADC_REG_SetDMATransfer(RCM_handle_array[RCM_currentHandle]->regADC, + LL_ADC_REG_DMA_TRANSFER_NONE); + + /* Disabling External Trigger of ADC */ + LL_ADC_REG_SetTriggerSource(RCM_handle_array[RCM_currentHandle]->regADC, + LL_ADC_REG_TRIG_SOFTWARE); + + /* Set Sampling time and channel of ADC for Regular Conversion */ + LL_ADC_SetSamplingTimeCommonChannels( + RCM_handle_array[RCM_currentHandle]->regADC, + RCM_handle_array[RCM_currentHandle]->samplingTime); + (void)LL_ADC_REG_SetSequencerChannels( + RCM_handle_array[RCM_currentHandle]->regADC, + __LL_ADC_DECIMAL_NB_TO_CHANNEL(RCM_handle_array[RCM_currentHandle]->channel)); + /* Start ADC for regular conversion */ + LL_ADC_REG_StartConversion(RCM_handle_array[RCM_currentHandle]->regADC); + RCM_NoInj_array[RCM_currentHandle].status = ongoing; + } + else + { + /* nothing to do, conversion not enabled have already notvalid status */ + } +} + +#if defined(CCMRAM) +#if defined(__ICCARM__) +#pragma location = ".ccmram" +#elif defined(__CC_ARM) || defined(__GNUC__) +__attribute__((section (".ccmram"))) +#endif +#endif +/* + * Reads the result of the ongoing regular conversion + * + * This function is foreseen to be used inside + * high frequency task where ADC are shared between current reading + * and user conversion. + * + * NOTE: This function is not part of the public API and users should not call it. + */ +void RCM_ReadOngoingConv(void) +{ + uint32_t result; + RCM_status_t status; + + status = RCM_NoInj_array[RCM_currentHandle].status; + result = LL_ADC_IsActiveFlag_EOC(RCM_handle_array[RCM_currentHandle]->regADC); + if ((valid == status) || (notvalid == status) || (0U == result)) + { + /* Nothing to do */ + } + else + { + /* Reading of ADC Converted Value */ + RCM_NoInj_array[RCM_currentHandle].value = + LL_ADC_REG_ReadConversionData12(RCM_handle_array[RCM_currentHandle]->regADC); + RCM_NoInj_array[RCM_currentHandle].status = valid; + /* Restore back DMA configuration. */ + LL_ADC_REG_SetDMATransfer(RCM_handle_array[RCM_currentHandle]->regADC, + LL_ADC_REG_DMA_TRANSFER_LIMITED); + } + + /* Prepare next conversion */ + RCM_currentHandle = RCM_NoInj_array[RCM_currentHandle].next; +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT 2022 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/regular_conversion_manager.h b/src/firmware/motor/regular_conversion_manager.h new file mode 100644 index 0000000000..614e7f0e4d --- /dev/null +++ b/src/firmware/motor/regular_conversion_manager.h @@ -0,0 +1,119 @@ + +/** + ****************************************************************************** + * @file regular_conversion_manager.h + * @author Motor Control SDK Team, ST Microelectronics + * @brief This file contains all definitions and functions prototypes for the + * regular_conversion_manager component of the Motor Control SDK. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2022 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef REGULAR_CONVERSION_MANAGER_H +#define REGULAR_CONVERSION_MANAGER_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mcsdk/mc_type.h" + + /** @addtogroup MCSDK + * @{ + */ + + /** @addtogroup RCM + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief RegConv_t contains all the parameters required to execute a regular + * conversion + * + * it is used by all regular_conversion_manager's client + * + */ + typedef struct + { + ADC_TypeDef *regADC; + uint8_t channel; + uint32_t samplingTime; + } RegConv_t; + + /** + * @brief Conversion states + */ + typedef enum + { + RCM_USERCONV_IDLE, /**< @brief No conversion currently scheduled */ + RCM_USERCONV_REQUESTED, /**< @brief A conversion is scheduled for execution */ + RCM_USERCONV_EOC /**< @brief A conversion has completed and the value is ready */ + } RCM_UserConvState_t; + + typedef void (*RCM_exec_cb_t)(uint8_t handle, uint16_t data, void *UserData); + + /* Exported functions ------------------------------------------------------- */ + + /* Function used to register a regular conversion */ + uint8_t RCM_RegisterRegConv(RegConv_t *regConv); + + /* Function used to register a regular conversion with a callback attached*/ + uint8_t RCM_RegisterRegConv_WithCB(RegConv_t *regConv, RCM_exec_cb_t fctCB, + void *data); + + /* Function used to execute an already registered regular conversion */ + uint16_t RCM_ExecRegularConv(uint8_t handle); + + /* select the handle conversion to be executed during the next call to + * RCM_ExecUserConv */ + bool RCM_RequestUserConv(uint8_t handle); + + /* return the latest user conversion value*/ + uint16_t RCM_GetUserConv(void); + + /* Must be called by MC_TASK only to grantee proper scheduling*/ + void RCM_ExecUserConv(void); + + /* return the state of the user conversion state machine*/ + RCM_UserConvState_t RCM_GetUserConvState(void); + + /* Function used to un-schedule a regular conversion exectuted after current sampling + * in HF task */ + bool RCM_PauseRegularConv(uint8_t handle); + + /* non blocking function to start conversion inside HF task */ + void RCM_ExecNextConv(void); + + /* non blocking function used to read back already started regular conversion*/ + void RCM_ReadOngoingConv(void); + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cpluplus */ + +#endif /* REGULAR_CONVERSION_MANAGER_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/stm32f0xx/legacy/stm32_hal_legacy.h b/src/firmware/motor/stm32f0xx/legacy/stm32_hal_legacy.h new file mode 100644 index 0000000000..32d84f5b74 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/legacy/stm32_hal_legacy.h @@ -0,0 +1,4608 @@ +/** + ****************************************************************************** + * @file stm32_hal_legacy.h + * @author MCD Application Team + * @brief This file contains aliases definition for the STM32Cube HAL constants + * macros and functions maintained for legacy purpose. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32_HAL_LEGACY +#define STM32_HAL_LEGACY + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HAL_AES_Aliased_Defines HAL CRYP Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define AES_FLAG_RDERR CRYP_FLAG_RDERR +#define AES_FLAG_WRERR CRYP_FLAG_WRERR +#define AES_CLEARFLAG_CCF CRYP_CLEARFLAG_CCF +#define AES_CLEARFLAG_RDERR CRYP_CLEARFLAG_RDERR +#define AES_CLEARFLAG_WRERR CRYP_CLEARFLAG_WRERR +#if defined(STM32U5) || defined(STM32H7) || defined(STM32MP1) +#define CRYP_DATATYPE_32B CRYP_NO_SWAP +#define CRYP_DATATYPE_16B CRYP_HALFWORD_SWAP +#define CRYP_DATATYPE_8B CRYP_BYTE_SWAP +#define CRYP_DATATYPE_1B CRYP_BIT_SWAP +#if defined(STM32U5) +#define CRYP_CCF_CLEAR CRYP_CLEAR_CCF +#define CRYP_ERR_CLEAR CRYP_CLEAR_RWEIF +#endif /* STM32U5 */ +#endif /* STM32U5 || STM32H7 || STM32MP1 */ +/** + * @} + */ + +/** @defgroup HAL_ADC_Aliased_Defines HAL ADC Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define ADC_RESOLUTION12b ADC_RESOLUTION_12B +#define ADC_RESOLUTION10b ADC_RESOLUTION_10B +#define ADC_RESOLUTION8b ADC_RESOLUTION_8B +#define ADC_RESOLUTION6b ADC_RESOLUTION_6B +#define OVR_DATA_OVERWRITTEN ADC_OVR_DATA_OVERWRITTEN +#define OVR_DATA_PRESERVED ADC_OVR_DATA_PRESERVED +#define EOC_SINGLE_CONV ADC_EOC_SINGLE_CONV +#define EOC_SEQ_CONV ADC_EOC_SEQ_CONV +#define EOC_SINGLE_SEQ_CONV ADC_EOC_SINGLE_SEQ_CONV +#define REGULAR_GROUP ADC_REGULAR_GROUP +#define INJECTED_GROUP ADC_INJECTED_GROUP +#define REGULAR_INJECTED_GROUP ADC_REGULAR_INJECTED_GROUP +#define AWD_EVENT ADC_AWD_EVENT +#define AWD1_EVENT ADC_AWD1_EVENT +#define AWD2_EVENT ADC_AWD2_EVENT +#define AWD3_EVENT ADC_AWD3_EVENT +#define OVR_EVENT ADC_OVR_EVENT +#define JQOVF_EVENT ADC_JQOVF_EVENT +#define ALL_CHANNELS ADC_ALL_CHANNELS +#define REGULAR_CHANNELS ADC_REGULAR_CHANNELS +#define INJECTED_CHANNELS ADC_INJECTED_CHANNELS +#define SYSCFG_FLAG_SENSOR_ADC ADC_FLAG_SENSOR +#define SYSCFG_FLAG_VREF_ADC ADC_FLAG_VREFINT +#define ADC_CLOCKPRESCALER_PCLK_DIV1 ADC_CLOCK_SYNC_PCLK_DIV1 +#define ADC_CLOCKPRESCALER_PCLK_DIV2 ADC_CLOCK_SYNC_PCLK_DIV2 +#define ADC_CLOCKPRESCALER_PCLK_DIV4 ADC_CLOCK_SYNC_PCLK_DIV4 +#define ADC_CLOCKPRESCALER_PCLK_DIV6 ADC_CLOCK_SYNC_PCLK_DIV6 +#define ADC_CLOCKPRESCALER_PCLK_DIV8 ADC_CLOCK_SYNC_PCLK_DIV8 +#define ADC_EXTERNALTRIG0_T6_TRGO ADC_EXTERNALTRIGCONV_T6_TRGO +#define ADC_EXTERNALTRIG1_T21_CC2 ADC_EXTERNALTRIGCONV_T21_CC2 +#define ADC_EXTERNALTRIG2_T2_TRGO ADC_EXTERNALTRIGCONV_T2_TRGO +#define ADC_EXTERNALTRIG3_T2_CC4 ADC_EXTERNALTRIGCONV_T2_CC4 +#define ADC_EXTERNALTRIG4_T22_TRGO ADC_EXTERNALTRIGCONV_T22_TRGO +#define ADC_EXTERNALTRIG7_EXT_IT11 ADC_EXTERNALTRIGCONV_EXT_IT11 +#define ADC_CLOCK_ASYNC ADC_CLOCK_ASYNC_DIV1 +#define ADC_EXTERNALTRIG_EDGE_NONE ADC_EXTERNALTRIGCONVEDGE_NONE +#define ADC_EXTERNALTRIG_EDGE_RISING ADC_EXTERNALTRIGCONVEDGE_RISING +#define ADC_EXTERNALTRIG_EDGE_FALLING ADC_EXTERNALTRIGCONVEDGE_FALLING +#define ADC_EXTERNALTRIG_EDGE_RISINGFALLING ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING +#define ADC_SAMPLETIME_2CYCLE_5 ADC_SAMPLETIME_2CYCLES_5 + +#define HAL_ADC_STATE_BUSY_REG HAL_ADC_STATE_REG_BUSY +#define HAL_ADC_STATE_BUSY_INJ HAL_ADC_STATE_INJ_BUSY +#define HAL_ADC_STATE_EOC_REG HAL_ADC_STATE_REG_EOC +#define HAL_ADC_STATE_EOC_INJ HAL_ADC_STATE_INJ_EOC +#define HAL_ADC_STATE_ERROR HAL_ADC_STATE_ERROR_INTERNAL +#define HAL_ADC_STATE_BUSY HAL_ADC_STATE_BUSY_INTERNAL +#define HAL_ADC_STATE_AWD HAL_ADC_STATE_AWD1 + +#if defined(STM32H7) +#define ADC_CHANNEL_VBAT_DIV4 ADC_CHANNEL_VBAT +#endif /* STM32H7 */ + +#if defined(STM32U5) +#define ADC_SAMPLETIME_5CYCLE ADC_SAMPLETIME_5CYCLES +#define ADC_SAMPLETIME_391CYCLES_5 ADC_SAMPLETIME_391CYCLES +#define ADC4_SAMPLETIME_160CYCLES_5 ADC4_SAMPLETIME_814CYCLES_5 +#endif /* STM32U5 */ + +#if defined(STM32H5) +#define ADC_CHANNEL_VCORE ADC_CHANNEL_VDDCORE +#endif /* STM32H5 */ + /** + * @} + */ + + /** @defgroup HAL_CEC_Aliased_Defines HAL CEC Aliased Defines maintained for legacy + * purpose + * @{ + */ + +#define __HAL_CEC_GET_IT __HAL_CEC_GET_FLAG + +/** + * @} + */ + +/** @defgroup HAL_COMP_Aliased_Defines HAL COMP Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define COMP_WINDOWMODE_DISABLED COMP_WINDOWMODE_DISABLE +#define COMP_WINDOWMODE_ENABLED COMP_WINDOWMODE_ENABLE +#define COMP_EXTI_LINE_COMP1_EVENT COMP_EXTI_LINE_COMP1 +#define COMP_EXTI_LINE_COMP2_EVENT COMP_EXTI_LINE_COMP2 +#define COMP_EXTI_LINE_COMP3_EVENT COMP_EXTI_LINE_COMP3 +#define COMP_EXTI_LINE_COMP4_EVENT COMP_EXTI_LINE_COMP4 +#define COMP_EXTI_LINE_COMP5_EVENT COMP_EXTI_LINE_COMP5 +#define COMP_EXTI_LINE_COMP6_EVENT COMP_EXTI_LINE_COMP6 +#define COMP_EXTI_LINE_COMP7_EVENT COMP_EXTI_LINE_COMP7 +#if defined(STM32L0) +#define COMP_LPTIMCONNECTION_ENABLED \ + ((uint32_t)0x00000003U) /*!< COMPX output generic naming: connected to LPTIM \ + input 1 for COMP1, LPTIM input 2 for COMP2 */ +#endif +#define COMP_OUTPUT_COMP6TIM2OCREFCLR COMP_OUTPUT_COMP6_TIM2OCREFCLR +#if defined(STM32F373xC) || defined(STM32F378xx) +#define COMP_OUTPUT_TIM3IC1 COMP_OUTPUT_COMP1_TIM3IC1 +#define COMP_OUTPUT_TIM3OCREFCLR COMP_OUTPUT_COMP1_TIM3OCREFCLR +#endif /* STM32F373xC || STM32F378xx */ + +#if defined(STM32L0) || defined(STM32L4) +#define COMP_WINDOWMODE_ENABLE COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON + +#define COMP_NONINVERTINGINPUT_IO1 COMP_INPUT_PLUS_IO1 +#define COMP_NONINVERTINGINPUT_IO2 COMP_INPUT_PLUS_IO2 +#define COMP_NONINVERTINGINPUT_IO3 COMP_INPUT_PLUS_IO3 +#define COMP_NONINVERTINGINPUT_IO4 COMP_INPUT_PLUS_IO4 +#define COMP_NONINVERTINGINPUT_IO5 COMP_INPUT_PLUS_IO5 +#define COMP_NONINVERTINGINPUT_IO6 COMP_INPUT_PLUS_IO6 + +#define COMP_INVERTINGINPUT_1_4VREFINT COMP_INPUT_MINUS_1_4VREFINT +#define COMP_INVERTINGINPUT_1_2VREFINT COMP_INPUT_MINUS_1_2VREFINT +#define COMP_INVERTINGINPUT_3_4VREFINT COMP_INPUT_MINUS_3_4VREFINT +#define COMP_INVERTINGINPUT_VREFINT COMP_INPUT_MINUS_VREFINT +#define COMP_INVERTINGINPUT_DAC1_CH1 COMP_INPUT_MINUS_DAC1_CH1 +#define COMP_INVERTINGINPUT_DAC1_CH2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_DAC1 COMP_INPUT_MINUS_DAC1_CH1 +#define COMP_INVERTINGINPUT_DAC2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_IO1 COMP_INPUT_MINUS_IO1 +#if defined(STM32L0) +/* Issue fixed on STM32L0 COMP driver: only 2 dedicated IO (IO1 and IO2), */ +/* IO2 was wrongly assigned to IO shared with DAC and IO3 was corresponding */ +/* to the second dedicated IO (only for COMP2). */ +#define COMP_INVERTINGINPUT_IO2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_IO3 COMP_INPUT_MINUS_IO2 +#else +#define COMP_INVERTINGINPUT_IO2 COMP_INPUT_MINUS_IO2 +#define COMP_INVERTINGINPUT_IO3 COMP_INPUT_MINUS_IO3 +#endif +#define COMP_INVERTINGINPUT_IO4 COMP_INPUT_MINUS_IO4 +#define COMP_INVERTINGINPUT_IO5 COMP_INPUT_MINUS_IO5 + +#define COMP_OUTPUTLEVEL_LOW COMP_OUTPUT_LEVEL_LOW +#define COMP_OUTPUTLEVEL_HIGH COMP_OUTPUT_LEVEL_HIGH + +/* Note: Literal "COMP_FLAG_LOCK" kept for legacy purpose. */ +/* To check COMP lock state, use macro "__HAL_COMP_IS_LOCKED()". */ +#if defined(COMP_CSR_LOCK) +#define COMP_FLAG_LOCK COMP_CSR_LOCK +#elif defined(COMP_CSR_COMP1LOCK) +#define COMP_FLAG_LOCK COMP_CSR_COMP1LOCK +#elif defined(COMP_CSR_COMPxLOCK) +#define COMP_FLAG_LOCK COMP_CSR_COMPxLOCK +#endif + +#if defined(STM32L4) +#define COMP_BLANKINGSRCE_TIM1OC5 COMP_BLANKINGSRC_TIM1_OC5_COMP1 +#define COMP_BLANKINGSRCE_TIM2OC3 COMP_BLANKINGSRC_TIM2_OC3_COMP1 +#define COMP_BLANKINGSRCE_TIM3OC3 COMP_BLANKINGSRC_TIM3_OC3_COMP1 +#define COMP_BLANKINGSRCE_TIM3OC4 COMP_BLANKINGSRC_TIM3_OC4_COMP2 +#define COMP_BLANKINGSRCE_TIM8OC5 COMP_BLANKINGSRC_TIM8_OC5_COMP2 +#define COMP_BLANKINGSRCE_TIM15OC1 COMP_BLANKINGSRC_TIM15_OC1_COMP2 +#define COMP_BLANKINGSRCE_NONE COMP_BLANKINGSRC_NONE +#endif + +#if defined(STM32L0) +#define COMP_MODE_HIGHSPEED COMP_POWERMODE_MEDIUMSPEED +#define COMP_MODE_LOWSPEED COMP_POWERMODE_ULTRALOWPOWER +#else +#define COMP_MODE_HIGHSPEED COMP_POWERMODE_HIGHSPEED +#define COMP_MODE_MEDIUMSPEED COMP_POWERMODE_MEDIUMSPEED +#define COMP_MODE_LOWPOWER COMP_POWERMODE_LOWPOWER +#define COMP_MODE_ULTRALOWPOWER COMP_POWERMODE_ULTRALOWPOWER +#endif + +#endif + +#if defined(STM32U5) +#define __HAL_COMP_COMP1_EXTI_CLEAR_RASING_FLAG __HAL_COMP_COMP1_EXTI_CLEAR_RISING_FLAG +#endif + +/** + * @} + */ + +/** @defgroup HAL_CORTEX_Aliased_Defines HAL CORTEX Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define __HAL_CORTEX_SYSTICKCLK_CONFIG HAL_SYSTICK_CLKSourceConfig +#if defined(STM32U5) +#define MPU_DEVICE_nGnRnE MPU_DEVICE_NGNRNE +#define MPU_DEVICE_nGnRE MPU_DEVICE_NGNRE +#define MPU_DEVICE_nGRE MPU_DEVICE_NGRE +#endif /* STM32U5 */ +/** + * @} + */ + +/** @defgroup CRC_Aliases CRC API aliases + * @{ + */ +#if defined(STM32H5) || defined(STM32C0) +#else +#define HAL_CRC_Input_Data_Reverse \ + HAL_CRCEx_Input_Data_Reverse /*!< Aliased to HAL_CRCEx_Input_Data_Reverse for \ + inter STM32 series compatibility */ +#define HAL_CRC_Output_Data_Reverse \ + HAL_CRCEx_Output_Data_Reverse /*!< Aliased to HAL_CRCEx_Output_Data_Reverse for \ + inter STM32 series compatibility */ +#endif + /** + * @} + */ + + /** @defgroup HAL_CRC_Aliased_Defines HAL CRC Aliased Defines maintained for legacy + * purpose + * @{ + */ + +#define CRC_OUTPUTDATA_INVERSION_DISABLED CRC_OUTPUTDATA_INVERSION_DISABLE +#define CRC_OUTPUTDATA_INVERSION_ENABLED CRC_OUTPUTDATA_INVERSION_ENABLE + + /** + * @} + */ + + /** @defgroup HAL_DAC_Aliased_Defines HAL DAC Aliased Defines maintained for legacy + * purpose + * @{ + */ + +#define DAC1_CHANNEL_1 DAC_CHANNEL_1 +#define DAC1_CHANNEL_2 DAC_CHANNEL_2 +#define DAC2_CHANNEL_1 DAC_CHANNEL_1 +#define DAC_WAVE_NONE 0x00000000U +#define DAC_WAVE_NOISE DAC_CR_WAVE1_0 +#define DAC_WAVE_TRIANGLE DAC_CR_WAVE1_1 +#define DAC_WAVEGENERATION_NONE DAC_WAVE_NONE +#define DAC_WAVEGENERATION_NOISE DAC_WAVE_NOISE +#define DAC_WAVEGENERATION_TRIANGLE DAC_WAVE_TRIANGLE + +#if defined(STM32G4) || defined(STM32L5) || defined(STM32H7) || defined(STM32U5) +#define DAC_CHIPCONNECT_DISABLE DAC_CHIPCONNECT_EXTERNAL +#define DAC_CHIPCONNECT_ENABLE DAC_CHIPCONNECT_INTERNAL +#endif + +#if defined(STM32U5) +#define DAC_TRIGGER_STOP_LPTIM1_OUT DAC_TRIGGER_STOP_LPTIM1_CH1 +#define DAC_TRIGGER_STOP_LPTIM3_OUT DAC_TRIGGER_STOP_LPTIM3_CH1 +#define DAC_TRIGGER_LPTIM1_OUT DAC_TRIGGER_LPTIM1_CH1 +#define DAC_TRIGGER_LPTIM3_OUT DAC_TRIGGER_LPTIM3_CH1 +#endif + +#if defined(STM32H5) +#define DAC_TRIGGER_LPTIM1_OUT DAC_TRIGGER_LPTIM1_CH1 +#define DAC_TRIGGER_LPTIM2_OUT DAC_TRIGGER_LPTIM2_CH1 +#endif + +#if defined(STM32L1) || defined(STM32L4) || defined(STM32G0) || defined(STM32L5) || \ + defined(STM32H7) || defined(STM32F4) || defined(STM32G4) +#define HAL_DAC_MSP_INIT_CB_ID HAL_DAC_MSPINIT_CB_ID +#define HAL_DAC_MSP_DEINIT_CB_ID HAL_DAC_MSPDEINIT_CB_ID +#endif + +/** + * @} + */ + +/** @defgroup HAL_DMA_Aliased_Defines HAL DMA Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define HAL_REMAPDMA_ADC_DMA_CH2 DMA_REMAP_ADC_DMA_CH2 +#define HAL_REMAPDMA_USART1_TX_DMA_CH4 DMA_REMAP_USART1_TX_DMA_CH4 +#define HAL_REMAPDMA_USART1_RX_DMA_CH5 DMA_REMAP_USART1_RX_DMA_CH5 +#define HAL_REMAPDMA_TIM16_DMA_CH4 DMA_REMAP_TIM16_DMA_CH4 +#define HAL_REMAPDMA_TIM17_DMA_CH2 DMA_REMAP_TIM17_DMA_CH2 +#define HAL_REMAPDMA_USART3_DMA_CH32 DMA_REMAP_USART3_DMA_CH32 +#define HAL_REMAPDMA_TIM16_DMA_CH6 DMA_REMAP_TIM16_DMA_CH6 +#define HAL_REMAPDMA_TIM17_DMA_CH7 DMA_REMAP_TIM17_DMA_CH7 +#define HAL_REMAPDMA_SPI2_DMA_CH67 DMA_REMAP_SPI2_DMA_CH67 +#define HAL_REMAPDMA_USART2_DMA_CH67 DMA_REMAP_USART2_DMA_CH67 +#define HAL_REMAPDMA_I2C1_DMA_CH76 DMA_REMAP_I2C1_DMA_CH76 +#define HAL_REMAPDMA_TIM1_DMA_CH6 DMA_REMAP_TIM1_DMA_CH6 +#define HAL_REMAPDMA_TIM2_DMA_CH7 DMA_REMAP_TIM2_DMA_CH7 +#define HAL_REMAPDMA_TIM3_DMA_CH6 DMA_REMAP_TIM3_DMA_CH6 + +#define IS_HAL_REMAPDMA IS_DMA_REMAP +#define __HAL_REMAPDMA_CHANNEL_ENABLE __HAL_DMA_REMAP_CHANNEL_ENABLE +#define __HAL_REMAPDMA_CHANNEL_DISABLE __HAL_DMA_REMAP_CHANNEL_DISABLE + +#if defined(STM32L4) + +#define HAL_DMAMUX1_REQUEST_GEN_EXTI0 HAL_DMAMUX1_REQ_GEN_EXTI0 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI1 HAL_DMAMUX1_REQ_GEN_EXTI1 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI2 HAL_DMAMUX1_REQ_GEN_EXTI2 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI3 HAL_DMAMUX1_REQ_GEN_EXTI3 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI4 HAL_DMAMUX1_REQ_GEN_EXTI4 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI5 HAL_DMAMUX1_REQ_GEN_EXTI5 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI6 HAL_DMAMUX1_REQ_GEN_EXTI6 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI7 HAL_DMAMUX1_REQ_GEN_EXTI7 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI8 HAL_DMAMUX1_REQ_GEN_EXTI8 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI9 HAL_DMAMUX1_REQ_GEN_EXTI9 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI10 HAL_DMAMUX1_REQ_GEN_EXTI10 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI11 HAL_DMAMUX1_REQ_GEN_EXTI11 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI12 HAL_DMAMUX1_REQ_GEN_EXTI12 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI13 HAL_DMAMUX1_REQ_GEN_EXTI13 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI14 HAL_DMAMUX1_REQ_GEN_EXTI14 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI15 HAL_DMAMUX1_REQ_GEN_EXTI15 +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH0_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH1_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH2_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH3_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH3_EVT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM1_OUT HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX1_REQUEST_GEN_DSI_TE HAL_DMAMUX1_REQ_GEN_DSI_TE +#define HAL_DMAMUX1_REQUEST_GEN_DSI_EOT HAL_DMAMUX1_REQ_GEN_DSI_EOT +#define HAL_DMAMUX1_REQUEST_GEN_DMA2D_EOT HAL_DMAMUX1_REQ_GEN_DMA2D_EOT +#define HAL_DMAMUX1_REQUEST_GEN_LTDC_IT HAL_DMAMUX1_REQ_GEN_LTDC_IT + +#define HAL_DMAMUX_REQUEST_GEN_NO_EVENT HAL_DMAMUX_REQ_GEN_NO_EVENT +#define HAL_DMAMUX_REQUEST_GEN_RISING HAL_DMAMUX_REQ_GEN_RISING +#define HAL_DMAMUX_REQUEST_GEN_FALLING HAL_DMAMUX_REQ_GEN_FALLING +#define HAL_DMAMUX_REQUEST_GEN_RISING_FALLING HAL_DMAMUX_REQ_GEN_RISING_FALLING + +#if defined(STM32L4R5xx) || defined(STM32L4R9xx) || defined(STM32L4R9xx) || \ + defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) +#define DMA_REQUEST_DCMI_PSSI DMA_REQUEST_DCMI +#endif + +#endif /* STM32L4 */ + +#if defined(STM32G0) +#define DMA_REQUEST_DAC1_CHANNEL1 DMA_REQUEST_DAC1_CH1 +#define DMA_REQUEST_DAC1_CHANNEL2 DMA_REQUEST_DAC1_CH2 +#define DMA_REQUEST_TIM16_TRIG_COM DMA_REQUEST_TIM16_COM +#define DMA_REQUEST_TIM17_TRIG_COM DMA_REQUEST_TIM17_COM + +#define LL_DMAMUX_REQ_TIM16_TRIG_COM LL_DMAMUX_REQ_TIM16_COM +#define LL_DMAMUX_REQ_TIM17_TRIG_COM LL_DMAMUX_REQ_TIM17_COM +#endif + +#if defined(STM32H7) + +#define DMA_REQUEST_DAC1 DMA_REQUEST_DAC1_CH1 +#define DMA_REQUEST_DAC2 DMA_REQUEST_DAC1_CH2 + +#define BDMA_REQUEST_LP_UART1_RX BDMA_REQUEST_LPUART1_RX +#define BDMA_REQUEST_LP_UART1_TX BDMA_REQUEST_LPUART1_TX + +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH0_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH1_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH2_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM1_OUT HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM3_OUT HAL_DMAMUX1_REQ_GEN_LPTIM3_OUT +#define HAL_DMAMUX1_REQUEST_GEN_EXTI0 HAL_DMAMUX1_REQ_GEN_EXTI0 +#define HAL_DMAMUX1_REQUEST_GEN_TIM12_TRGO HAL_DMAMUX1_REQ_GEN_TIM12_TRGO + +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH0_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH0_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH1_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH1_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH2_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH2_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH3_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH3_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH4_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH4_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH5_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH5_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH6_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH6_EVT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_RX_WKUP HAL_DMAMUX2_REQ_GEN_LPUART1_RX_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_TX_WKUP HAL_DMAMUX2_REQ_GEN_LPUART1_TX_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM2_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM2_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM3_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM3_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM3_OUT HAL_DMAMUX2_REQ_GEN_LPTIM3_OUT +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM4_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM4_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM5_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM5_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_I2C4_WKUP HAL_DMAMUX2_REQ_GEN_I2C4_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_SPI6_WKUP HAL_DMAMUX2_REQ_GEN_SPI6_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_COMP1_OUT HAL_DMAMUX2_REQ_GEN_COMP1_OUT +#define HAL_DMAMUX2_REQUEST_GEN_COMP2_OUT HAL_DMAMUX2_REQ_GEN_COMP2_OUT +#define HAL_DMAMUX2_REQUEST_GEN_RTC_WKUP HAL_DMAMUX2_REQ_GEN_RTC_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_EXTI0 HAL_DMAMUX2_REQ_GEN_EXTI0 +#define HAL_DMAMUX2_REQUEST_GEN_EXTI2 HAL_DMAMUX2_REQ_GEN_EXTI2 +#define HAL_DMAMUX2_REQUEST_GEN_I2C4_IT_EVT HAL_DMAMUX2_REQ_GEN_I2C4_IT_EVT +#define HAL_DMAMUX2_REQUEST_GEN_SPI6_IT HAL_DMAMUX2_REQ_GEN_SPI6_IT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_TX_IT HAL_DMAMUX2_REQ_GEN_LPUART1_TX_IT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_RX_IT HAL_DMAMUX2_REQ_GEN_LPUART1_RX_IT +#define HAL_DMAMUX2_REQUEST_GEN_ADC3_IT HAL_DMAMUX2_REQ_GEN_ADC3_IT +#define HAL_DMAMUX2_REQUEST_GEN_ADC3_AWD1_OUT HAL_DMAMUX2_REQ_GEN_ADC3_AWD1_OUT +#define HAL_DMAMUX2_REQUEST_GEN_BDMA_CH0_IT HAL_DMAMUX2_REQ_GEN_BDMA_CH0_IT +#define HAL_DMAMUX2_REQUEST_GEN_BDMA_CH1_IT HAL_DMAMUX2_REQ_GEN_BDMA_CH1_IT + +#define HAL_DMAMUX_REQUEST_GEN_NO_EVENT HAL_DMAMUX_REQ_GEN_NO_EVENT +#define HAL_DMAMUX_REQUEST_GEN_RISING HAL_DMAMUX_REQ_GEN_RISING +#define HAL_DMAMUX_REQUEST_GEN_FALLING HAL_DMAMUX_REQ_GEN_FALLING +#define HAL_DMAMUX_REQUEST_GEN_RISING_FALLING HAL_DMAMUX_REQ_GEN_RISING_FALLING + +#define DFSDM_FILTER_EXT_TRIG_LPTIM1 DFSDM_FILTER_EXT_TRIG_LPTIM1_OUT +#define DFSDM_FILTER_EXT_TRIG_LPTIM2 DFSDM_FILTER_EXT_TRIG_LPTIM2_OUT +#define DFSDM_FILTER_EXT_TRIG_LPTIM3 DFSDM_FILTER_EXT_TRIG_LPTIM3_OUT + +#define DAC_TRIGGER_LP1_OUT DAC_TRIGGER_LPTIM1_OUT +#define DAC_TRIGGER_LP2_OUT DAC_TRIGGER_LPTIM2_OUT + +#endif /* STM32H7 */ + +#if defined(STM32U5) +#define GPDMA1_REQUEST_DCMI GPDMA1_REQUEST_DCMI_PSSI +#endif /* STM32U5 */ + /** + * @} + */ + + /** @defgroup HAL_FLASH_Aliased_Defines HAL FLASH Aliased Defines maintained for + * legacy purpose + * @{ + */ + +#define TYPEPROGRAM_BYTE FLASH_TYPEPROGRAM_BYTE +#define TYPEPROGRAM_HALFWORD FLASH_TYPEPROGRAM_HALFWORD +#define TYPEPROGRAM_WORD FLASH_TYPEPROGRAM_WORD +#define TYPEPROGRAM_DOUBLEWORD FLASH_TYPEPROGRAM_DOUBLEWORD +#define TYPEERASE_SECTORS FLASH_TYPEERASE_SECTORS +#define TYPEERASE_PAGES FLASH_TYPEERASE_PAGES +#define TYPEERASE_PAGEERASE FLASH_TYPEERASE_PAGES +#define TYPEERASE_MASSERASE FLASH_TYPEERASE_MASSERASE +#define WRPSTATE_DISABLE OB_WRPSTATE_DISABLE +#define WRPSTATE_ENABLE OB_WRPSTATE_ENABLE +#define HAL_FLASH_TIMEOUT_VALUE FLASH_TIMEOUT_VALUE +#define OBEX_PCROP OPTIONBYTE_PCROP +#define OBEX_BOOTCONFIG OPTIONBYTE_BOOTCONFIG +#define PCROPSTATE_DISABLE OB_PCROP_STATE_DISABLE +#define PCROPSTATE_ENABLE OB_PCROP_STATE_ENABLE +#define TYPEERASEDATA_BYTE FLASH_TYPEERASEDATA_BYTE +#define TYPEERASEDATA_HALFWORD FLASH_TYPEERASEDATA_HALFWORD +#define TYPEERASEDATA_WORD FLASH_TYPEERASEDATA_WORD +#define TYPEPROGRAMDATA_BYTE FLASH_TYPEPROGRAMDATA_BYTE +#define TYPEPROGRAMDATA_HALFWORD FLASH_TYPEPROGRAMDATA_HALFWORD +#define TYPEPROGRAMDATA_WORD FLASH_TYPEPROGRAMDATA_WORD +#define TYPEPROGRAMDATA_FASTBYTE FLASH_TYPEPROGRAMDATA_FASTBYTE +#define TYPEPROGRAMDATA_FASTHALFWORD FLASH_TYPEPROGRAMDATA_FASTHALFWORD +#define TYPEPROGRAMDATA_FASTWORD FLASH_TYPEPROGRAMDATA_FASTWORD +#define PAGESIZE FLASH_PAGE_SIZE +#define TYPEPROGRAM_FASTBYTE FLASH_TYPEPROGRAM_BYTE +#define TYPEPROGRAM_FASTHALFWORD FLASH_TYPEPROGRAM_HALFWORD +#define TYPEPROGRAM_FASTWORD FLASH_TYPEPROGRAM_WORD +#define VOLTAGE_RANGE_1 FLASH_VOLTAGE_RANGE_1 +#define VOLTAGE_RANGE_2 FLASH_VOLTAGE_RANGE_2 +#define VOLTAGE_RANGE_3 FLASH_VOLTAGE_RANGE_3 +#define VOLTAGE_RANGE_4 FLASH_VOLTAGE_RANGE_4 +#define TYPEPROGRAM_FAST FLASH_TYPEPROGRAM_FAST +#define TYPEPROGRAM_FAST_AND_LAST FLASH_TYPEPROGRAM_FAST_AND_LAST +#define WRPAREA_BANK1_AREAA OB_WRPAREA_BANK1_AREAA +#define WRPAREA_BANK1_AREAB OB_WRPAREA_BANK1_AREAB +#define WRPAREA_BANK2_AREAA OB_WRPAREA_BANK2_AREAA +#define WRPAREA_BANK2_AREAB OB_WRPAREA_BANK2_AREAB +#define IWDG_STDBY_FREEZE OB_IWDG_STDBY_FREEZE +#define IWDG_STDBY_ACTIVE OB_IWDG_STDBY_RUN +#define IWDG_STOP_FREEZE OB_IWDG_STOP_FREEZE +#define IWDG_STOP_ACTIVE OB_IWDG_STOP_RUN +#define FLASH_ERROR_NONE HAL_FLASH_ERROR_NONE +#define FLASH_ERROR_RD HAL_FLASH_ERROR_RD +#define FLASH_ERROR_PG HAL_FLASH_ERROR_PROG +#define FLASH_ERROR_PGP HAL_FLASH_ERROR_PGS +#define FLASH_ERROR_WRP HAL_FLASH_ERROR_WRP +#define FLASH_ERROR_OPTV HAL_FLASH_ERROR_OPTV +#define FLASH_ERROR_OPTVUSR HAL_FLASH_ERROR_OPTVUSR +#define FLASH_ERROR_PROG HAL_FLASH_ERROR_PROG +#define FLASH_ERROR_OP HAL_FLASH_ERROR_OPERATION +#define FLASH_ERROR_PGA HAL_FLASH_ERROR_PGA +#define FLASH_ERROR_SIZE HAL_FLASH_ERROR_SIZE +#define FLASH_ERROR_SIZ HAL_FLASH_ERROR_SIZE +#define FLASH_ERROR_PGS HAL_FLASH_ERROR_PGS +#define FLASH_ERROR_MIS HAL_FLASH_ERROR_MIS +#define FLASH_ERROR_FAST HAL_FLASH_ERROR_FAST +#define FLASH_ERROR_FWWERR HAL_FLASH_ERROR_FWWERR +#define FLASH_ERROR_NOTZERO HAL_FLASH_ERROR_NOTZERO +#define FLASH_ERROR_OPERATION HAL_FLASH_ERROR_OPERATION +#define FLASH_ERROR_ERS HAL_FLASH_ERROR_ERS +#define OB_WDG_SW OB_IWDG_SW +#define OB_WDG_HW OB_IWDG_HW +#define OB_SDADC12_VDD_MONITOR_SET OB_SDACD_VDD_MONITOR_SET +#define OB_SDADC12_VDD_MONITOR_RESET OB_SDACD_VDD_MONITOR_RESET +#define OB_RAM_PARITY_CHECK_SET OB_SRAM_PARITY_SET +#define OB_RAM_PARITY_CHECK_RESET OB_SRAM_PARITY_RESET +#define IS_OB_SDADC12_VDD_MONITOR IS_OB_SDACD_VDD_MONITOR +#define OB_RDP_LEVEL0 OB_RDP_LEVEL_0 +#define OB_RDP_LEVEL1 OB_RDP_LEVEL_1 +#define OB_RDP_LEVEL2 OB_RDP_LEVEL_2 +#if defined(STM32G0) || defined(STM32C0) +#define OB_BOOT_LOCK_DISABLE OB_BOOT_ENTRY_FORCED_NONE +#define OB_BOOT_LOCK_ENABLE OB_BOOT_ENTRY_FORCED_FLASH +#else +#define OB_BOOT_ENTRY_FORCED_NONE OB_BOOT_LOCK_DISABLE +#define OB_BOOT_ENTRY_FORCED_FLASH OB_BOOT_LOCK_ENABLE +#endif +#if defined(STM32H7) +#define FLASH_FLAG_SNECCE_BANK1RR FLASH_FLAG_SNECCERR_BANK1 +#define FLASH_FLAG_DBECCE_BANK1RR FLASH_FLAG_DBECCERR_BANK1 +#define FLASH_FLAG_STRBER_BANK1R FLASH_FLAG_STRBERR_BANK1 +#define FLASH_FLAG_SNECCE_BANK2RR FLASH_FLAG_SNECCERR_BANK2 +#define FLASH_FLAG_DBECCE_BANK2RR FLASH_FLAG_DBECCERR_BANK2 +#define FLASH_FLAG_STRBER_BANK2R FLASH_FLAG_STRBERR_BANK2 +#define FLASH_FLAG_WDW FLASH_FLAG_WBNE +#define OB_WRP_SECTOR_All OB_WRP_SECTOR_ALL +#endif /* STM32H7 */ +#if defined(STM32U5) +#define OB_USER_nRST_STOP OB_USER_NRST_STOP +#define OB_USER_nRST_STDBY OB_USER_NRST_STDBY +#define OB_USER_nRST_SHDW OB_USER_NRST_SHDW +#define OB_USER_nSWBOOT0 OB_USER_NSWBOOT0 +#define OB_USER_nBOOT0 OB_USER_NBOOT0 +#define OB_nBOOT0_RESET OB_NBOOT0_RESET +#define OB_nBOOT0_SET OB_NBOOT0_SET +#define OB_USER_SRAM134_RST OB_USER_SRAM_RST +#define OB_SRAM134_RST_ERASE OB_SRAM_RST_ERASE +#define OB_SRAM134_RST_NOT_ERASE OB_SRAM_RST_NOT_ERASE +#endif /* STM32U5 */ + + /** + * @} + */ + + /** @defgroup HAL_JPEG_Aliased_Macros HAL JPEG Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#if defined(STM32H7) +#define __HAL_RCC_JPEG_CLK_ENABLE __HAL_RCC_JPGDECEN_CLK_ENABLE +#define __HAL_RCC_JPEG_CLK_DISABLE __HAL_RCC_JPGDECEN_CLK_DISABLE +#define __HAL_RCC_JPEG_FORCE_RESET __HAL_RCC_JPGDECRST_FORCE_RESET +#define __HAL_RCC_JPEG_RELEASE_RESET __HAL_RCC_JPGDECRST_RELEASE_RESET +#define __HAL_RCC_JPEG_CLK_SLEEP_ENABLE __HAL_RCC_JPGDEC_CLK_SLEEP_ENABLE +#define __HAL_RCC_JPEG_CLK_SLEEP_DISABLE __HAL_RCC_JPGDEC_CLK_SLEEP_DISABLE +#endif /* STM32H7 */ + + /** + * @} + */ + + /** @defgroup HAL_SYSCFG_Aliased_Defines HAL SYSCFG Aliased Defines maintained for + * legacy purpose + * @{ + */ + +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PA9 I2C_FASTMODEPLUS_PA9 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PA10 I2C_FASTMODEPLUS_PA10 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB6 I2C_FASTMODEPLUS_PB6 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB7 I2C_FASTMODEPLUS_PB7 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB8 I2C_FASTMODEPLUS_PB8 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB9 I2C_FASTMODEPLUS_PB9 +#define HAL_SYSCFG_FASTMODEPLUS_I2C1 I2C_FASTMODEPLUS_I2C1 +#define HAL_SYSCFG_FASTMODEPLUS_I2C2 I2C_FASTMODEPLUS_I2C2 +#define HAL_SYSCFG_FASTMODEPLUS_I2C3 I2C_FASTMODEPLUS_I2C3 +#if defined(STM32G4) + +#define HAL_SYSCFG_EnableIOAnalogSwitchBooster HAL_SYSCFG_EnableIOSwitchBooster +#define HAL_SYSCFG_DisableIOAnalogSwitchBooster HAL_SYSCFG_DisableIOSwitchBooster +#define HAL_SYSCFG_EnableIOAnalogSwitchVDD HAL_SYSCFG_EnableIOSwitchVDD +#define HAL_SYSCFG_DisableIOAnalogSwitchVDD HAL_SYSCFG_DisableIOSwitchVDD +#endif /* STM32G4 */ + +#if defined(STM32H5) +#define SYSCFG_IT_FPU_IOC SBS_IT_FPU_IOC +#define SYSCFG_IT_FPU_DZC SBS_IT_FPU_DZC +#define SYSCFG_IT_FPU_UFC SBS_IT_FPU_UFC +#define SYSCFG_IT_FPU_OFC SBS_IT_FPU_OFC +#define SYSCFG_IT_FPU_IDC SBS_IT_FPU_IDC +#define SYSCFG_IT_FPU_IXC SBS_IT_FPU_IXC + +#define SYSCFG_BREAK_FLASH_ECC SBS_BREAK_FLASH_ECC +#define SYSCFG_BREAK_PVD SBS_BREAK_PVD +#define SYSCFG_BREAK_SRAM_ECC SBS_BREAK_SRAM_ECC +#define SYSCFG_BREAK_LOCKUP SBS_BREAK_LOCKUP + +#define SYSCFG_VREFBUF_VOLTAGE_SCALE0 VREFBUF_VOLTAGE_SCALE0 +#define SYSCFG_VREFBUF_VOLTAGE_SCALE1 VREFBUF_VOLTAGE_SCALE1 +#define SYSCFG_VREFBUF_VOLTAGE_SCALE2 VREFBUF_VOLTAGE_SCALE2 +#define SYSCFG_VREFBUF_VOLTAGE_SCALE3 VREFBUF_VOLTAGE_SCALE3 + +#define SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE VREFBUF_HIGH_IMPEDANCE_DISABLE +#define SYSCFG_VREFBUF_HIGH_IMPEDANCE_ENABLE VREFBUF_HIGH_IMPEDANCE_ENABLE + +#define SYSCFG_FASTMODEPLUS_PB6 SBS_FASTMODEPLUS_PB6 +#define SYSCFG_FASTMODEPLUS_PB7 SBS_FASTMODEPLUS_PB7 +#define SYSCFG_FASTMODEPLUS_PB8 SBS_FASTMODEPLUS_PB8 +#define SYSCFG_FASTMODEPLUS_PB9 SBS_FASTMODEPLUS_PB9 + +#define SYSCFG_ETH_MII SBS_ETH_MII +#define SYSCFG_ETH_RMII SBS_ETH_RMII +#define IS_SYSCFG_ETHERNET_CONFIG IS_SBS_ETHERNET_CONFIG + +#define SYSCFG_MEMORIES_ERASE_FLAG_IPMEE SBS_MEMORIES_ERASE_FLAG_IPMEE +#define SYSCFG_MEMORIES_ERASE_FLAG_MCLR SBS_MEMORIES_ERASE_FLAG_MCLR +#define IS_SYSCFG_MEMORIES_ERASE_FLAG IS_SBS_MEMORIES_ERASE_FLAG + +#define IS_SYSCFG_CODE_CONFIG IS_SBS_CODE_CONFIG + +#define SYSCFG_MPU_NSEC SBS_MPU_NSEC +#define SYSCFG_VTOR_NSEC SBS_VTOR_NSEC +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define SYSCFG_SAU SBS_SAU +#define SYSCFG_MPU_SEC SBS_MPU_SEC +#define SYSCFG_VTOR_AIRCR_SEC SBS_VTOR_AIRCR_SEC +#define SYSCFG_LOCK_ALL SBS_LOCK_ALL +#else +#define SYSCFG_LOCK_ALL SBS_LOCK_ALL +#endif /* __ARM_FEATURE_CMSE */ + +#define SYSCFG_CLK SBS_CLK +#define SYSCFG_CLASSB SBS_CLASSB +#define SYSCFG_FPU SBS_FPU +#define SYSCFG_ALL SBS_ALL + +#define SYSCFG_SEC SBS_SEC +#define SYSCFG_NSEC SBS_NSEC + +#define __HAL_SYSCFG_FPU_INTERRUPT_ENABLE __HAL_SBS_FPU_INTERRUPT_ENABLE +#define __HAL_SYSCFG_FPU_INTERRUPT_DISABLE __HAL_SBS_FPU_INTERRUPT_DISABLE + +#define __HAL_SYSCFG_BREAK_ECC_LOCK __HAL_SBS_BREAK_ECC_LOCK +#define __HAL_SYSCFG_BREAK_LOCKUP_LOCK __HAL_SBS_BREAK_LOCKUP_LOCK +#define __HAL_SYSCFG_BREAK_PVD_LOCK __HAL_SBS_BREAK_PVD_LOCK +#define __HAL_SYSCFG_BREAK_SRAM_ECC_LOCK __HAL_SBS_BREAK_SRAM_ECC_LOCK + +#define __HAL_SYSCFG_FASTMODEPLUS_ENABLE __HAL_SBS_FASTMODEPLUS_ENABLE +#define __HAL_SYSCFG_FASTMODEPLUS_DISABLE __HAL_SBS_FASTMODEPLUS_DISABLE + +#define __HAL_SYSCFG_GET_MEMORIES_ERASE_STATUS __HAL_SBS_GET_MEMORIES_ERASE_STATUS +#define __HAL_SYSCFG_CLEAR_MEMORIES_ERASE_STATUS __HAL_SBS_CLEAR_MEMORIES_ERASE_STATUS + +#define IS_SYSCFG_FPU_INTERRUPT IS_SBS_FPU_INTERRUPT +#define IS_SYSCFG_BREAK_CONFIG IS_SBS_BREAK_CONFIG +#define IS_SYSCFG_VREFBUF_VOLTAGE_SCALE IS_VREFBUF_VOLTAGE_SCALE +#define IS_SYSCFG_VREFBUF_HIGH_IMPEDANCE IS_VREFBUF_HIGH_IMPEDANCE +#define IS_SYSCFG_VREFBUF_TRIMMING IS_VREFBUF_TRIMMING +#define IS_SYSCFG_FASTMODEPLUS IS_SBS_FASTMODEPLUS +#define IS_SYSCFG_ITEMS_ATTRIBUTES IS_SBS_ITEMS_ATTRIBUTES +#define IS_SYSCFG_ATTRIBUTES IS_SBS_ATTRIBUTES +#define IS_SYSCFG_LOCK_ITEMS IS_SBS_LOCK_ITEMS + +#define HAL_SYSCFG_VREFBUF_VoltageScalingConfig HAL_VREFBUF_VoltageScalingConfig +#define HAL_SYSCFG_VREFBUF_HighImpedanceConfig HAL_VREFBUF_HighImpedanceConfig +#define HAL_SYSCFG_VREFBUF_TrimmingConfig HAL_VREFBUF_TrimmingConfig +#define HAL_SYSCFG_EnableVREFBUF HAL_EnableVREFBUF +#define HAL_SYSCFG_DisableVREFBUF HAL_DisableVREFBUF + +#define HAL_SYSCFG_EnableIOAnalogSwitchBooster HAL_SBS_EnableIOAnalogSwitchBooster +#define HAL_SYSCFG_DisableIOAnalogSwitchBooster HAL_SBS_DisableIOAnalogSwitchBooster +#define HAL_SYSCFG_ETHInterfaceSelect HAL_SBS_ETHInterfaceSelect + +#define HAL_SYSCFG_Lock HAL_SBS_Lock +#define HAL_SYSCFG_GetLock HAL_SBS_GetLock + +#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define HAL_SYSCFG_ConfigAttributes HAL_SBS_ConfigAttributes +#define HAL_SYSCFG_GetConfigAttributes HAL_SBS_GetConfigAttributes +#endif /* __ARM_FEATURE_CMSE */ + +#endif /* STM32H5 */ + + +/** + * @} + */ + + +/** @defgroup LL_FMC_Aliased_Defines LL FMC Aliased Defines maintained for compatibility + * purpose + * @{ + */ +#if defined(STM32L4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4) +#define FMC_NAND_PCC_WAIT_FEATURE_DISABLE FMC_NAND_WAIT_FEATURE_DISABLE +#define FMC_NAND_PCC_WAIT_FEATURE_ENABLE FMC_NAND_WAIT_FEATURE_ENABLE +#define FMC_NAND_PCC_MEM_BUS_WIDTH_8 FMC_NAND_MEM_BUS_WIDTH_8 +#define FMC_NAND_PCC_MEM_BUS_WIDTH_16 FMC_NAND_MEM_BUS_WIDTH_16 +#elif defined(STM32F1) || defined(STM32F2) || defined(STM32F3) || defined(STM32F4) +#define FMC_NAND_WAIT_FEATURE_DISABLE FMC_NAND_PCC_WAIT_FEATURE_DISABLE +#define FMC_NAND_WAIT_FEATURE_ENABLE FMC_NAND_PCC_WAIT_FEATURE_ENABLE +#define FMC_NAND_MEM_BUS_WIDTH_8 FMC_NAND_PCC_MEM_BUS_WIDTH_8 +#define FMC_NAND_MEM_BUS_WIDTH_16 FMC_NAND_PCC_MEM_BUS_WIDTH_16 +#endif + /** + * @} + */ + + /** @defgroup LL_FSMC_Aliased_Defines LL FSMC Aliased Defines maintained for legacy + * purpose + * @{ + */ + +#define FSMC_NORSRAM_TYPEDEF FSMC_NORSRAM_TypeDef +#define FSMC_NORSRAM_EXTENDED_TYPEDEF FSMC_NORSRAM_EXTENDED_TypeDef +/** + * @} + */ + +/** @defgroup HAL_GPIO_Aliased_Macros HAL GPIO Aliased Macros maintained for legacy + * purpose + * @{ + */ +#define GET_GPIO_SOURCE GPIO_GET_INDEX +#define GET_GPIO_INDEX GPIO_GET_INDEX + +#if defined(STM32F4) +#define GPIO_AF12_SDMMC GPIO_AF12_SDIO +#define GPIO_AF12_SDMMC1 GPIO_AF12_SDIO +#endif + +#if defined(STM32F7) +#define GPIO_AF12_SDIO GPIO_AF12_SDMMC1 +#define GPIO_AF12_SDMMC GPIO_AF12_SDMMC1 +#endif + +#if defined(STM32L4) +#define GPIO_AF12_SDIO GPIO_AF12_SDMMC1 +#define GPIO_AF12_SDMMC GPIO_AF12_SDMMC1 +#endif + +#if defined(STM32H7) +#define GPIO_AF7_SDIO1 GPIO_AF7_SDMMC1 +#define GPIO_AF8_SDIO1 GPIO_AF8_SDMMC1 +#define GPIO_AF12_SDIO1 GPIO_AF12_SDMMC1 +#define GPIO_AF9_SDIO2 GPIO_AF9_SDMMC2 +#define GPIO_AF10_SDIO2 GPIO_AF10_SDMMC2 +#define GPIO_AF11_SDIO2 GPIO_AF11_SDMMC2 + +#if defined(STM32H743xx) || defined(STM32H753xx) || defined(STM32H750xx) || \ + defined(STM32H742xx) || defined(STM32H745xx) || defined(STM32H755xx) || \ + defined(STM32H747xx) || defined(STM32H757xx) +#define GPIO_AF10_OTG2_HS GPIO_AF10_OTG2_FS +#define GPIO_AF10_OTG1_FS GPIO_AF10_OTG1_HS +#define GPIO_AF12_OTG2_FS GPIO_AF12_OTG1_FS +#endif /*STM32H743xx || STM32H753xx || STM32H750xx || STM32H742xx || STM32H745xx || \ + STM32H755xx || STM32H747xx || STM32H757xx */ +#endif /* STM32H7 */ + +#define GPIO_AF0_LPTIM GPIO_AF0_LPTIM1 +#define GPIO_AF1_LPTIM GPIO_AF1_LPTIM1 +#define GPIO_AF2_LPTIM GPIO_AF2_LPTIM1 + +#if defined(STM32L0) || defined(STM32L4) || defined(STM32F4) || defined(STM32F2) || \ + defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || \ + defined(STM32U5) +#define GPIO_SPEED_LOW GPIO_SPEED_FREQ_LOW +#define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_MEDIUM +#define GPIO_SPEED_FAST GPIO_SPEED_FREQ_HIGH +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_VERY_HIGH +#endif /* STM32L0 || STM32L4 || STM32F4 || STM32F2 || STM32F7 || STM32G4 || STM32H7 || \ + STM32WB || STM32U5*/ + +#if defined(STM32L1) +#define GPIO_SPEED_VERY_LOW GPIO_SPEED_FREQ_LOW +#define GPIO_SPEED_LOW GPIO_SPEED_FREQ_MEDIUM +#define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_HIGH +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_VERY_HIGH +#endif /* STM32L1 */ + +#if defined(STM32F0) || defined(STM32F3) || defined(STM32F1) +#define GPIO_SPEED_LOW GPIO_SPEED_FREQ_LOW +#define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_MEDIUM +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_HIGH +#endif /* STM32F0 || STM32F3 || STM32F1 */ + +#define GPIO_AF6_DFSDM GPIO_AF6_DFSDM1 + +#if defined(STM32U5) || defined(STM32H5) +#define GPIO_AF0_RTC_50Hz GPIO_AF0_RTC_50HZ +#endif /* STM32U5 || STM32H5 */ +#if defined(STM32U5) +#define GPIO_AF0_S2DSTOP GPIO_AF0_SRDSTOP +#define GPIO_AF11_LPGPIO GPIO_AF11_LPGPIO1 +#endif /* STM32U5 */ +/** + * @} + */ + +/** @defgroup HAL_GTZC_Aliased_Defines HAL GTZC Aliased Defines maintained for legacy + * purpose + * @{ + */ +#if defined(STM32U5) +#define GTZC_PERIPH_DCMI GTZC_PERIPH_DCMI_PSSI +#define GTZC_PERIPH_LTDC GTZC_PERIPH_LTDCUSB +#endif /* STM32U5 */ +#if defined(STM32H5) +#define GTZC_PERIPH_DAC12 GTZC_PERIPH_DAC1 +#define GTZC_PERIPH_ADC12 GTZC_PERIPH_ADC +#define GTZC_PERIPH_USBFS GTZC_PERIPH_USB +#endif /* STM32H5 */ +#if defined(STM32H5) || defined(STM32U5) +#define GTZC_MCPBB_NB_VCTR_REG_MAX GTZC_MPCBB_NB_VCTR_REG_MAX +#define GTZC_MCPBB_NB_LCK_VCTR_REG_MAX GTZC_MPCBB_NB_LCK_VCTR_REG_MAX +#define GTZC_MCPBB_SUPERBLOCK_UNLOCKED GTZC_MPCBB_SUPERBLOCK_UNLOCKED +#define GTZC_MCPBB_SUPERBLOCK_LOCKED GTZC_MPCBB_SUPERBLOCK_LOCKED +#define GTZC_MCPBB_BLOCK_NSEC GTZC_MPCBB_BLOCK_NSEC +#define GTZC_MCPBB_BLOCK_SEC GTZC_MPCBB_BLOCK_SEC +#define GTZC_MCPBB_BLOCK_NPRIV GTZC_MPCBB_BLOCK_NPRIV +#define GTZC_MCPBB_BLOCK_PRIV GTZC_MPCBB_BLOCK_PRIV +#define GTZC_MCPBB_LOCK_OFF GTZC_MPCBB_LOCK_OFF +#define GTZC_MCPBB_LOCK_ON GTZC_MPCBB_LOCK_ON +#endif /* STM32H5 || STM32U5 */ +/** + * @} + */ + +/** @defgroup HAL_HRTIM_Aliased_Macros HAL HRTIM Aliased Macros maintained for legacy + * purpose + * @{ + */ +#define HRTIM_TIMDELAYEDPROTECTION_DISABLED HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT1_EEV68 \ + HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT1_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT2_EEV68 \ + HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT2_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDBOTH_EEV68 \ + HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDBOTH_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_BALANCED_EEV68 \ + HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_BALANCED_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT1_DEEV79 \ + HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT1_DEEV7 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT2_DEEV79 \ + HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT2_DEEV7 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDBOTH_EEV79 \ + HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDBOTH_EEV7 +#define HRTIM_TIMDELAYEDPROTECTION_BALANCED_EEV79 \ + HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_BALANCED_EEV7 + +#define __HAL_HRTIM_SetCounter __HAL_HRTIM_SETCOUNTER +#define __HAL_HRTIM_GetCounter __HAL_HRTIM_GETCOUNTER +#define __HAL_HRTIM_SetPeriod __HAL_HRTIM_SETPERIOD +#define __HAL_HRTIM_GetPeriod __HAL_HRTIM_GETPERIOD +#define __HAL_HRTIM_SetClockPrescaler __HAL_HRTIM_SETCLOCKPRESCALER +#define __HAL_HRTIM_GetClockPrescaler __HAL_HRTIM_GETCLOCKPRESCALER +#define __HAL_HRTIM_SetCompare __HAL_HRTIM_SETCOMPARE +#define __HAL_HRTIM_GetCompare __HAL_HRTIM_GETCOMPARE + +#if defined(STM32G4) +#define HAL_HRTIM_ExternalEventCounterConfig HAL_HRTIM_ExtEventCounterConfig +#define HAL_HRTIM_ExternalEventCounterEnable HAL_HRTIM_ExtEventCounterEnable +#define HAL_HRTIM_ExternalEventCounterDisable HAL_HRTIM_ExtEventCounterDisable +#define HAL_HRTIM_ExternalEventCounterReset HAL_HRTIM_ExtEventCounterReset +#define HRTIM_TIMEEVENT_A HRTIM_EVENTCOUNTER_A +#define HRTIM_TIMEEVENT_B HRTIM_EVENTCOUNTER_B +#define HRTIM_TIMEEVENTRESETMODE_UNCONDITIONAL HRTIM_EVENTCOUNTER_RSTMODE_UNCONDITIONAL +#define HRTIM_TIMEEVENTRESETMODE_CONDITIONAL HRTIM_EVENTCOUNTER_RSTMODE_CONDITIONAL +#endif /* STM32G4 */ + +#if defined(STM32H7) +#define HRTIM_OUTPUTSET_TIMAEV1_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMAEV2_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMAEV3_TIMCCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMAEV4_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMAEV5_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMAEV6_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMAEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMAEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMAEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMBEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMBEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMBEV3_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMBEV4_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMBEV5_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMBEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMBEV7_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMBEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMBEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMCEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMCEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMCEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMCEV4_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMCEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMCEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMCEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMCEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMCEV9_TIMFCMP2 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMDEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMDEV2_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMDEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMDEV4_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMDEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMDEV6_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMDEV7_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMDEV8_TIMFCMP1 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMDEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMEEV1_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMEEV2_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMEEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMEEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMEEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMEEV6_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMEEV7_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMEEV8_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMEEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMFEV1_TIMACMP3 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMFEV2_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMFEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMFEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMFEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMFEV6_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMFEV7_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMFEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMFEV9_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_9 + +#define HRTIM_OUTPUTRESET_TIMAEV1_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMAEV2_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMAEV3_TIMCCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMAEV4_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMAEV5_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMAEV6_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMAEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMAEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMAEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMBEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMBEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMBEV3_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMBEV4_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMBEV5_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMBEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMBEV7_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMBEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMBEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMCEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMCEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMCEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMCEV4_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMCEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMCEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMCEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMCEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMCEV9_TIMFCMP2 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMDEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMDEV2_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMDEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMDEV4_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMDEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMDEV6_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMDEV7_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMDEV8_TIMFCMP1 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMDEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMEEV1_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMEEV2_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMEEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMEEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMEEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMEEV6_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMEEV7_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMEEV8_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMEEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMFEV1_TIMACMP3 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMFEV2_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMFEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMFEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMFEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMFEV6_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMFEV7_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMFEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMFEV9_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_9 +#endif /* STM32H7 */ + +#if defined(STM32F3) +/** @brief Constants defining available sources associated to external events. + */ +#define HRTIM_EVENTSRC_1 (0x00000000U) +#define HRTIM_EVENTSRC_2 (HRTIM_EECR1_EE1SRC_0) +#define HRTIM_EVENTSRC_3 (HRTIM_EECR1_EE1SRC_1) +#define HRTIM_EVENTSRC_4 (HRTIM_EECR1_EE1SRC_1 | HRTIM_EECR1_EE1SRC_0) + +/** @brief Constants defining the DLL calibration periods (in micro seconds) + */ +#define HRTIM_CALIBRATIONRATE_7300 0x00000000U +#define HRTIM_CALIBRATIONRATE_910 (HRTIM_DLLCR_CALRTE_0) +#define HRTIM_CALIBRATIONRATE_114 (HRTIM_DLLCR_CALRTE_1) +#define HRTIM_CALIBRATIONRATE_14 (HRTIM_DLLCR_CALRTE_1 | HRTIM_DLLCR_CALRTE_0) + +#endif /* STM32F3 */ +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Defines HAL I2C Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define I2C_DUALADDRESS_DISABLED I2C_DUALADDRESS_DISABLE +#define I2C_DUALADDRESS_ENABLED I2C_DUALADDRESS_ENABLE +#define I2C_GENERALCALL_DISABLED I2C_GENERALCALL_DISABLE +#define I2C_GENERALCALL_ENABLED I2C_GENERALCALL_ENABLE +#define I2C_NOSTRETCH_DISABLED I2C_NOSTRETCH_DISABLE +#define I2C_NOSTRETCH_ENABLED I2C_NOSTRETCH_ENABLE +#define I2C_ANALOGFILTER_ENABLED I2C_ANALOGFILTER_ENABLE +#define I2C_ANALOGFILTER_DISABLED I2C_ANALOGFILTER_DISABLE +#if defined(STM32F0) || defined(STM32F1) || defined(STM32F3) || defined(STM32G0) || \ + defined(STM32L4) || defined(STM32L1) || defined(STM32F7) +#define HAL_I2C_STATE_MEM_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_MEM_BUSY_RX HAL_I2C_STATE_BUSY_RX +#define HAL_I2C_STATE_MASTER_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_MASTER_BUSY_RX HAL_I2C_STATE_BUSY_RX +#define HAL_I2C_STATE_SLAVE_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_SLAVE_BUSY_RX HAL_I2C_STATE_BUSY_RX +#endif +/** + * @} + */ + +/** @defgroup HAL_IRDA_Aliased_Defines HAL IRDA Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define IRDA_ONE_BIT_SAMPLE_DISABLED IRDA_ONE_BIT_SAMPLE_DISABLE +#define IRDA_ONE_BIT_SAMPLE_ENABLED IRDA_ONE_BIT_SAMPLE_ENABLE + +/** + * @} + */ + +/** @defgroup HAL_IWDG_Aliased_Defines HAL IWDG Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define KR_KEY_RELOAD IWDG_KEY_RELOAD +#define KR_KEY_ENABLE IWDG_KEY_ENABLE +#define KR_KEY_EWA IWDG_KEY_WRITE_ACCESS_ENABLE +#define KR_KEY_DWA IWDG_KEY_WRITE_ACCESS_DISABLE + /** + * @} + */ + + /** @defgroup HAL_LPTIM_Aliased_Defines HAL LPTIM Aliased Defines maintained for + * legacy purpose + * @{ + */ + +#define LPTIM_CLOCKSAMPLETIME_DIRECTTRANSISTION LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION +#define LPTIM_CLOCKSAMPLETIME_2TRANSISTIONS LPTIM_CLOCKSAMPLETIME_2TRANSITIONS +#define LPTIM_CLOCKSAMPLETIME_4TRANSISTIONS LPTIM_CLOCKSAMPLETIME_4TRANSITIONS +#define LPTIM_CLOCKSAMPLETIME_8TRANSISTIONS LPTIM_CLOCKSAMPLETIME_8TRANSITIONS + +#define LPTIM_CLOCKPOLARITY_RISINGEDGE LPTIM_CLOCKPOLARITY_RISING +#define LPTIM_CLOCKPOLARITY_FALLINGEDGE LPTIM_CLOCKPOLARITY_FALLING +#define LPTIM_CLOCKPOLARITY_BOTHEDGES LPTIM_CLOCKPOLARITY_RISING_FALLING + +#define LPTIM_TRIGSAMPLETIME_DIRECTTRANSISTION LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION +#define LPTIM_TRIGSAMPLETIME_2TRANSISTIONS LPTIM_TRIGSAMPLETIME_2TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_4TRANSISTIONS LPTIM_TRIGSAMPLETIME_4TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_8TRANSISTIONS LPTIM_TRIGSAMPLETIME_8TRANSITIONS + +/* The following 3 definition have also been present in a temporary version of lptim.h */ +/* They need to be renamed also to the right name, just in case */ +#define LPTIM_TRIGSAMPLETIME_2TRANSITION LPTIM_TRIGSAMPLETIME_2TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_4TRANSITION LPTIM_TRIGSAMPLETIME_4TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_8TRANSITION LPTIM_TRIGSAMPLETIME_8TRANSITIONS + + +/** @defgroup HAL_LPTIM_Aliased_Defines HAL LPTIM Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define HAL_LPTIM_ReadCompare HAL_LPTIM_ReadCapturedValue + /** + * @} + */ + +#if defined(STM32U5) +#define LPTIM_ISR_CC1 LPTIM_ISR_CC1IF +#define LPTIM_ISR_CC2 LPTIM_ISR_CC2IF +#define LPTIM_CHANNEL_ALL 0x00000000U +#endif /* STM32U5 */ +/** + * @} + */ + +/** @defgroup HAL_NAND_Aliased_Defines HAL NAND Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define HAL_NAND_Read_Page HAL_NAND_Read_Page_8b +#define HAL_NAND_Write_Page HAL_NAND_Write_Page_8b +#define HAL_NAND_Read_SpareArea HAL_NAND_Read_SpareArea_8b +#define HAL_NAND_Write_SpareArea HAL_NAND_Write_SpareArea_8b + +#define NAND_AddressTypedef NAND_AddressTypeDef + +#define __ARRAY_ADDRESS ARRAY_ADDRESS +#define __ADDR_1st_CYCLE ADDR_1ST_CYCLE +#define __ADDR_2nd_CYCLE ADDR_2ND_CYCLE +#define __ADDR_3rd_CYCLE ADDR_3RD_CYCLE +#define __ADDR_4th_CYCLE ADDR_4TH_CYCLE +/** + * @} + */ + +/** @defgroup HAL_NOR_Aliased_Defines HAL NOR Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define NOR_StatusTypedef HAL_NOR_StatusTypeDef +#define NOR_SUCCESS HAL_NOR_STATUS_SUCCESS +#define NOR_ONGOING HAL_NOR_STATUS_ONGOING +#define NOR_ERROR HAL_NOR_STATUS_ERROR +#define NOR_TIMEOUT HAL_NOR_STATUS_TIMEOUT + +#define __NOR_WRITE NOR_WRITE +#define __NOR_ADDR_SHIFT NOR_ADDR_SHIFT + /** + * @} + */ + + /** @defgroup HAL_OPAMP_Aliased_Defines HAL OPAMP Aliased Defines maintained for + * legacy purpose + * @{ + */ + +#define OPAMP_NONINVERTINGINPUT_VP0 OPAMP_NONINVERTINGINPUT_IO0 +#define OPAMP_NONINVERTINGINPUT_VP1 OPAMP_NONINVERTINGINPUT_IO1 +#define OPAMP_NONINVERTINGINPUT_VP2 OPAMP_NONINVERTINGINPUT_IO2 +#define OPAMP_NONINVERTINGINPUT_VP3 OPAMP_NONINVERTINGINPUT_IO3 + +#define OPAMP_SEC_NONINVERTINGINPUT_VP0 OPAMP_SEC_NONINVERTINGINPUT_IO0 +#define OPAMP_SEC_NONINVERTINGINPUT_VP1 OPAMP_SEC_NONINVERTINGINPUT_IO1 +#define OPAMP_SEC_NONINVERTINGINPUT_VP2 OPAMP_SEC_NONINVERTINGINPUT_IO2 +#define OPAMP_SEC_NONINVERTINGINPUT_VP3 OPAMP_SEC_NONINVERTINGINPUT_IO3 + +#define OPAMP_INVERTINGINPUT_VM0 OPAMP_INVERTINGINPUT_IO0 +#define OPAMP_INVERTINGINPUT_VM1 OPAMP_INVERTINGINPUT_IO1 + +#define IOPAMP_INVERTINGINPUT_VM0 OPAMP_INVERTINGINPUT_IO0 +#define IOPAMP_INVERTINGINPUT_VM1 OPAMP_INVERTINGINPUT_IO1 + +#define OPAMP_SEC_INVERTINGINPUT_VM0 OPAMP_SEC_INVERTINGINPUT_IO0 +#define OPAMP_SEC_INVERTINGINPUT_VM1 OPAMP_SEC_INVERTINGINPUT_IO1 + +#define OPAMP_INVERTINGINPUT_VINM OPAMP_SEC_INVERTINGINPUT_IO1 + +#define OPAMP_PGACONNECT_NO OPAMP_PGA_CONNECT_INVERTINGINPUT_NO +#define OPAMP_PGACONNECT_VM0 OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0 +#define OPAMP_PGACONNECT_VM1 OPAMP_PGA_CONNECT_INVERTINGINPUT_IO1 + +#if defined(STM32L1) || defined(STM32L4) || defined(STM32L5) || defined(STM32H7) || \ + defined(STM32G4) || defined(STM32U5) +#define HAL_OPAMP_MSP_INIT_CB_ID HAL_OPAMP_MSPINIT_CB_ID +#define HAL_OPAMP_MSP_DEINIT_CB_ID HAL_OPAMP_MSPDEINIT_CB_ID +#endif + +#if defined(STM32L4) || defined(STM32L5) +#define OPAMP_POWERMODE_NORMAL OPAMP_POWERMODE_NORMALPOWER +#elif defined(STM32G4) +#define OPAMP_POWERMODE_NORMAL OPAMP_POWERMODE_NORMALSPEED +#endif + +/** + * @} + */ + +/** @defgroup HAL_I2S_Aliased_Defines HAL I2S Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define I2S_STANDARD_PHILLIPS I2S_STANDARD_PHILIPS + +#if defined(STM32H7) +#define I2S_IT_TXE I2S_IT_TXP +#define I2S_IT_RXNE I2S_IT_RXP + +#define I2S_FLAG_TXE I2S_FLAG_TXP +#define I2S_FLAG_RXNE I2S_FLAG_RXP +#endif + +#if defined(STM32F7) +#define I2S_CLOCK_SYSCLK I2S_CLOCK_PLL +#endif +/** + * @} + */ + +/** @defgroup HAL_PCCARD_Aliased_Defines HAL PCCARD Aliased Defines maintained for legacy + * purpose + * @{ + */ + +/* Compact Flash-ATA registers description */ +#define CF_DATA ATA_DATA +#define CF_SECTOR_COUNT ATA_SECTOR_COUNT +#define CF_SECTOR_NUMBER ATA_SECTOR_NUMBER +#define CF_CYLINDER_LOW ATA_CYLINDER_LOW +#define CF_CYLINDER_HIGH ATA_CYLINDER_HIGH +#define CF_CARD_HEAD ATA_CARD_HEAD +#define CF_STATUS_CMD ATA_STATUS_CMD +#define CF_STATUS_CMD_ALTERNATE ATA_STATUS_CMD_ALTERNATE +#define CF_COMMON_DATA_AREA ATA_COMMON_DATA_AREA + +/* Compact Flash-ATA commands */ +#define CF_READ_SECTOR_CMD ATA_READ_SECTOR_CMD +#define CF_WRITE_SECTOR_CMD ATA_WRITE_SECTOR_CMD +#define CF_ERASE_SECTOR_CMD ATA_ERASE_SECTOR_CMD +#define CF_IDENTIFY_CMD ATA_IDENTIFY_CMD + +#define PCCARD_StatusTypedef HAL_PCCARD_StatusTypeDef +#define PCCARD_SUCCESS HAL_PCCARD_STATUS_SUCCESS +#define PCCARD_ONGOING HAL_PCCARD_STATUS_ONGOING +#define PCCARD_ERROR HAL_PCCARD_STATUS_ERROR +#define PCCARD_TIMEOUT HAL_PCCARD_STATUS_TIMEOUT + /** + * @} + */ + + /** @defgroup HAL_RTC_Aliased_Defines HAL RTC Aliased Defines maintained for legacy + * purpose + * @{ + */ + +#define FORMAT_BIN RTC_FORMAT_BIN +#define FORMAT_BCD RTC_FORMAT_BCD + +#define RTC_ALARMSUBSECONDMASK_None RTC_ALARMSUBSECONDMASK_NONE +#define RTC_TAMPERERASEBACKUP_DISABLED RTC_TAMPER_ERASE_BACKUP_DISABLE +#define RTC_TAMPERMASK_FLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_TAMPERMASK_FLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE + +#define RTC_MASKTAMPERFLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_MASKTAMPERFLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE +#define RTC_TAMPERERASEBACKUP_ENABLED RTC_TAMPER_ERASE_BACKUP_ENABLE +#define RTC_TAMPER1_2_INTERRUPT RTC_ALL_TAMPER_INTERRUPT +#define RTC_TAMPER1_2_3_INTERRUPT RTC_ALL_TAMPER_INTERRUPT + +#define RTC_TIMESTAMPPIN_PC13 RTC_TIMESTAMPPIN_DEFAULT +#define RTC_TIMESTAMPPIN_PA0 RTC_TIMESTAMPPIN_POS1 +#define RTC_TIMESTAMPPIN_PI8 RTC_TIMESTAMPPIN_POS1 +#define RTC_TIMESTAMPPIN_PC1 RTC_TIMESTAMPPIN_POS2 + +#define RTC_OUTPUT_REMAP_PC13 RTC_OUTPUT_REMAP_NONE +#define RTC_OUTPUT_REMAP_PB14 RTC_OUTPUT_REMAP_POS1 +#define RTC_OUTPUT_REMAP_PB2 RTC_OUTPUT_REMAP_POS1 + +#define RTC_TAMPERPIN_PC13 RTC_TAMPERPIN_DEFAULT +#define RTC_TAMPERPIN_PA0 RTC_TAMPERPIN_POS1 +#define RTC_TAMPERPIN_PI8 RTC_TAMPERPIN_POS1 + +#if defined(STM32H5) +#define TAMP_SECRETDEVICE_ERASE_NONE TAMP_DEVICESECRETS_ERASE_NONE +#define TAMP_SECRETDEVICE_ERASE_BKP_SRAM TAMP_DEVICESECRETS_ERASE_BKPSRAM +#endif /* STM32H5 */ + +#if defined(STM32WBA) +#define TAMP_SECRETDEVICE_ERASE_NONE TAMP_DEVICESECRETS_ERASE_NONE +#define TAMP_SECRETDEVICE_ERASE_SRAM2 TAMP_DEVICESECRETS_ERASE_SRAM2 +#define TAMP_SECRETDEVICE_ERASE_RHUK TAMP_DEVICESECRETS_ERASE_RHUK +#define TAMP_SECRETDEVICE_ERASE_ICACHE TAMP_DEVICESECRETS_ERASE_ICACHE +#define TAMP_SECRETDEVICE_ERASE_SAES_AES_HASH TAMP_DEVICESECRETS_ERASE_SAES_AES_HASH +#define TAMP_SECRETDEVICE_ERASE_PKA_SRAM TAMP_DEVICESECRETS_ERASE_PKA_SRAM +#define TAMP_SECRETDEVICE_ERASE_ALL TAMP_DEVICESECRETS_ERASE_ALL +#endif /* STM32WBA */ + +#if defined(STM32H5) || defined(STM32WBA) +#define TAMP_SECRETDEVICE_ERASE_DISABLE TAMP_DEVICESECRETS_ERASE_NONE +#define TAMP_SECRETDEVICE_ERASE_ENABLE TAMP_SECRETDEVICE_ERASE_ALL +#endif /* STM32H5 || STM32WBA */ + +#if defined(STM32F7) +#define RTC_TAMPCR_TAMPXE RTC_TAMPER_ENABLE_BITS_MASK +#define RTC_TAMPCR_TAMPXIE RTC_TAMPER_IT_ENABLE_BITS_MASK +#endif /* STM32F7 */ + +#if defined(STM32H7) +#define RTC_TAMPCR_TAMPXE RTC_TAMPER_X +#define RTC_TAMPCR_TAMPXIE RTC_TAMPER_X_INTERRUPT +#endif /* STM32H7 */ + +#if defined(STM32F7) || defined(STM32H7) || defined(STM32L0) +#define RTC_TAMPER1_INTERRUPT RTC_IT_TAMP1 +#define RTC_TAMPER2_INTERRUPT RTC_IT_TAMP2 +#define RTC_TAMPER3_INTERRUPT RTC_IT_TAMP3 +#define RTC_ALL_TAMPER_INTERRUPT RTC_IT_TAMP +#endif /* STM32F7 || STM32H7 || STM32L0 */ + +/** + * @} + */ + + +/** @defgroup HAL_SMARTCARD_Aliased_Defines HAL SMARTCARD Aliased Defines maintained for + * legacy purpose + * @{ + */ +#define SMARTCARD_NACK_ENABLED SMARTCARD_NACK_ENABLE +#define SMARTCARD_NACK_DISABLED SMARTCARD_NACK_DISABLE + +#define SMARTCARD_ONEBIT_SAMPLING_DISABLED SMARTCARD_ONE_BIT_SAMPLE_DISABLE +#define SMARTCARD_ONEBIT_SAMPLING_ENABLED SMARTCARD_ONE_BIT_SAMPLE_ENABLE +#define SMARTCARD_ONEBIT_SAMPLING_DISABLE SMARTCARD_ONE_BIT_SAMPLE_DISABLE +#define SMARTCARD_ONEBIT_SAMPLING_ENABLE SMARTCARD_ONE_BIT_SAMPLE_ENABLE + +#define SMARTCARD_TIMEOUT_DISABLED SMARTCARD_TIMEOUT_DISABLE +#define SMARTCARD_TIMEOUT_ENABLED SMARTCARD_TIMEOUT_ENABLE + +#define SMARTCARD_LASTBIT_DISABLED SMARTCARD_LASTBIT_DISABLE +#define SMARTCARD_LASTBIT_ENABLED SMARTCARD_LASTBIT_ENABLE +/** + * @} + */ + + +/** @defgroup HAL_SMBUS_Aliased_Defines HAL SMBUS Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define SMBUS_DUALADDRESS_DISABLED SMBUS_DUALADDRESS_DISABLE +#define SMBUS_DUALADDRESS_ENABLED SMBUS_DUALADDRESS_ENABLE +#define SMBUS_GENERALCALL_DISABLED SMBUS_GENERALCALL_DISABLE +#define SMBUS_GENERALCALL_ENABLED SMBUS_GENERALCALL_ENABLE +#define SMBUS_NOSTRETCH_DISABLED SMBUS_NOSTRETCH_DISABLE +#define SMBUS_NOSTRETCH_ENABLED SMBUS_NOSTRETCH_ENABLE +#define SMBUS_ANALOGFILTER_ENABLED SMBUS_ANALOGFILTER_ENABLE +#define SMBUS_ANALOGFILTER_DISABLED SMBUS_ANALOGFILTER_DISABLE +#define SMBUS_PEC_DISABLED SMBUS_PEC_DISABLE +#define SMBUS_PEC_ENABLED SMBUS_PEC_ENABLE +#define HAL_SMBUS_STATE_SLAVE_LISTEN HAL_SMBUS_STATE_LISTEN +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Defines HAL SPI Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define SPI_TIMODE_DISABLED SPI_TIMODE_DISABLE +#define SPI_TIMODE_ENABLED SPI_TIMODE_ENABLE + +#define SPI_CRCCALCULATION_DISABLED SPI_CRCCALCULATION_DISABLE +#define SPI_CRCCALCULATION_ENABLED SPI_CRCCALCULATION_ENABLE + +#define SPI_NSS_PULSE_DISABLED SPI_NSS_PULSE_DISABLE +#define SPI_NSS_PULSE_ENABLED SPI_NSS_PULSE_ENABLE + +#if defined(STM32H7) + +#define SPI_FLAG_TXE SPI_FLAG_TXP +#define SPI_FLAG_RXNE SPI_FLAG_RXP + +#define SPI_IT_TXE SPI_IT_TXP +#define SPI_IT_RXNE SPI_IT_RXP + +#define SPI_FRLVL_EMPTY SPI_RX_FIFO_0PACKET +#define SPI_FRLVL_QUARTER_FULL SPI_RX_FIFO_1PACKET +#define SPI_FRLVL_HALF_FULL SPI_RX_FIFO_2PACKET +#define SPI_FRLVL_FULL SPI_RX_FIFO_3PACKET + +#endif /* STM32H7 */ + +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Defines HAL TIM Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define CCER_CCxE_MASK TIM_CCER_CCxE_MASK +#define CCER_CCxNE_MASK TIM_CCER_CCxNE_MASK + +#define TIM_DMABase_CR1 TIM_DMABASE_CR1 +#define TIM_DMABase_CR2 TIM_DMABASE_CR2 +#define TIM_DMABase_SMCR TIM_DMABASE_SMCR +#define TIM_DMABase_DIER TIM_DMABASE_DIER +#define TIM_DMABase_SR TIM_DMABASE_SR +#define TIM_DMABase_EGR TIM_DMABASE_EGR +#define TIM_DMABase_CCMR1 TIM_DMABASE_CCMR1 +#define TIM_DMABase_CCMR2 TIM_DMABASE_CCMR2 +#define TIM_DMABase_CCER TIM_DMABASE_CCER +#define TIM_DMABase_CNT TIM_DMABASE_CNT +#define TIM_DMABase_PSC TIM_DMABASE_PSC +#define TIM_DMABase_ARR TIM_DMABASE_ARR +#define TIM_DMABase_RCR TIM_DMABASE_RCR +#define TIM_DMABase_CCR1 TIM_DMABASE_CCR1 +#define TIM_DMABase_CCR2 TIM_DMABASE_CCR2 +#define TIM_DMABase_CCR3 TIM_DMABASE_CCR3 +#define TIM_DMABase_CCR4 TIM_DMABASE_CCR4 +#define TIM_DMABase_BDTR TIM_DMABASE_BDTR +#define TIM_DMABase_DCR TIM_DMABASE_DCR +#define TIM_DMABase_DMAR TIM_DMABASE_DMAR +#define TIM_DMABase_OR1 TIM_DMABASE_OR1 +#define TIM_DMABase_CCMR3 TIM_DMABASE_CCMR3 +#define TIM_DMABase_CCR5 TIM_DMABASE_CCR5 +#define TIM_DMABase_CCR6 TIM_DMABASE_CCR6 +#define TIM_DMABase_OR2 TIM_DMABASE_OR2 +#define TIM_DMABase_OR3 TIM_DMABASE_OR3 +#define TIM_DMABase_OR TIM_DMABASE_OR + +#define TIM_EventSource_Update TIM_EVENTSOURCE_UPDATE +#define TIM_EventSource_CC1 TIM_EVENTSOURCE_CC1 +#define TIM_EventSource_CC2 TIM_EVENTSOURCE_CC2 +#define TIM_EventSource_CC3 TIM_EVENTSOURCE_CC3 +#define TIM_EventSource_CC4 TIM_EVENTSOURCE_CC4 +#define TIM_EventSource_COM TIM_EVENTSOURCE_COM +#define TIM_EventSource_Trigger TIM_EVENTSOURCE_TRIGGER +#define TIM_EventSource_Break TIM_EVENTSOURCE_BREAK +#define TIM_EventSource_Break2 TIM_EVENTSOURCE_BREAK2 + +#define TIM_DMABurstLength_1Transfer TIM_DMABURSTLENGTH_1TRANSFER +#define TIM_DMABurstLength_2Transfers TIM_DMABURSTLENGTH_2TRANSFERS +#define TIM_DMABurstLength_3Transfers TIM_DMABURSTLENGTH_3TRANSFERS +#define TIM_DMABurstLength_4Transfers TIM_DMABURSTLENGTH_4TRANSFERS +#define TIM_DMABurstLength_5Transfers TIM_DMABURSTLENGTH_5TRANSFERS +#define TIM_DMABurstLength_6Transfers TIM_DMABURSTLENGTH_6TRANSFERS +#define TIM_DMABurstLength_7Transfers TIM_DMABURSTLENGTH_7TRANSFERS +#define TIM_DMABurstLength_8Transfers TIM_DMABURSTLENGTH_8TRANSFERS +#define TIM_DMABurstLength_9Transfers TIM_DMABURSTLENGTH_9TRANSFERS +#define TIM_DMABurstLength_10Transfers TIM_DMABURSTLENGTH_10TRANSFERS +#define TIM_DMABurstLength_11Transfers TIM_DMABURSTLENGTH_11TRANSFERS +#define TIM_DMABurstLength_12Transfers TIM_DMABURSTLENGTH_12TRANSFERS +#define TIM_DMABurstLength_13Transfers TIM_DMABURSTLENGTH_13TRANSFERS +#define TIM_DMABurstLength_14Transfers TIM_DMABURSTLENGTH_14TRANSFERS +#define TIM_DMABurstLength_15Transfers TIM_DMABURSTLENGTH_15TRANSFERS +#define TIM_DMABurstLength_16Transfers TIM_DMABURSTLENGTH_16TRANSFERS +#define TIM_DMABurstLength_17Transfers TIM_DMABURSTLENGTH_17TRANSFERS +#define TIM_DMABurstLength_18Transfers TIM_DMABURSTLENGTH_18TRANSFERS + +#if defined(STM32L0) +#define TIM22_TI1_GPIO1 TIM22_TI1_GPIO +#define TIM22_TI1_GPIO2 TIM22_TI1_GPIO +#endif + +#if defined(STM32F3) +#define IS_TIM_HALL_INTERFACE_INSTANCE IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE +#endif + +#if defined(STM32H7) +#define TIM_TIM1_ETR_COMP1_OUT TIM_TIM1_ETR_COMP1 +#define TIM_TIM1_ETR_COMP2_OUT TIM_TIM1_ETR_COMP2 +#define TIM_TIM8_ETR_COMP1_OUT TIM_TIM8_ETR_COMP1 +#define TIM_TIM8_ETR_COMP2_OUT TIM_TIM8_ETR_COMP2 +#define TIM_TIM2_ETR_COMP1_OUT TIM_TIM2_ETR_COMP1 +#define TIM_TIM2_ETR_COMP2_OUT TIM_TIM2_ETR_COMP2 +#define TIM_TIM3_ETR_COMP1_OUT TIM_TIM3_ETR_COMP1 +#define TIM_TIM1_TI1_COMP1_OUT TIM_TIM1_TI1_COMP1 +#define TIM_TIM8_TI1_COMP2_OUT TIM_TIM8_TI1_COMP2 +#define TIM_TIM2_TI4_COMP1_OUT TIM_TIM2_TI4_COMP1 +#define TIM_TIM2_TI4_COMP2_OUT TIM_TIM2_TI4_COMP2 +#define TIM_TIM2_TI4_COMP1COMP2_OUT TIM_TIM2_TI4_COMP1_COMP2 +#define TIM_TIM3_TI1_COMP1_OUT TIM_TIM3_TI1_COMP1 +#define TIM_TIM3_TI1_COMP2_OUT TIM_TIM3_TI1_COMP2 +#define TIM_TIM3_TI1_COMP1COMP2_OUT TIM_TIM3_TI1_COMP1_COMP2 +#endif + +#if defined(STM32U5) +#define OCREF_CLEAR_SELECT_Pos OCREF_CLEAR_SELECT_POS +#define OCREF_CLEAR_SELECT_Msk OCREF_CLEAR_SELECT_MSK +#endif +/** + * @} + */ + +/** @defgroup HAL_TSC_Aliased_Defines HAL TSC Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define TSC_SYNC_POL_FALL TSC_SYNC_POLARITY_FALLING +#define TSC_SYNC_POL_RISE_HIGH TSC_SYNC_POLARITY_RISING +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Defines HAL UART Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define UART_ONEBIT_SAMPLING_DISABLED UART_ONE_BIT_SAMPLE_DISABLE +#define UART_ONEBIT_SAMPLING_ENABLED UART_ONE_BIT_SAMPLE_ENABLE +#define UART_ONE_BIT_SAMPLE_DISABLED UART_ONE_BIT_SAMPLE_DISABLE +#define UART_ONE_BIT_SAMPLE_ENABLED UART_ONE_BIT_SAMPLE_ENABLE + +#define __HAL_UART_ONEBIT_ENABLE __HAL_UART_ONE_BIT_SAMPLE_ENABLE +#define __HAL_UART_ONEBIT_DISABLE __HAL_UART_ONE_BIT_SAMPLE_DISABLE + +#define __DIV_SAMPLING16 UART_DIV_SAMPLING16 +#define __DIVMANT_SAMPLING16 UART_DIVMANT_SAMPLING16 +#define __DIVFRAQ_SAMPLING16 UART_DIVFRAQ_SAMPLING16 +#define __UART_BRR_SAMPLING16 UART_BRR_SAMPLING16 + +#define __DIV_SAMPLING8 UART_DIV_SAMPLING8 +#define __DIVMANT_SAMPLING8 UART_DIVMANT_SAMPLING8 +#define __DIVFRAQ_SAMPLING8 UART_DIVFRAQ_SAMPLING8 +#define __UART_BRR_SAMPLING8 UART_BRR_SAMPLING8 + +#define __DIV_LPUART UART_DIV_LPUART + +#define UART_WAKEUPMETHODE_IDLELINE UART_WAKEUPMETHOD_IDLELINE +#define UART_WAKEUPMETHODE_ADDRESSMARK UART_WAKEUPMETHOD_ADDRESSMARK + + /** + * @} + */ + + + /** @defgroup HAL_USART_Aliased_Defines HAL USART Aliased Defines maintained for + * legacy purpose + * @{ + */ + +#define USART_CLOCK_DISABLED USART_CLOCK_DISABLE +#define USART_CLOCK_ENABLED USART_CLOCK_ENABLE + +#define USARTNACK_ENABLED USART_NACK_ENABLE +#define USARTNACK_DISABLED USART_NACK_DISABLE +/** + * @} + */ + +/** @defgroup HAL_WWDG_Aliased_Defines HAL WWDG Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define CFR_BASE WWDG_CFR_BASE + +/** + * @} + */ + +/** @defgroup HAL_CAN_Aliased_Defines HAL CAN Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define CAN_FilterFIFO0 CAN_FILTER_FIFO0 +#define CAN_FilterFIFO1 CAN_FILTER_FIFO1 +#define CAN_IT_RQCP0 CAN_IT_TME +#define CAN_IT_RQCP1 CAN_IT_TME +#define CAN_IT_RQCP2 CAN_IT_TME +#define INAK_TIMEOUT CAN_TIMEOUT_VALUE +#define SLAK_TIMEOUT CAN_TIMEOUT_VALUE +#define CAN_TXSTATUS_FAILED ((uint8_t)0x00U) +#define CAN_TXSTATUS_OK ((uint8_t)0x01U) +#define CAN_TXSTATUS_PENDING ((uint8_t)0x02U) + + /** + * @} + */ + + /** @defgroup HAL_ETH_Aliased_Defines HAL ETH Aliased Defines maintained for legacy + * purpose + * @{ + */ + +#define VLAN_TAG ETH_VLAN_TAG +#define MIN_ETH_PAYLOAD ETH_MIN_ETH_PAYLOAD +#define MAX_ETH_PAYLOAD ETH_MAX_ETH_PAYLOAD +#define JUMBO_FRAME_PAYLOAD ETH_JUMBO_FRAME_PAYLOAD +#define MACMIIAR_CR_MASK ETH_MACMIIAR_CR_MASK +#define MACCR_CLEAR_MASK ETH_MACCR_CLEAR_MASK +#define MACFCR_CLEAR_MASK ETH_MACFCR_CLEAR_MASK +#define DMAOMR_CLEAR_MASK ETH_DMAOMR_CLEAR_MASK + +#define ETH_MMCCR 0x00000100U +#define ETH_MMCRIR 0x00000104U +#define ETH_MMCTIR 0x00000108U +#define ETH_MMCRIMR 0x0000010CU +#define ETH_MMCTIMR 0x00000110U +#define ETH_MMCTGFSCCR 0x0000014CU +#define ETH_MMCTGFMSCCR 0x00000150U +#define ETH_MMCTGFCR 0x00000168U +#define ETH_MMCRFCECR 0x00000194U +#define ETH_MMCRFAECR 0x00000198U +#define ETH_MMCRGUFCR 0x000001C4U + +#define ETH_MAC_TXFIFO_FULL 0x02000000U /* Tx FIFO full */ +#define ETH_MAC_TXFIFONOT_EMPTY 0x01000000U /* Tx FIFO not empty */ +#define ETH_MAC_TXFIFO_WRITE_ACTIVE 0x00400000U /* Tx FIFO write active */ +#define ETH_MAC_TXFIFO_IDLE 0x00000000U /* Tx FIFO read status: Idle */ +#define ETH_MAC_TXFIFO_READ \ + 0x00100000U /* Tx FIFO read status: Read (transferring data to \ + the MAC transmitter) */ +#define ETH_MAC_TXFIFO_WAITING \ + 0x00200000U /* Tx FIFO read status: Waiting for TxStatus from \ + MAC transmitter */ +#define ETH_MAC_TXFIFO_WRITING \ + 0x00300000U /* Tx FIFO read status: Writing the received TxStatus \ + or flushing the TxFIFO */ +#define ETH_MAC_TRANSMISSION_PAUSE 0x00080000U /* MAC transmitter in pause */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE \ + 0x00000000U /* MAC transmit frame controller: Idle */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING \ + 0x00020000U /* MAC transmit frame controller: Waiting for Status \ + of previous frame or IFG/backoff period to be over */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF \ + 0x00040000U /* MAC transmit frame controller: Generating and \ + transmitting a Pause control frame (in full duplex mode) */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING \ + 0x00060000U /* MAC transmit frame controller: Transferring input \ + frame for transmission */ +#define ETH_MAC_MII_TRANSMIT_ACTIVE 0x00010000U /* MAC MII transmit engine active */ +#define ETH_MAC_RXFIFO_EMPTY 0x00000000U /* Rx FIFO fill level: empty */ +#define ETH_MAC_RXFIFO_BELOW_THRESHOLD \ + 0x00000100U /* Rx FIFO fill level: fill-level below flow-control \ + de-activate threshold */ +#define ETH_MAC_RXFIFO_ABOVE_THRESHOLD \ + 0x00000200U /* Rx FIFO fill level: fill-level above flow-control \ + activate threshold */ +#define ETH_MAC_RXFIFO_FULL 0x00000300U /* Rx FIFO fill level: full */ +#if defined(STM32F1) +#else +#define ETH_MAC_READCONTROLLER_IDLE 0x00000000U /* Rx FIFO read controller IDLE state */ +#define ETH_MAC_READCONTROLLER_READING_DATA \ + 0x00000020U /* Rx FIFO read controller Reading frame data */ +#define ETH_MAC_READCONTROLLER_READING_STATUS \ + 0x00000040U /* Rx FIFO read controller Reading frame status \ + (or time-stamp) */ +#endif +#define ETH_MAC_READCONTROLLER_FLUSHING \ + 0x00000060U /* Rx FIFO read controller Flushing the frame data and \ + status */ +#define ETH_MAC_RXFIFO_WRITE_ACTIVE 0x00000010U /* Rx FIFO write controller active */ +#define ETH_MAC_SMALL_FIFO_NOTACTIVE \ + 0x00000000U /* MAC small FIFO read / write controllers not active */ +#define ETH_MAC_SMALL_FIFO_READ_ACTIVE \ + 0x00000002U /* MAC small FIFO read controller active */ +#define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE \ + 0x00000004U /* MAC small FIFO write controller active */ +#define ETH_MAC_SMALL_FIFO_RW_ACTIVE \ + 0x00000006U /* MAC small FIFO read / write controllers active */ +#define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE \ + 0x00000001U /* MAC MII receive protocol engine active */ + +/** + * @} + */ + +/** @defgroup HAL_DCMI_Aliased_Defines HAL DCMI Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define HAL_DCMI_ERROR_OVF HAL_DCMI_ERROR_OVR +#define DCMI_IT_OVF DCMI_IT_OVR +#define DCMI_FLAG_OVFRI DCMI_FLAG_OVRRI +#define DCMI_FLAG_OVFMI DCMI_FLAG_OVRMI + +#define HAL_DCMI_ConfigCROP HAL_DCMI_ConfigCrop +#define HAL_DCMI_EnableCROP HAL_DCMI_EnableCrop +#define HAL_DCMI_DisableCROP HAL_DCMI_DisableCrop + + /** + * @} + */ + +#if defined(STM32L4) || defined(STM32F7) || defined(STM32F427xx) || \ + defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ + defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32H7) +/** @defgroup HAL_DMA2D_Aliased_Defines HAL DMA2D Aliased Defines maintained for legacy + * purpose + * @{ + */ +#define DMA2D_ARGB8888 DMA2D_OUTPUT_ARGB8888 +#define DMA2D_RGB888 DMA2D_OUTPUT_RGB888 +#define DMA2D_RGB565 DMA2D_OUTPUT_RGB565 +#define DMA2D_ARGB1555 DMA2D_OUTPUT_ARGB1555 +#define DMA2D_ARGB4444 DMA2D_OUTPUT_ARGB4444 + +#define CM_ARGB8888 DMA2D_INPUT_ARGB8888 +#define CM_RGB888 DMA2D_INPUT_RGB888 +#define CM_RGB565 DMA2D_INPUT_RGB565 +#define CM_ARGB1555 DMA2D_INPUT_ARGB1555 +#define CM_ARGB4444 DMA2D_INPUT_ARGB4444 +#define CM_L8 DMA2D_INPUT_L8 +#define CM_AL44 DMA2D_INPUT_AL44 +#define CM_AL88 DMA2D_INPUT_AL88 +#define CM_L4 DMA2D_INPUT_L4 +#define CM_A8 DMA2D_INPUT_A8 +#define CM_A4 DMA2D_INPUT_A4 +/** + * @} + */ +#endif /* STM32L4 || STM32F7 || STM32F4 || STM32H7 */ + +#if defined(STM32L4) || defined(STM32F7) || defined(STM32F427xx) || \ + defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ + defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32H7) || defined(STM32U5) +/** @defgroup DMA2D_Aliases DMA2D API Aliases + * @{ + */ +#define HAL_DMA2D_DisableCLUT \ + HAL_DMA2D_CLUTLoading_Abort /*!< Aliased to HAL_DMA2D_CLUTLoading_Abort \ + for compatibility with legacy code */ + /** + * @} + */ + +#endif /* STM32L4 || STM32F7 || STM32F4 || STM32H7 || STM32U5 */ + +/** @defgroup HAL_PPP_Aliased_Defines HAL PPP Aliased Defines maintained for legacy + * purpose + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup HAL_CRYP_Aliased_Functions HAL CRYP Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_CRYP_ComputationCpltCallback HAL_CRYPEx_ComputationCpltCallback + /** + * @} + */ + + /** @defgroup HAL_DCACHE_Aliased_Functions HAL DCACHE Aliased Functions maintained for + * legacy purpose + * @{ + */ + +#if defined(STM32U5) +#define HAL_DCACHE_CleanInvalidateByAddr HAL_DCACHE_CleanInvalidByAddr +#define HAL_DCACHE_CleanInvalidateByAddr_IT HAL_DCACHE_CleanInvalidByAddr_IT +#endif /* STM32U5 */ + + /** + * @} + */ + +#if !defined(STM32F2) +/** @defgroup HASH_alias HASH API alias + * @{ + */ +#define HAL_HASHEx_IRQHandler \ + HAL_HASH_IRQHandler /*!< Redirection for compatibility with legacy code */ +/** + * + * @} + */ +#endif /* STM32F2 */ +/** @defgroup HAL_HASH_Aliased_Functions HAL HASH Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_HASH_STATETypeDef HAL_HASH_StateTypeDef +#define HAL_HASHPhaseTypeDef HAL_HASH_PhaseTypeDef +#define HAL_HMAC_MD5_Finish HAL_HASH_MD5_Finish +#define HAL_HMAC_SHA1_Finish HAL_HASH_SHA1_Finish +#define HAL_HMAC_SHA224_Finish HAL_HASH_SHA224_Finish +#define HAL_HMAC_SHA256_Finish HAL_HASH_SHA256_Finish + + /*HASH Algorithm Selection*/ + +#define HASH_AlgoSelection_SHA1 HASH_ALGOSELECTION_SHA1 +#define HASH_AlgoSelection_SHA224 HASH_ALGOSELECTION_SHA224 +#define HASH_AlgoSelection_SHA256 HASH_ALGOSELECTION_SHA256 +#define HASH_AlgoSelection_MD5 HASH_ALGOSELECTION_MD5 + +#define HASH_AlgoMode_HASH HASH_ALGOMODE_HASH +#define HASH_AlgoMode_HMAC HASH_ALGOMODE_HMAC + +#define HASH_HMACKeyType_ShortKey HASH_HMAC_KEYTYPE_SHORTKEY +#define HASH_HMACKeyType_LongKey HASH_HMAC_KEYTYPE_LONGKEY + +#if defined(STM32L4) || defined(STM32L5) || defined(STM32F2) || defined(STM32F4) || \ + defined(STM32F7) || defined(STM32H7) + +#define HAL_HASH_MD5_Accumulate HAL_HASH_MD5_Accmlt +#define HAL_HASH_MD5_Accumulate_End HAL_HASH_MD5_Accmlt_End +#define HAL_HASH_MD5_Accumulate_IT HAL_HASH_MD5_Accmlt_IT +#define HAL_HASH_MD5_Accumulate_End_IT HAL_HASH_MD5_Accmlt_End_IT + +#define HAL_HASH_SHA1_Accumulate HAL_HASH_SHA1_Accmlt +#define HAL_HASH_SHA1_Accumulate_End HAL_HASH_SHA1_Accmlt_End +#define HAL_HASH_SHA1_Accumulate_IT HAL_HASH_SHA1_Accmlt_IT +#define HAL_HASH_SHA1_Accumulate_End_IT HAL_HASH_SHA1_Accmlt_End_IT + +#define HAL_HASHEx_SHA224_Accumulate HAL_HASHEx_SHA224_Accmlt +#define HAL_HASHEx_SHA224_Accumulate_End HAL_HASHEx_SHA224_Accmlt_End +#define HAL_HASHEx_SHA224_Accumulate_IT HAL_HASHEx_SHA224_Accmlt_IT +#define HAL_HASHEx_SHA224_Accumulate_End_IT HAL_HASHEx_SHA224_Accmlt_End_IT + +#define HAL_HASHEx_SHA256_Accumulate HAL_HASHEx_SHA256_Accmlt +#define HAL_HASHEx_SHA256_Accumulate_End HAL_HASHEx_SHA256_Accmlt_End +#define HAL_HASHEx_SHA256_Accumulate_IT HAL_HASHEx_SHA256_Accmlt_IT +#define HAL_HASHEx_SHA256_Accumulate_End_IT HAL_HASHEx_SHA256_Accmlt_End_IT + +#endif /* STM32L4 || STM32L5 || STM32F2 || STM32F4 || STM32F7 || STM32H7 */ +/** + * @} + */ + +/** @defgroup HAL_Aliased_Functions HAL Generic Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_EnableDBGSleepMode HAL_DBGMCU_EnableDBGSleepMode +#define HAL_DisableDBGSleepMode HAL_DBGMCU_DisableDBGSleepMode +#define HAL_EnableDBGStopMode HAL_DBGMCU_EnableDBGStopMode +#define HAL_DisableDBGStopMode HAL_DBGMCU_DisableDBGStopMode +#define HAL_EnableDBGStandbyMode HAL_DBGMCU_EnableDBGStandbyMode +#define HAL_DisableDBGStandbyMode HAL_DBGMCU_DisableDBGStandbyMode +#define HAL_DBG_LowPowerConfig(Periph, cmd) \ + (((cmd) == ENABLE) ? HAL_DBGMCU_DBG_EnableLowPowerConfig(Periph) \ + : HAL_DBGMCU_DBG_DisableLowPowerConfig(Periph)) +#define HAL_VREFINT_OutputSelect HAL_SYSCFG_VREFINT_OutputSelect +#define HAL_Lock_Cmd(cmd) \ + (((cmd) == ENABLE) ? HAL_SYSCFG_Enable_Lock_VREFINT() \ + : HAL_SYSCFG_Disable_Lock_VREFINT()) +#if defined(STM32L0) +#else +#define HAL_VREFINT_Cmd(cmd) \ + (((cmd) == ENABLE) ? HAL_SYSCFG_EnableVREFINT() : HAL_SYSCFG_DisableVREFINT()) +#endif +#define HAL_ADC_EnableBuffer_Cmd(cmd) \ + (((cmd) == ENABLE) ? HAL_ADCEx_EnableVREFINT() : HAL_ADCEx_DisableVREFINT()) +#define HAL_ADC_EnableBufferSensor_Cmd(cmd) \ + (((cmd) == ENABLE) ? HAL_ADCEx_EnableVREFINTTempSensor() \ + : HAL_ADCEx_DisableVREFINTTempSensor()) +#if defined(STM32H7A3xx) || defined(STM32H7B3xx) || defined(STM32H7B0xx) || \ + defined(STM32H7A3xxQ) || defined(STM32H7B3xxQ) || defined(STM32H7B0xxQ) +#define HAL_EnableSRDomainDBGStopMode HAL_EnableDomain3DBGStopMode +#define HAL_DisableSRDomainDBGStopMode HAL_DisableDomain3DBGStopMode +#define HAL_EnableSRDomainDBGStandbyMode HAL_EnableDomain3DBGStandbyMode +#define HAL_DisableSRDomainDBGStandbyMode HAL_DisableDomain3DBGStandbyMode +#endif /* STM32H7A3xx || STM32H7B3xx || STM32H7B0xx || STM32H7A3xxQ || STM32H7B3xxQ || \ + STM32H7B0xxQ */ + +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Functions HAL FLASH Aliased Functions maintained for + * legacy purpose + * @{ + */ +#define FLASH_HalfPageProgram HAL_FLASHEx_HalfPageProgram +#define FLASH_EnableRunPowerDown HAL_FLASHEx_EnableRunPowerDown +#define FLASH_DisableRunPowerDown HAL_FLASHEx_DisableRunPowerDown +#define HAL_DATA_EEPROMEx_Unlock HAL_FLASHEx_DATAEEPROM_Unlock +#define HAL_DATA_EEPROMEx_Lock HAL_FLASHEx_DATAEEPROM_Lock +#define HAL_DATA_EEPROMEx_Erase HAL_FLASHEx_DATAEEPROM_Erase +#define HAL_DATA_EEPROMEx_Program HAL_FLASHEx_DATAEEPROM_Program + +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Functions HAL I2C Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_I2CEx_AnalogFilter_Config HAL_I2CEx_ConfigAnalogFilter +#define HAL_I2CEx_DigitalFilter_Config HAL_I2CEx_ConfigDigitalFilter +#define HAL_FMPI2CEx_AnalogFilter_Config HAL_FMPI2CEx_ConfigAnalogFilter +#define HAL_FMPI2CEx_DigitalFilter_Config HAL_FMPI2CEx_ConfigDigitalFilter + +#define HAL_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus, cmd) \ + ((cmd == ENABLE) ? HAL_I2CEx_EnableFastModePlus(SYSCFG_I2CFastModePlus) \ + : HAL_I2CEx_DisableFastModePlus(SYSCFG_I2CFastModePlus)) + +#if defined(STM32H7) || defined(STM32WB) || defined(STM32G0) || defined(STM32F0) || \ + defined(STM32F1) || defined(STM32F2) || defined(STM32F3) || defined(STM32F4) || \ + defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32L5) || \ + defined(STM32G4) || defined(STM32L1) +#define HAL_I2C_Master_Sequential_Transmit_IT HAL_I2C_Master_Seq_Transmit_IT +#define HAL_I2C_Master_Sequential_Receive_IT HAL_I2C_Master_Seq_Receive_IT +#define HAL_I2C_Slave_Sequential_Transmit_IT HAL_I2C_Slave_Seq_Transmit_IT +#define HAL_I2C_Slave_Sequential_Receive_IT HAL_I2C_Slave_Seq_Receive_IT +#endif /* STM32H7 || STM32WB || STM32G0 || STM32F0 || STM32F1 || STM32F2 || STM32F3 || \ + STM32F4 || STM32F7 || STM32L0 || STM32L4 || STM32L5 || STM32G4 || STM32L1 */ +#if defined(STM32H7) || defined(STM32WB) || defined(STM32G0) || defined(STM32F4) || \ + defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32L5) || \ + defined(STM32G4) || defined(STM32L1) +#define HAL_I2C_Master_Sequential_Transmit_DMA HAL_I2C_Master_Seq_Transmit_DMA +#define HAL_I2C_Master_Sequential_Receive_DMA HAL_I2C_Master_Seq_Receive_DMA +#define HAL_I2C_Slave_Sequential_Transmit_DMA HAL_I2C_Slave_Seq_Transmit_DMA +#define HAL_I2C_Slave_Sequential_Receive_DMA HAL_I2C_Slave_Seq_Receive_DMA +#endif /* STM32H7 || STM32WB || STM32G0 || STM32F4 || STM32F7 || STM32L0 || STM32L4 || \ + STM32L5 || STM32G4 || STM32L1 */ + +#if defined(STM32F4) +#define HAL_FMPI2C_Master_Sequential_Transmit_IT HAL_FMPI2C_Master_Seq_Transmit_IT +#define HAL_FMPI2C_Master_Sequential_Receive_IT HAL_FMPI2C_Master_Seq_Receive_IT +#define HAL_FMPI2C_Slave_Sequential_Transmit_IT HAL_FMPI2C_Slave_Seq_Transmit_IT +#define HAL_FMPI2C_Slave_Sequential_Receive_IT HAL_FMPI2C_Slave_Seq_Receive_IT +#define HAL_FMPI2C_Master_Sequential_Transmit_DMA HAL_FMPI2C_Master_Seq_Transmit_DMA +#define HAL_FMPI2C_Master_Sequential_Receive_DMA HAL_FMPI2C_Master_Seq_Receive_DMA +#define HAL_FMPI2C_Slave_Sequential_Transmit_DMA HAL_FMPI2C_Slave_Seq_Transmit_DMA +#define HAL_FMPI2C_Slave_Sequential_Receive_DMA HAL_FMPI2C_Slave_Seq_Receive_DMA +#endif /* STM32F4 */ + /** + * @} + */ + + /** @defgroup HAL_PWR_Aliased HAL PWR Aliased maintained for legacy purpose + * @{ + */ + +#if defined(STM32G0) +#define HAL_PWR_ConfigPVD HAL_PWREx_ConfigPVD +#define HAL_PWR_EnablePVD HAL_PWREx_EnablePVD +#define HAL_PWR_DisablePVD HAL_PWREx_DisablePVD +#define HAL_PWR_PVD_IRQHandler HAL_PWREx_PVD_IRQHandler +#endif +#define HAL_PWR_PVDConfig HAL_PWR_ConfigPVD +#define HAL_PWR_DisableBkUpReg HAL_PWREx_DisableBkUpReg +#define HAL_PWR_DisableFlashPowerDown HAL_PWREx_DisableFlashPowerDown +#define HAL_PWR_DisableVddio2Monitor HAL_PWREx_DisableVddio2Monitor +#define HAL_PWR_EnableBkUpReg HAL_PWREx_EnableBkUpReg +#define HAL_PWR_EnableFlashPowerDown HAL_PWREx_EnableFlashPowerDown +#define HAL_PWR_EnableVddio2Monitor HAL_PWREx_EnableVddio2Monitor +#define HAL_PWR_PVD_PVM_IRQHandler HAL_PWREx_PVD_PVM_IRQHandler +#define HAL_PWR_PVDLevelConfig HAL_PWR_ConfigPVD +#define HAL_PWR_Vddio2Monitor_IRQHandler HAL_PWREx_Vddio2Monitor_IRQHandler +#define HAL_PWR_Vddio2MonitorCallback HAL_PWREx_Vddio2MonitorCallback +#define HAL_PWREx_ActivateOverDrive HAL_PWREx_EnableOverDrive +#define HAL_PWREx_DeactivateOverDrive HAL_PWREx_DisableOverDrive +#define HAL_PWREx_DisableSDADCAnalog HAL_PWREx_DisableSDADC +#define HAL_PWREx_EnableSDADCAnalog HAL_PWREx_EnableSDADC +#define HAL_PWREx_PVMConfig HAL_PWREx_ConfigPVM + +#define PWR_MODE_NORMAL PWR_PVD_MODE_NORMAL +#define PWR_MODE_IT_RISING PWR_PVD_MODE_IT_RISING +#define PWR_MODE_IT_FALLING PWR_PVD_MODE_IT_FALLING +#define PWR_MODE_IT_RISING_FALLING PWR_PVD_MODE_IT_RISING_FALLING +#define PWR_MODE_EVENT_RISING PWR_PVD_MODE_EVENT_RISING +#define PWR_MODE_EVENT_FALLING PWR_PVD_MODE_EVENT_FALLING +#define PWR_MODE_EVENT_RISING_FALLING PWR_PVD_MODE_EVENT_RISING_FALLING + +#define CR_OFFSET_BB PWR_CR_OFFSET_BB +#define CSR_OFFSET_BB PWR_CSR_OFFSET_BB +#define PMODE_BIT_NUMBER VOS_BIT_NUMBER +#define CR_PMODE_BB CR_VOS_BB + +#define DBP_BitNumber DBP_BIT_NUMBER +#define PVDE_BitNumber PVDE_BIT_NUMBER +#define PMODE_BitNumber PMODE_BIT_NUMBER +#define EWUP_BitNumber EWUP_BIT_NUMBER +#define FPDS_BitNumber FPDS_BIT_NUMBER +#define ODEN_BitNumber ODEN_BIT_NUMBER +#define ODSWEN_BitNumber ODSWEN_BIT_NUMBER +#define MRLVDS_BitNumber MRLVDS_BIT_NUMBER +#define LPLVDS_BitNumber LPLVDS_BIT_NUMBER +#define BRE_BitNumber BRE_BIT_NUMBER + +#define PWR_MODE_EVT PWR_PVD_MODE_NORMAL + +#if defined(STM32U5) +#define PWR_SRAM1_PAGE1_STOP_RETENTION PWR_SRAM1_PAGE1_STOP +#define PWR_SRAM1_PAGE2_STOP_RETENTION PWR_SRAM1_PAGE2_STOP +#define PWR_SRAM1_PAGE3_STOP_RETENTION PWR_SRAM1_PAGE3_STOP +#define PWR_SRAM1_PAGE4_STOP_RETENTION PWR_SRAM1_PAGE4_STOP +#define PWR_SRAM1_PAGE5_STOP_RETENTION PWR_SRAM1_PAGE5_STOP +#define PWR_SRAM1_PAGE6_STOP_RETENTION PWR_SRAM1_PAGE6_STOP +#define PWR_SRAM1_PAGE7_STOP_RETENTION PWR_SRAM1_PAGE7_STOP +#define PWR_SRAM1_PAGE8_STOP_RETENTION PWR_SRAM1_PAGE8_STOP +#define PWR_SRAM1_PAGE9_STOP_RETENTION PWR_SRAM1_PAGE9_STOP +#define PWR_SRAM1_PAGE10_STOP_RETENTION PWR_SRAM1_PAGE10_STOP +#define PWR_SRAM1_PAGE11_STOP_RETENTION PWR_SRAM1_PAGE11_STOP +#define PWR_SRAM1_PAGE12_STOP_RETENTION PWR_SRAM1_PAGE12_STOP +#define PWR_SRAM1_FULL_STOP_RETENTION PWR_SRAM1_FULL_STOP + +#define PWR_SRAM2_PAGE1_STOP_RETENTION PWR_SRAM2_PAGE1_STOP +#define PWR_SRAM2_PAGE2_STOP_RETENTION PWR_SRAM2_PAGE2_STOP +#define PWR_SRAM2_FULL_STOP_RETENTION PWR_SRAM2_FULL_STOP + +#define PWR_SRAM3_PAGE1_STOP_RETENTION PWR_SRAM3_PAGE1_STOP +#define PWR_SRAM3_PAGE2_STOP_RETENTION PWR_SRAM3_PAGE2_STOP +#define PWR_SRAM3_PAGE3_STOP_RETENTION PWR_SRAM3_PAGE3_STOP +#define PWR_SRAM3_PAGE4_STOP_RETENTION PWR_SRAM3_PAGE4_STOP +#define PWR_SRAM3_PAGE5_STOP_RETENTION PWR_SRAM3_PAGE5_STOP +#define PWR_SRAM3_PAGE6_STOP_RETENTION PWR_SRAM3_PAGE6_STOP +#define PWR_SRAM3_PAGE7_STOP_RETENTION PWR_SRAM3_PAGE7_STOP +#define PWR_SRAM3_PAGE8_STOP_RETENTION PWR_SRAM3_PAGE8_STOP +#define PWR_SRAM3_PAGE9_STOP_RETENTION PWR_SRAM3_PAGE9_STOP +#define PWR_SRAM3_PAGE10_STOP_RETENTION PWR_SRAM3_PAGE10_STOP +#define PWR_SRAM3_PAGE11_STOP_RETENTION PWR_SRAM3_PAGE11_STOP +#define PWR_SRAM3_PAGE12_STOP_RETENTION PWR_SRAM3_PAGE12_STOP +#define PWR_SRAM3_PAGE13_STOP_RETENTION PWR_SRAM3_PAGE13_STOP +#define PWR_SRAM3_FULL_STOP_RETENTION PWR_SRAM3_FULL_STOP + +#define PWR_SRAM4_FULL_STOP_RETENTION PWR_SRAM4_FULL_STOP + +#define PWR_SRAM5_PAGE1_STOP_RETENTION PWR_SRAM5_PAGE1_STOP +#define PWR_SRAM5_PAGE2_STOP_RETENTION PWR_SRAM5_PAGE2_STOP +#define PWR_SRAM5_PAGE3_STOP_RETENTION PWR_SRAM5_PAGE3_STOP +#define PWR_SRAM5_PAGE4_STOP_RETENTION PWR_SRAM5_PAGE4_STOP +#define PWR_SRAM5_PAGE5_STOP_RETENTION PWR_SRAM5_PAGE5_STOP +#define PWR_SRAM5_PAGE6_STOP_RETENTION PWR_SRAM5_PAGE6_STOP +#define PWR_SRAM5_PAGE7_STOP_RETENTION PWR_SRAM5_PAGE7_STOP +#define PWR_SRAM5_PAGE8_STOP_RETENTION PWR_SRAM5_PAGE8_STOP +#define PWR_SRAM5_PAGE9_STOP_RETENTION PWR_SRAM5_PAGE9_STOP +#define PWR_SRAM5_PAGE10_STOP_RETENTION PWR_SRAM5_PAGE10_STOP +#define PWR_SRAM5_PAGE11_STOP_RETENTION PWR_SRAM5_PAGE11_STOP +#define PWR_SRAM5_PAGE12_STOP_RETENTION PWR_SRAM5_PAGE12_STOP +#define PWR_SRAM5_PAGE13_STOP_RETENTION PWR_SRAM5_PAGE13_STOP +#define PWR_SRAM5_FULL_STOP_RETENTION PWR_SRAM5_FULL_STOP + +#define PWR_SRAM6_PAGE1_STOP_RETENTION PWR_SRAM6_PAGE1_STOP +#define PWR_SRAM6_PAGE2_STOP_RETENTION PWR_SRAM6_PAGE2_STOP +#define PWR_SRAM6_PAGE3_STOP_RETENTION PWR_SRAM6_PAGE3_STOP +#define PWR_SRAM6_PAGE4_STOP_RETENTION PWR_SRAM6_PAGE4_STOP +#define PWR_SRAM6_PAGE5_STOP_RETENTION PWR_SRAM6_PAGE5_STOP +#define PWR_SRAM6_PAGE6_STOP_RETENTION PWR_SRAM6_PAGE6_STOP +#define PWR_SRAM6_PAGE7_STOP_RETENTION PWR_SRAM6_PAGE7_STOP +#define PWR_SRAM6_PAGE8_STOP_RETENTION PWR_SRAM6_PAGE8_STOP +#define PWR_SRAM6_FULL_STOP_RETENTION PWR_SRAM6_FULL_STOP + + +#define PWR_ICACHE_FULL_STOP_RETENTION PWR_ICACHE_FULL_STOP +#define PWR_DCACHE1_FULL_STOP_RETENTION PWR_DCACHE1_FULL_STOP +#define PWR_DCACHE2_FULL_STOP_RETENTION PWR_DCACHE2_FULL_STOP +#define PWR_DMA2DRAM_FULL_STOP_RETENTION PWR_DMA2DRAM_FULL_STOP +#define PWR_PERIPHRAM_FULL_STOP_RETENTION PWR_PERIPHRAM_FULL_STOP +#define PWR_PKA32RAM_FULL_STOP_RETENTION PWR_PKA32RAM_FULL_STOP +#define PWR_GRAPHICPRAM_FULL_STOP_RETENTION PWR_GRAPHICPRAM_FULL_STOP +#define PWR_DSIRAM_FULL_STOP_RETENTION PWR_DSIRAM_FULL_STOP +#define PWR_JPEGRAM_FULL_STOP_RETENTION PWR_JPEGRAM_FULL_STOP + + +#define PWR_SRAM2_PAGE1_STANDBY_RETENTION PWR_SRAM2_PAGE1_STANDBY +#define PWR_SRAM2_PAGE2_STANDBY_RETENTION PWR_SRAM2_PAGE2_STANDBY +#define PWR_SRAM2_FULL_STANDBY_RETENTION PWR_SRAM2_FULL_STANDBY + +#define PWR_SRAM1_FULL_RUN_RETENTION PWR_SRAM1_FULL_RUN +#define PWR_SRAM2_FULL_RUN_RETENTION PWR_SRAM2_FULL_RUN +#define PWR_SRAM3_FULL_RUN_RETENTION PWR_SRAM3_FULL_RUN +#define PWR_SRAM4_FULL_RUN_RETENTION PWR_SRAM4_FULL_RUN +#define PWR_SRAM5_FULL_RUN_RETENTION PWR_SRAM5_FULL_RUN +#define PWR_SRAM6_FULL_RUN_RETENTION PWR_SRAM6_FULL_RUN + +#define PWR_ALL_RAM_RUN_RETENTION_MASK PWR_ALL_RAM_RUN_MASK +#endif + +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Functions HAL RTC Aliased Functions maintained for legacy + * purpose + * @{ + */ +#if defined(STM32H5) || defined(STM32WBA) +#define HAL_RTCEx_SetBoothardwareKey HAL_RTCEx_LockBootHardwareKey +#define HAL_RTCEx_BKUPBlock_Enable HAL_RTCEx_BKUPBlock +#define HAL_RTCEx_BKUPBlock_Disable HAL_RTCEx_BKUPUnblock +#define HAL_RTCEx_Erase_SecretDev_Conf HAL_RTCEx_ConfigEraseDeviceSecrets +#endif /* STM32H5 || STM32WBA */ + +/** + * @} + */ + +/** @defgroup HAL_SMBUS_Aliased_Functions HAL SMBUS Aliased Functions maintained for + * legacy purpose + * @{ + */ +#define HAL_SMBUS_Slave_Listen_IT HAL_SMBUS_EnableListen_IT +#define HAL_SMBUS_SlaveAddrCallback HAL_SMBUS_AddrCallback +#define HAL_SMBUS_SlaveListenCpltCallback HAL_SMBUS_ListenCpltCallback +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Functions HAL SPI Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_SPI_FlushRxFifo HAL_SPIEx_FlushRxFifo +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Functions HAL TIM Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_TIM_DMADelayPulseCplt TIM_DMADelayPulseCplt +#define HAL_TIM_DMAError TIM_DMAError +#define HAL_TIM_DMACaptureCplt TIM_DMACaptureCplt +#define HAL_TIMEx_DMACommutationCplt TIMEx_DMACommutationCplt +#if defined(STM32H7) || defined(STM32G0) || defined(STM32F0) || defined(STM32F1) || \ + defined(STM32F2) || defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || \ + defined(STM32L0) || defined(STM32L4) +#define HAL_TIM_SlaveConfigSynchronization HAL_TIM_SlaveConfigSynchro +#define HAL_TIM_SlaveConfigSynchronization_IT HAL_TIM_SlaveConfigSynchro_IT +#define HAL_TIMEx_CommutationCallback HAL_TIMEx_CommutCallback +#define HAL_TIMEx_ConfigCommutationEvent HAL_TIMEx_ConfigCommutEvent +#define HAL_TIMEx_ConfigCommutationEvent_IT HAL_TIMEx_ConfigCommutEvent_IT +#define HAL_TIMEx_ConfigCommutationEvent_DMA HAL_TIMEx_ConfigCommutEvent_DMA +#endif /* STM32H7 || STM32G0 || STM32F0 || STM32F1 || STM32F2 || STM32F3 || STM32F4 || \ + STM32F7 || STM32L0 */ +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Functions HAL UART Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_UART_WakeupCallback HAL_UARTEx_WakeupCallback +/** + * @} + */ + +/** @defgroup HAL_LTDC_Aliased_Functions HAL LTDC Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_LTDC_LineEvenCallback HAL_LTDC_LineEventCallback +#define HAL_LTDC_Relaod HAL_LTDC_Reload +#define HAL_LTDC_StructInitFromVideoConfig HAL_LTDCEx_StructInitFromVideoConfig +#define HAL_LTDC_StructInitFromAdaptedCommandConfig \ + HAL_LTDCEx_StructInitFromAdaptedCommandConfig +/** + * @} + */ + + +/** @defgroup HAL_PPP_Aliased_Functions HAL PPP Aliased Functions maintained for legacy + * purpose + * @{ + */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ + +/** @defgroup HAL_AES_Aliased_Macros HAL CRYP Aliased Macros maintained for legacy purpose + * @{ + */ +#define AES_IT_CC CRYP_IT_CC +#define AES_IT_ERR CRYP_IT_ERR +#define AES_FLAG_CCF CRYP_FLAG_CCF +/** + * @} + */ + +/** @defgroup HAL_Aliased_Macros HAL Generic Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_GET_BOOT_MODE __HAL_SYSCFG_GET_BOOT_MODE +#define __HAL_REMAPMEMORY_FLASH __HAL_SYSCFG_REMAPMEMORY_FLASH +#define __HAL_REMAPMEMORY_SYSTEMFLASH __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH +#define __HAL_REMAPMEMORY_SRAM __HAL_SYSCFG_REMAPMEMORY_SRAM +#define __HAL_REMAPMEMORY_FMC __HAL_SYSCFG_REMAPMEMORY_FMC +#define __HAL_REMAPMEMORY_FMC_SDRAM __HAL_SYSCFG_REMAPMEMORY_FMC_SDRAM +#define __HAL_REMAPMEMORY_FSMC __HAL_SYSCFG_REMAPMEMORY_FSMC +#define __HAL_REMAPMEMORY_QUADSPI __HAL_SYSCFG_REMAPMEMORY_QUADSPI +#define __HAL_FMC_BANK __HAL_SYSCFG_FMC_BANK +#define __HAL_GET_FLAG __HAL_SYSCFG_GET_FLAG +#define __HAL_CLEAR_FLAG __HAL_SYSCFG_CLEAR_FLAG +#define __HAL_VREFINT_OUT_ENABLE __HAL_SYSCFG_VREFINT_OUT_ENABLE +#define __HAL_VREFINT_OUT_DISABLE __HAL_SYSCFG_VREFINT_OUT_DISABLE +#define __HAL_SYSCFG_SRAM2_WRP_ENABLE __HAL_SYSCFG_SRAM2_WRP_0_31_ENABLE + +#define SYSCFG_FLAG_VREF_READY SYSCFG_FLAG_VREFINT_READY +#define SYSCFG_FLAG_RC48 RCC_FLAG_HSI48 +#define IS_SYSCFG_FASTMODEPLUS_CONFIG IS_I2C_FASTMODEPLUS +#define UFB_MODE_BitNumber UFB_MODE_BIT_NUMBER +#define CMP_PD_BitNumber CMP_PD_BIT_NUMBER + +/** + * @} + */ + + +/** @defgroup HAL_ADC_Aliased_Macros HAL ADC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __ADC_ENABLE __HAL_ADC_ENABLE +#define __ADC_DISABLE __HAL_ADC_DISABLE +#define __HAL_ADC_ENABLING_CONDITIONS ADC_ENABLING_CONDITIONS +#define __HAL_ADC_DISABLING_CONDITIONS ADC_DISABLING_CONDITIONS +#define __HAL_ADC_IS_ENABLED ADC_IS_ENABLE +#define __ADC_IS_ENABLED ADC_IS_ENABLE +#define __HAL_ADC_IS_SOFTWARE_START_REGULAR ADC_IS_SOFTWARE_START_REGULAR +#define __HAL_ADC_IS_SOFTWARE_START_INJECTED ADC_IS_SOFTWARE_START_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING_REGULAR_INJECTED \ + ADC_IS_CONVERSION_ONGOING_REGULAR_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING_REGULAR ADC_IS_CONVERSION_ONGOING_REGULAR +#define __HAL_ADC_IS_CONVERSION_ONGOING_INJECTED ADC_IS_CONVERSION_ONGOING_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING ADC_IS_CONVERSION_ONGOING +#define __HAL_ADC_CLEAR_ERRORCODE ADC_CLEAR_ERRORCODE + +#define __HAL_ADC_GET_RESOLUTION ADC_GET_RESOLUTION +#define __HAL_ADC_JSQR_RK ADC_JSQR_RK +#define __HAL_ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_SHIFT +#define __HAL_ADC_CFGR_AWD23CR ADC_CFGR_AWD23CR +#define __HAL_ADC_CFGR_INJECT_AUTO_CONVERSION ADC_CFGR_INJECT_AUTO_CONVERSION +#define __HAL_ADC_CFGR_INJECT_CONTEXT_QUEUE ADC_CFGR_INJECT_CONTEXT_QUEUE +#define __HAL_ADC_CFGR_INJECT_DISCCONTINUOUS ADC_CFGR_INJECT_DISCCONTINUOUS +#define __HAL_ADC_CFGR_REG_DISCCONTINUOUS ADC_CFGR_REG_DISCCONTINUOUS +#define __HAL_ADC_CFGR_DISCONTINUOUS_NUM ADC_CFGR_DISCONTINUOUS_NUM +#define __HAL_ADC_CFGR_AUTOWAIT ADC_CFGR_AUTOWAIT +#define __HAL_ADC_CFGR_CONTINUOUS ADC_CFGR_CONTINUOUS +#define __HAL_ADC_CFGR_OVERRUN ADC_CFGR_OVERRUN +#define __HAL_ADC_CFGR_DMACONTREQ ADC_CFGR_DMACONTREQ +#define __HAL_ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_SET +#define __HAL_ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_SET +#define __HAL_ADC_OFR_CHANNEL ADC_OFR_CHANNEL +#define __HAL_ADC_DIFSEL_CHANNEL ADC_DIFSEL_CHANNEL +#define __HAL_ADC_CALFACT_DIFF_SET ADC_CALFACT_DIFF_SET +#define __HAL_ADC_CALFACT_DIFF_GET ADC_CALFACT_DIFF_GET +#define __HAL_ADC_TRX_HIGHTHRESHOLD ADC_TRX_HIGHTHRESHOLD + +#define __HAL_ADC_OFFSET_SHIFT_RESOLUTION ADC_OFFSET_SHIFT_RESOLUTION +#define __HAL_ADC_AWD1THRESHOLD_SHIFT_RESOLUTION ADC_AWD1THRESHOLD_SHIFT_RESOLUTION +#define __HAL_ADC_AWD23THRESHOLD_SHIFT_RESOLUTION ADC_AWD23THRESHOLD_SHIFT_RESOLUTION +#define __HAL_ADC_COMMON_REGISTER ADC_COMMON_REGISTER +#define __HAL_ADC_COMMON_CCR_MULTI ADC_COMMON_CCR_MULTI +#define __HAL_ADC_MULTIMODE_IS_ENABLED ADC_MULTIMODE_IS_ENABLE +#define __ADC_MULTIMODE_IS_ENABLED ADC_MULTIMODE_IS_ENABLE +#define __HAL_ADC_NONMULTIMODE_OR_MULTIMODEMASTER ADC_NONMULTIMODE_OR_MULTIMODEMASTER +#define __HAL_ADC_COMMON_ADC_OTHER ADC_COMMON_ADC_OTHER +#define __HAL_ADC_MULTI_SLAVE ADC_MULTI_SLAVE + +#define __HAL_ADC_SQR1_L ADC_SQR1_L_SHIFT +#define __HAL_ADC_JSQR_JL ADC_JSQR_JL_SHIFT +#define __HAL_ADC_JSQR_RK_JL ADC_JSQR_RK_JL +#define __HAL_ADC_CR1_DISCONTINUOUS_NUM ADC_CR1_DISCONTINUOUS_NUM +#define __HAL_ADC_CR1_SCAN ADC_CR1_SCAN_SET +#define __HAL_ADC_CONVCYCLES_MAX_RANGE ADC_CONVCYCLES_MAX_RANGE +#define __HAL_ADC_CLOCK_PRESCALER_RANGE ADC_CLOCK_PRESCALER_RANGE +#define __HAL_ADC_GET_CLOCK_PRESCALER ADC_GET_CLOCK_PRESCALER + +#define __HAL_ADC_SQR1 ADC_SQR1 +#define __HAL_ADC_SMPR1 ADC_SMPR1 +#define __HAL_ADC_SMPR2 ADC_SMPR2 +#define __HAL_ADC_SQR3_RK ADC_SQR3_RK +#define __HAL_ADC_SQR2_RK ADC_SQR2_RK +#define __HAL_ADC_SQR1_RK ADC_SQR1_RK +#define __HAL_ADC_CR2_CONTINUOUS ADC_CR2_CONTINUOUS +#define __HAL_ADC_CR1_DISCONTINUOUS ADC_CR1_DISCONTINUOUS +#define __HAL_ADC_CR1_SCANCONV ADC_CR1_SCANCONV +#define __HAL_ADC_CR2_EOCSelection ADC_CR2_EOCSelection +#define __HAL_ADC_CR2_DMAContReq ADC_CR2_DMAContReq +#define __HAL_ADC_JSQR ADC_JSQR + +#define __HAL_ADC_CHSELR_CHANNEL ADC_CHSELR_CHANNEL +#define __HAL_ADC_CFGR1_REG_DISCCONTINUOUS ADC_CFGR1_REG_DISCCONTINUOUS +#define __HAL_ADC_CFGR1_AUTOOFF ADC_CFGR1_AUTOOFF +#define __HAL_ADC_CFGR1_AUTOWAIT ADC_CFGR1_AUTOWAIT +#define __HAL_ADC_CFGR1_CONTINUOUS ADC_CFGR1_CONTINUOUS +#define __HAL_ADC_CFGR1_OVERRUN ADC_CFGR1_OVERRUN +#define __HAL_ADC_CFGR1_SCANDIR ADC_CFGR1_SCANDIR +#define __HAL_ADC_CFGR1_DMACONTREQ ADC_CFGR1_DMACONTREQ + +/** + * @} + */ + +/** @defgroup HAL_DAC_Aliased_Macros HAL DAC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_DHR12R1_ALIGNEMENT DAC_DHR12R1_ALIGNMENT +#define __HAL_DHR12R2_ALIGNEMENT DAC_DHR12R2_ALIGNMENT +#define __HAL_DHR12RD_ALIGNEMENT DAC_DHR12RD_ALIGNMENT +#define IS_DAC_GENERATE_WAVE IS_DAC_WAVE + +/** + * @} + */ + +/** @defgroup HAL_DBGMCU_Aliased_Macros HAL DBGMCU Aliased Macros maintained for legacy + * purpose + * @{ + */ +#define __HAL_FREEZE_TIM1_DBGMCU __HAL_DBGMCU_FREEZE_TIM1 +#define __HAL_UNFREEZE_TIM1_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM1 +#define __HAL_FREEZE_TIM2_DBGMCU __HAL_DBGMCU_FREEZE_TIM2 +#define __HAL_UNFREEZE_TIM2_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM2 +#define __HAL_FREEZE_TIM3_DBGMCU __HAL_DBGMCU_FREEZE_TIM3 +#define __HAL_UNFREEZE_TIM3_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM3 +#define __HAL_FREEZE_TIM4_DBGMCU __HAL_DBGMCU_FREEZE_TIM4 +#define __HAL_UNFREEZE_TIM4_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM4 +#define __HAL_FREEZE_TIM5_DBGMCU __HAL_DBGMCU_FREEZE_TIM5 +#define __HAL_UNFREEZE_TIM5_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM5 +#define __HAL_FREEZE_TIM6_DBGMCU __HAL_DBGMCU_FREEZE_TIM6 +#define __HAL_UNFREEZE_TIM6_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM6 +#define __HAL_FREEZE_TIM7_DBGMCU __HAL_DBGMCU_FREEZE_TIM7 +#define __HAL_UNFREEZE_TIM7_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM7 +#define __HAL_FREEZE_TIM8_DBGMCU __HAL_DBGMCU_FREEZE_TIM8 +#define __HAL_UNFREEZE_TIM8_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM8 + +#define __HAL_FREEZE_TIM9_DBGMCU __HAL_DBGMCU_FREEZE_TIM9 +#define __HAL_UNFREEZE_TIM9_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM9 +#define __HAL_FREEZE_TIM10_DBGMCU __HAL_DBGMCU_FREEZE_TIM10 +#define __HAL_UNFREEZE_TIM10_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM10 +#define __HAL_FREEZE_TIM11_DBGMCU __HAL_DBGMCU_FREEZE_TIM11 +#define __HAL_UNFREEZE_TIM11_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM11 +#define __HAL_FREEZE_TIM12_DBGMCU __HAL_DBGMCU_FREEZE_TIM12 +#define __HAL_UNFREEZE_TIM12_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM12 +#define __HAL_FREEZE_TIM13_DBGMCU __HAL_DBGMCU_FREEZE_TIM13 +#define __HAL_UNFREEZE_TIM13_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM13 +#define __HAL_FREEZE_TIM14_DBGMCU __HAL_DBGMCU_FREEZE_TIM14 +#define __HAL_UNFREEZE_TIM14_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM14 +#define __HAL_FREEZE_CAN2_DBGMCU __HAL_DBGMCU_FREEZE_CAN2 +#define __HAL_UNFREEZE_CAN2_DBGMCU __HAL_DBGMCU_UNFREEZE_CAN2 + + +#define __HAL_FREEZE_TIM15_DBGMCU __HAL_DBGMCU_FREEZE_TIM15 +#define __HAL_UNFREEZE_TIM15_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM15 +#define __HAL_FREEZE_TIM16_DBGMCU __HAL_DBGMCU_FREEZE_TIM16 +#define __HAL_UNFREEZE_TIM16_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM16 +#define __HAL_FREEZE_TIM17_DBGMCU __HAL_DBGMCU_FREEZE_TIM17 +#define __HAL_UNFREEZE_TIM17_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM17 +#define __HAL_FREEZE_RTC_DBGMCU __HAL_DBGMCU_FREEZE_RTC +#define __HAL_UNFREEZE_RTC_DBGMCU __HAL_DBGMCU_UNFREEZE_RTC +#if defined(STM32H7) +#define __HAL_FREEZE_WWDG_DBGMCU __HAL_DBGMCU_FREEZE_WWDG1 +#define __HAL_UNFREEZE_WWDG_DBGMCU __HAL_DBGMCU_UnFreeze_WWDG1 +#define __HAL_FREEZE_IWDG_DBGMCU __HAL_DBGMCU_FREEZE_IWDG1 +#define __HAL_UNFREEZE_IWDG_DBGMCU __HAL_DBGMCU_UnFreeze_IWDG1 +#else +#define __HAL_FREEZE_WWDG_DBGMCU __HAL_DBGMCU_FREEZE_WWDG +#define __HAL_UNFREEZE_WWDG_DBGMCU __HAL_DBGMCU_UNFREEZE_WWDG +#define __HAL_FREEZE_IWDG_DBGMCU __HAL_DBGMCU_FREEZE_IWDG +#define __HAL_UNFREEZE_IWDG_DBGMCU __HAL_DBGMCU_UNFREEZE_IWDG +#endif /* STM32H7 */ +#define __HAL_FREEZE_I2C1_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT +#define __HAL_UNFREEZE_I2C1_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT +#define __HAL_FREEZE_I2C2_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT +#define __HAL_UNFREEZE_I2C2_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT +#define __HAL_FREEZE_I2C3_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C3_TIMEOUT +#define __HAL_UNFREEZE_I2C3_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C3_TIMEOUT +#define __HAL_FREEZE_CAN1_DBGMCU __HAL_DBGMCU_FREEZE_CAN1 +#define __HAL_UNFREEZE_CAN1_DBGMCU __HAL_DBGMCU_UNFREEZE_CAN1 +#define __HAL_FREEZE_LPTIM1_DBGMCU __HAL_DBGMCU_FREEZE_LPTIM1 +#define __HAL_UNFREEZE_LPTIM1_DBGMCU __HAL_DBGMCU_UNFREEZE_LPTIM1 +#define __HAL_FREEZE_LPTIM2_DBGMCU __HAL_DBGMCU_FREEZE_LPTIM2 +#define __HAL_UNFREEZE_LPTIM2_DBGMCU __HAL_DBGMCU_UNFREEZE_LPTIM2 + +/** + * @} + */ + +/** @defgroup HAL_COMP_Aliased_Macros HAL COMP Aliased Macros maintained for legacy + * purpose + * @{ + */ +#if defined(STM32F3) +#define COMP_START __HAL_COMP_ENABLE +#define COMP_STOP __HAL_COMP_DISABLE +#define COMP_LOCK __HAL_COMP_LOCK + +#if defined(STM32F301x8) || defined(STM32F302x8) || defined(STM32F318xx) || \ + defined(STM32F303x8) || defined(STM32F334x8) || defined(STM32F328xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() \ + : __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() \ + : __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() \ + : __HAL_COMP_COMP6_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() \ + : __HAL_COMP_COMP6_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() \ + : __HAL_COMP_COMP6_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() \ + : __HAL_COMP_COMP6_EXTI_CLEAR_FLAG()) +#endif +#if defined(STM32F302xE) || defined(STM32F302xC) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() \ + : __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() \ + : __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() \ + : __HAL_COMP_COMP6_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() \ + : __HAL_COMP_COMP6_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() \ + : __HAL_COMP_COMP6_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() \ + : __HAL_COMP_COMP6_EXTI_CLEAR_FLAG()) +#endif +#if defined(STM32F303xE) || defined(STM32F398xx) || defined(STM32F303xC) || \ + defined(STM32F358xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) \ + ? __HAL_COMP_COMP3_EXTI_ENABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) \ + ? __HAL_COMP_COMP5_EXTI_ENABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) \ + ? __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE() \ + : __HAL_COMP_COMP7_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) \ + ? __HAL_COMP_COMP3_EXTI_DISABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) \ + ? __HAL_COMP_COMP5_EXTI_DISABLE_RISING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) \ + ? __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE() \ + : __HAL_COMP_COMP7_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) \ + ? __HAL_COMP_COMP3_EXTI_ENABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) \ + ? __HAL_COMP_COMP5_EXTI_ENABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) \ + ? __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP7_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) \ + ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) \ + ? __HAL_COMP_COMP3_EXTI_DISABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) \ + ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) \ + ? __HAL_COMP_COMP5_EXTI_DISABLE_FALLING_EDGE() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) \ + ? __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP7_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_ENABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_ENABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_ENABLE_IT() \ + : __HAL_COMP_COMP7_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_DISABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_DISABLE_IT() \ + : ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_DISABLE_IT() \ + : __HAL_COMP_COMP7_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_GET_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_GET_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_GET_FLAG() \ + : __HAL_COMP_COMP7_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_CLEAR_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_CLEAR_FLAG() \ + : ((__FLAG__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_CLEAR_FLAG() \ + : __HAL_COMP_COMP7_EXTI_CLEAR_FLAG()) +#endif +#if defined(STM32F373xC) || defined(STM32F378xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() \ + : __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() \ + : __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() \ + : __HAL_COMP_COMP2_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() \ + : __HAL_COMP_COMP2_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() \ + : __HAL_COMP_COMP2_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() \ + : __HAL_COMP_COMP2_EXTI_CLEAR_FLAG()) +#endif +#else +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() \ + : __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() \ + : __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) \ + ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() \ + : __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() \ + : __HAL_COMP_COMP2_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) \ + (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() \ + : __HAL_COMP_COMP2_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() \ + : __HAL_COMP_COMP2_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) \ + (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() \ + : __HAL_COMP_COMP2_EXTI_CLEAR_FLAG()) +#endif + +#define __HAL_COMP_GET_EXTI_LINE COMP_GET_EXTI_LINE + +#if defined(STM32L0) || defined(STM32L4) +/* Note: On these STM32 families, the only argument of this macro */ +/* is COMP_FLAG_LOCK. */ +/* This macro is replaced by __HAL_COMP_IS_LOCKED with only HAL handle */ +/* argument. */ +#define __HAL_COMP_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_COMP_IS_LOCKED(__HANDLE__)) +#endif + /** + * @} + */ + +#if defined(STM32L0) || defined(STM32L4) +/** @defgroup HAL_COMP_Aliased_Functions HAL COMP Aliased Functions maintained for legacy + * purpose + * @{ + */ +#define HAL_COMP_Start_IT \ + HAL_COMP_Start /* Function considered as legacy as EXTI event or IT configuration is \ + done into HAL_COMP_Init() */ +#define HAL_COMP_Stop_IT \ + HAL_COMP_Stop /* Function considered as legacy as EXTI event or IT configuration is \ + done into HAL_COMP_Init() */ +/** + * @} + */ +#endif + + /** @defgroup HAL_DAC_Aliased_Macros HAL DAC Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define IS_DAC_WAVE(WAVE) \ + (((WAVE) == DAC_WAVE_NONE) || ((WAVE) == DAC_WAVE_NOISE) || \ + ((WAVE) == DAC_WAVE_TRIANGLE)) + + /** + * @} + */ + + /** @defgroup HAL_FLASH_Aliased_Macros HAL FLASH Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define IS_WRPAREA IS_OB_WRPAREA +#define IS_TYPEPROGRAM IS_FLASH_TYPEPROGRAM +#define IS_TYPEPROGRAMFLASH IS_FLASH_TYPEPROGRAM +#define IS_TYPEERASE IS_FLASH_TYPEERASE +#define IS_NBSECTORS IS_FLASH_NBSECTORS +#define IS_OB_WDG_SOURCE IS_OB_IWDG_SOURCE + + /** + * @} + */ + + /** @defgroup HAL_I2C_Aliased_Macros HAL I2C Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define __HAL_I2C_RESET_CR2 I2C_RESET_CR2 +#define __HAL_I2C_GENERATE_START I2C_GENERATE_START +#if defined(STM32F1) +#define __HAL_I2C_FREQ_RANGE I2C_FREQRANGE +#else +#define __HAL_I2C_FREQ_RANGE I2C_FREQ_RANGE +#endif /* STM32F1 */ +#define __HAL_I2C_RISE_TIME I2C_RISE_TIME +#define __HAL_I2C_SPEED_STANDARD I2C_SPEED_STANDARD +#define __HAL_I2C_SPEED_FAST I2C_SPEED_FAST +#define __HAL_I2C_SPEED I2C_SPEED +#define __HAL_I2C_7BIT_ADD_WRITE I2C_7BIT_ADD_WRITE +#define __HAL_I2C_7BIT_ADD_READ I2C_7BIT_ADD_READ +#define __HAL_I2C_10BIT_ADDRESS I2C_10BIT_ADDRESS +#define __HAL_I2C_10BIT_HEADER_WRITE I2C_10BIT_HEADER_WRITE +#define __HAL_I2C_10BIT_HEADER_READ I2C_10BIT_HEADER_READ +#define __HAL_I2C_MEM_ADD_MSB I2C_MEM_ADD_MSB +#define __HAL_I2C_MEM_ADD_LSB I2C_MEM_ADD_LSB +#define __HAL_I2C_FREQRANGE I2C_FREQRANGE + /** + * @} + */ + + /** @defgroup HAL_I2S_Aliased_Macros HAL I2S Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define IS_I2S_INSTANCE IS_I2S_ALL_INSTANCE +#define IS_I2S_INSTANCE_EXT IS_I2S_ALL_INSTANCE_EXT + +#if defined(STM32H7) +#define __HAL_I2S_CLEAR_FREFLAG __HAL_I2S_CLEAR_TIFREFLAG +#endif + + /** + * @} + */ + + /** @defgroup HAL_IRDA_Aliased_Macros HAL IRDA Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define __IRDA_DISABLE __HAL_IRDA_DISABLE +#define __IRDA_ENABLE __HAL_IRDA_ENABLE + +#define __HAL_IRDA_GETCLOCKSOURCE IRDA_GETCLOCKSOURCE +#define __HAL_IRDA_MASK_COMPUTATION IRDA_MASK_COMPUTATION +#define __IRDA_GETCLOCKSOURCE IRDA_GETCLOCKSOURCE +#define __IRDA_MASK_COMPUTATION IRDA_MASK_COMPUTATION + +#define IS_IRDA_ONEBIT_SAMPLE IS_IRDA_ONE_BIT_SAMPLE + + +/** + * @} + */ + + +/** @defgroup HAL_IWDG_Aliased_Macros HAL IWDG Aliased Macros maintained for legacy + * purpose + * @{ + */ +#define __HAL_IWDG_ENABLE_WRITE_ACCESS IWDG_ENABLE_WRITE_ACCESS +#define __HAL_IWDG_DISABLE_WRITE_ACCESS IWDG_DISABLE_WRITE_ACCESS + /** + * @} + */ + + + /** @defgroup HAL_LPTIM_Aliased_Macros HAL LPTIM Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define __HAL_LPTIM_ENABLE_INTERRUPT __HAL_LPTIM_ENABLE_IT +#define __HAL_LPTIM_DISABLE_INTERRUPT __HAL_LPTIM_DISABLE_IT +#define __HAL_LPTIM_GET_ITSTATUS __HAL_LPTIM_GET_IT_SOURCE + +/** + * @} + */ + + +/** @defgroup HAL_OPAMP_Aliased_Macros HAL OPAMP Aliased Macros maintained for legacy + * purpose + * @{ + */ +#define __OPAMP_CSR_OPAXPD OPAMP_CSR_OPAXPD +#define __OPAMP_CSR_S3SELX OPAMP_CSR_S3SELX +#define __OPAMP_CSR_S4SELX OPAMP_CSR_S4SELX +#define __OPAMP_CSR_S5SELX OPAMP_CSR_S5SELX +#define __OPAMP_CSR_S6SELX OPAMP_CSR_S6SELX +#define __OPAMP_CSR_OPAXCAL_L OPAMP_CSR_OPAXCAL_L +#define __OPAMP_CSR_OPAXCAL_H OPAMP_CSR_OPAXCAL_H +#define __OPAMP_CSR_OPAXLPM OPAMP_CSR_OPAXLPM +#define __OPAMP_CSR_ALL_SWITCHES OPAMP_CSR_ALL_SWITCHES +#define __OPAMP_CSR_ANAWSELX OPAMP_CSR_ANAWSELX +#define __OPAMP_CSR_OPAXCALOUT OPAMP_CSR_OPAXCALOUT +#define __OPAMP_OFFSET_TRIM_BITSPOSITION OPAMP_OFFSET_TRIM_BITSPOSITION +#define __OPAMP_OFFSET_TRIM_SET OPAMP_OFFSET_TRIM_SET + +/** + * @} + */ + + +/** @defgroup HAL_PWR_Aliased_Macros HAL PWR Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_PVD_EVENT_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_EVENT +#define __HAL_PVD_EVENT_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_EVENT +#define __HAL_PVD_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PVD_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PVD_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE +#define __HAL_PVD_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PVM_EVENT_DISABLE __HAL_PWR_PVM_EVENT_DISABLE +#define __HAL_PVM_EVENT_ENABLE __HAL_PWR_PVM_EVENT_ENABLE +#define __HAL_PVM_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVM_EXTI_FALLINGTRIGGER_DISABLE +#define __HAL_PVM_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVM_EXTI_FALLINGTRIGGER_ENABLE +#define __HAL_PVM_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVM_EXTI_RISINGTRIGGER_DISABLE +#define __HAL_PVM_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVM_EXTI_RISINGTRIGGER_ENABLE +#define __HAL_PWR_INTERNALWAKEUP_DISABLE HAL_PWREx_DisableInternalWakeUpLine +#define __HAL_PWR_INTERNALWAKEUP_ENABLE HAL_PWREx_EnableInternalWakeUpLine +#define __HAL_PWR_PULL_UP_DOWN_CONFIG_DISABLE HAL_PWREx_DisablePullUpPullDownConfig +#define __HAL_PWR_PULL_UP_DOWN_CONFIG_ENABLE HAL_PWREx_EnablePullUpPullDownConfig +#define __HAL_PWR_PVD_EXTI_CLEAR_EGDE_TRIGGER() \ + do \ + { \ + __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE(); \ + __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); \ + } while (0) +#define __HAL_PWR_PVD_EXTI_EVENT_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_EVENT +#define __HAL_PWR_PVD_EXTI_EVENT_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_EVENT +#define __HAL_PWR_PVD_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE +#define __HAL_PWR_PVD_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PWR_PVD_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_SET_RISING_EDGE_TRIGGER __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PWR_PVM_DISABLE() \ + do \ + { \ + HAL_PWREx_DisablePVM1(); \ + HAL_PWREx_DisablePVM2(); \ + HAL_PWREx_DisablePVM3(); \ + HAL_PWREx_DisablePVM4(); \ + } while (0) +#define __HAL_PWR_PVM_ENABLE() \ + do \ + { \ + HAL_PWREx_EnablePVM1(); \ + HAL_PWREx_EnablePVM2(); \ + HAL_PWREx_EnablePVM3(); \ + HAL_PWREx_EnablePVM4(); \ + } while (0) +#define __HAL_PWR_SRAM2CONTENT_PRESERVE_DISABLE HAL_PWREx_DisableSRAM2ContentRetention +#define __HAL_PWR_SRAM2CONTENT_PRESERVE_ENABLE HAL_PWREx_EnableSRAM2ContentRetention +#define __HAL_PWR_VDDIO2_DISABLE HAL_PWREx_DisableVddIO2 +#define __HAL_PWR_VDDIO2_ENABLE HAL_PWREx_EnableVddIO2 +#define __HAL_PWR_VDDIO2_EXTI_CLEAR_EGDE_TRIGGER \ + __HAL_PWR_VDDIO2_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PWR_VDDIO2_EXTI_SET_FALLING_EGDE_TRIGGER \ + __HAL_PWR_VDDIO2_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_VDDUSB_DISABLE HAL_PWREx_DisableVddUSB +#define __HAL_PWR_VDDUSB_ENABLE HAL_PWREx_EnableVddUSB + +#if defined(STM32F4) +#define __HAL_PVD_EXTI_ENABLE_IT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_ENABLE_IT() +#define __HAL_PVD_EXTI_DISABLE_IT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_DISABLE_IT() +#define __HAL_PVD_EXTI_GET_FLAG(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_GET_FLAG() +#define __HAL_PVD_EXTI_CLEAR_FLAG(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_CLEAR_FLAG() +#define __HAL_PVD_EXTI_GENERATE_SWIT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_GENERATE_SWIT() +#else +#define __HAL_PVD_EXTI_CLEAR_FLAG __HAL_PWR_PVD_EXTI_CLEAR_FLAG +#define __HAL_PVD_EXTI_DISABLE_IT __HAL_PWR_PVD_EXTI_DISABLE_IT +#define __HAL_PVD_EXTI_ENABLE_IT __HAL_PWR_PVD_EXTI_ENABLE_IT +#define __HAL_PVD_EXTI_GENERATE_SWIT __HAL_PWR_PVD_EXTI_GENERATE_SWIT +#define __HAL_PVD_EXTI_GET_FLAG __HAL_PWR_PVD_EXTI_GET_FLAG +#endif /* STM32F4 */ + /** + * @} + */ + + + /** @defgroup HAL_RCC_Aliased HAL RCC Aliased maintained for legacy purpose + * @{ + */ + +#define RCC_StopWakeUpClock_MSI RCC_STOP_WAKEUPCLOCK_MSI +#define RCC_StopWakeUpClock_HSI RCC_STOP_WAKEUPCLOCK_HSI + +#define HAL_RCC_CCSCallback HAL_RCC_CSSCallback +#define HAL_RC48_EnableBuffer_Cmd(cmd) \ + (((cmd) == ENABLE) ? HAL_RCCEx_EnableHSI48_VREFINT() \ + : HAL_RCCEx_DisableHSI48_VREFINT()) + +#define __ADC_CLK_DISABLE __HAL_RCC_ADC_CLK_DISABLE +#define __ADC_CLK_ENABLE __HAL_RCC_ADC_CLK_ENABLE +#define __ADC_CLK_SLEEP_DISABLE __HAL_RCC_ADC_CLK_SLEEP_DISABLE +#define __ADC_CLK_SLEEP_ENABLE __HAL_RCC_ADC_CLK_SLEEP_ENABLE +#define __ADC_FORCE_RESET __HAL_RCC_ADC_FORCE_RESET +#define __ADC_RELEASE_RESET __HAL_RCC_ADC_RELEASE_RESET +#define __ADC1_CLK_DISABLE __HAL_RCC_ADC1_CLK_DISABLE +#define __ADC1_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE +#define __ADC1_FORCE_RESET __HAL_RCC_ADC1_FORCE_RESET +#define __ADC1_RELEASE_RESET __HAL_RCC_ADC1_RELEASE_RESET +#define __ADC1_CLK_SLEEP_ENABLE __HAL_RCC_ADC1_CLK_SLEEP_ENABLE +#define __ADC1_CLK_SLEEP_DISABLE __HAL_RCC_ADC1_CLK_SLEEP_DISABLE +#define __ADC2_CLK_DISABLE __HAL_RCC_ADC2_CLK_DISABLE +#define __ADC2_CLK_ENABLE __HAL_RCC_ADC2_CLK_ENABLE +#define __ADC2_FORCE_RESET __HAL_RCC_ADC2_FORCE_RESET +#define __ADC2_RELEASE_RESET __HAL_RCC_ADC2_RELEASE_RESET +#define __ADC3_CLK_DISABLE __HAL_RCC_ADC3_CLK_DISABLE +#define __ADC3_CLK_ENABLE __HAL_RCC_ADC3_CLK_ENABLE +#define __ADC3_FORCE_RESET __HAL_RCC_ADC3_FORCE_RESET +#define __ADC3_RELEASE_RESET __HAL_RCC_ADC3_RELEASE_RESET +#define __AES_CLK_DISABLE __HAL_RCC_AES_CLK_DISABLE +#define __AES_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE +#define __AES_CLK_SLEEP_DISABLE __HAL_RCC_AES_CLK_SLEEP_DISABLE +#define __AES_CLK_SLEEP_ENABLE __HAL_RCC_AES_CLK_SLEEP_ENABLE +#define __AES_FORCE_RESET __HAL_RCC_AES_FORCE_RESET +#define __AES_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET +#define __CRYP_CLK_SLEEP_ENABLE __HAL_RCC_CRYP_CLK_SLEEP_ENABLE +#define __CRYP_CLK_SLEEP_DISABLE __HAL_RCC_CRYP_CLK_SLEEP_DISABLE +#define __CRYP_CLK_ENABLE __HAL_RCC_CRYP_CLK_ENABLE +#define __CRYP_CLK_DISABLE __HAL_RCC_CRYP_CLK_DISABLE +#define __CRYP_FORCE_RESET __HAL_RCC_CRYP_FORCE_RESET +#define __CRYP_RELEASE_RESET __HAL_RCC_CRYP_RELEASE_RESET +#define __AFIO_CLK_DISABLE __HAL_RCC_AFIO_CLK_DISABLE +#define __AFIO_CLK_ENABLE __HAL_RCC_AFIO_CLK_ENABLE +#define __AFIO_FORCE_RESET __HAL_RCC_AFIO_FORCE_RESET +#define __AFIO_RELEASE_RESET __HAL_RCC_AFIO_RELEASE_RESET +#define __AHB_FORCE_RESET __HAL_RCC_AHB_FORCE_RESET +#define __AHB_RELEASE_RESET __HAL_RCC_AHB_RELEASE_RESET +#define __AHB1_FORCE_RESET __HAL_RCC_AHB1_FORCE_RESET +#define __AHB1_RELEASE_RESET __HAL_RCC_AHB1_RELEASE_RESET +#define __AHB2_FORCE_RESET __HAL_RCC_AHB2_FORCE_RESET +#define __AHB2_RELEASE_RESET __HAL_RCC_AHB2_RELEASE_RESET +#define __AHB3_FORCE_RESET __HAL_RCC_AHB3_FORCE_RESET +#define __AHB3_RELEASE_RESET __HAL_RCC_AHB3_RELEASE_RESET +#define __APB1_FORCE_RESET __HAL_RCC_APB1_FORCE_RESET +#define __APB1_RELEASE_RESET __HAL_RCC_APB1_RELEASE_RESET +#define __APB2_FORCE_RESET __HAL_RCC_APB2_FORCE_RESET +#define __APB2_RELEASE_RESET __HAL_RCC_APB2_RELEASE_RESET +#define __BKP_CLK_DISABLE __HAL_RCC_BKP_CLK_DISABLE +#define __BKP_CLK_ENABLE __HAL_RCC_BKP_CLK_ENABLE +#define __BKP_FORCE_RESET __HAL_RCC_BKP_FORCE_RESET +#define __BKP_RELEASE_RESET __HAL_RCC_BKP_RELEASE_RESET +#define __CAN1_CLK_DISABLE __HAL_RCC_CAN1_CLK_DISABLE +#define __CAN1_CLK_ENABLE __HAL_RCC_CAN1_CLK_ENABLE +#define __CAN1_CLK_SLEEP_DISABLE __HAL_RCC_CAN1_CLK_SLEEP_DISABLE +#define __CAN1_CLK_SLEEP_ENABLE __HAL_RCC_CAN1_CLK_SLEEP_ENABLE +#define __CAN1_FORCE_RESET __HAL_RCC_CAN1_FORCE_RESET +#define __CAN1_RELEASE_RESET __HAL_RCC_CAN1_RELEASE_RESET +#define __CAN_CLK_DISABLE __HAL_RCC_CAN1_CLK_DISABLE +#define __CAN_CLK_ENABLE __HAL_RCC_CAN1_CLK_ENABLE +#define __CAN_FORCE_RESET __HAL_RCC_CAN1_FORCE_RESET +#define __CAN_RELEASE_RESET __HAL_RCC_CAN1_RELEASE_RESET +#define __CAN2_CLK_DISABLE __HAL_RCC_CAN2_CLK_DISABLE +#define __CAN2_CLK_ENABLE __HAL_RCC_CAN2_CLK_ENABLE +#define __CAN2_FORCE_RESET __HAL_RCC_CAN2_FORCE_RESET +#define __CAN2_RELEASE_RESET __HAL_RCC_CAN2_RELEASE_RESET +#define __CEC_CLK_DISABLE __HAL_RCC_CEC_CLK_DISABLE +#define __CEC_CLK_ENABLE __HAL_RCC_CEC_CLK_ENABLE +#define __COMP_CLK_DISABLE __HAL_RCC_COMP_CLK_DISABLE +#define __COMP_CLK_ENABLE __HAL_RCC_COMP_CLK_ENABLE +#define __COMP_FORCE_RESET __HAL_RCC_COMP_FORCE_RESET +#define __COMP_RELEASE_RESET __HAL_RCC_COMP_RELEASE_RESET +#define __COMP_CLK_SLEEP_ENABLE __HAL_RCC_COMP_CLK_SLEEP_ENABLE +#define __COMP_CLK_SLEEP_DISABLE __HAL_RCC_COMP_CLK_SLEEP_DISABLE +#define __CEC_FORCE_RESET __HAL_RCC_CEC_FORCE_RESET +#define __CEC_RELEASE_RESET __HAL_RCC_CEC_RELEASE_RESET +#define __CRC_CLK_DISABLE __HAL_RCC_CRC_CLK_DISABLE +#define __CRC_CLK_ENABLE __HAL_RCC_CRC_CLK_ENABLE +#define __CRC_CLK_SLEEP_DISABLE __HAL_RCC_CRC_CLK_SLEEP_DISABLE +#define __CRC_CLK_SLEEP_ENABLE __HAL_RCC_CRC_CLK_SLEEP_ENABLE +#define __CRC_FORCE_RESET __HAL_RCC_CRC_FORCE_RESET +#define __CRC_RELEASE_RESET __HAL_RCC_CRC_RELEASE_RESET +#define __DAC_CLK_DISABLE __HAL_RCC_DAC_CLK_DISABLE +#define __DAC_CLK_ENABLE __HAL_RCC_DAC_CLK_ENABLE +#define __DAC_FORCE_RESET __HAL_RCC_DAC_FORCE_RESET +#define __DAC_RELEASE_RESET __HAL_RCC_DAC_RELEASE_RESET +#define __DAC1_CLK_DISABLE __HAL_RCC_DAC1_CLK_DISABLE +#define __DAC1_CLK_ENABLE __HAL_RCC_DAC1_CLK_ENABLE +#define __DAC1_CLK_SLEEP_DISABLE __HAL_RCC_DAC1_CLK_SLEEP_DISABLE +#define __DAC1_CLK_SLEEP_ENABLE __HAL_RCC_DAC1_CLK_SLEEP_ENABLE +#define __DAC1_FORCE_RESET __HAL_RCC_DAC1_FORCE_RESET +#define __DAC1_RELEASE_RESET __HAL_RCC_DAC1_RELEASE_RESET +#define __DBGMCU_CLK_ENABLE __HAL_RCC_DBGMCU_CLK_ENABLE +#define __DBGMCU_CLK_DISABLE __HAL_RCC_DBGMCU_CLK_DISABLE +#define __DBGMCU_FORCE_RESET __HAL_RCC_DBGMCU_FORCE_RESET +#define __DBGMCU_RELEASE_RESET __HAL_RCC_DBGMCU_RELEASE_RESET +#define __DFSDM_CLK_DISABLE __HAL_RCC_DFSDM_CLK_DISABLE +#define __DFSDM_CLK_ENABLE __HAL_RCC_DFSDM_CLK_ENABLE +#define __DFSDM_CLK_SLEEP_DISABLE __HAL_RCC_DFSDM_CLK_SLEEP_DISABLE +#define __DFSDM_CLK_SLEEP_ENABLE __HAL_RCC_DFSDM_CLK_SLEEP_ENABLE +#define __DFSDM_FORCE_RESET __HAL_RCC_DFSDM_FORCE_RESET +#define __DFSDM_RELEASE_RESET __HAL_RCC_DFSDM_RELEASE_RESET +#define __DMA1_CLK_DISABLE __HAL_RCC_DMA1_CLK_DISABLE +#define __DMA1_CLK_ENABLE __HAL_RCC_DMA1_CLK_ENABLE +#define __DMA1_CLK_SLEEP_DISABLE __HAL_RCC_DMA1_CLK_SLEEP_DISABLE +#define __DMA1_CLK_SLEEP_ENABLE __HAL_RCC_DMA1_CLK_SLEEP_ENABLE +#define __DMA1_FORCE_RESET __HAL_RCC_DMA1_FORCE_RESET +#define __DMA1_RELEASE_RESET __HAL_RCC_DMA1_RELEASE_RESET +#define __DMA2_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE +#define __DMA2_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE +#define __DMA2_CLK_SLEEP_DISABLE __HAL_RCC_DMA2_CLK_SLEEP_DISABLE +#define __DMA2_CLK_SLEEP_ENABLE __HAL_RCC_DMA2_CLK_SLEEP_ENABLE +#define __DMA2_FORCE_RESET __HAL_RCC_DMA2_FORCE_RESET +#define __DMA2_RELEASE_RESET __HAL_RCC_DMA2_RELEASE_RESET +#define __ETHMAC_CLK_DISABLE __HAL_RCC_ETHMAC_CLK_DISABLE +#define __ETHMAC_CLK_ENABLE __HAL_RCC_ETHMAC_CLK_ENABLE +#define __ETHMAC_FORCE_RESET __HAL_RCC_ETHMAC_FORCE_RESET +#define __ETHMAC_RELEASE_RESET __HAL_RCC_ETHMAC_RELEASE_RESET +#define __ETHMACRX_CLK_DISABLE __HAL_RCC_ETHMACRX_CLK_DISABLE +#define __ETHMACRX_CLK_ENABLE __HAL_RCC_ETHMACRX_CLK_ENABLE +#define __ETHMACTX_CLK_DISABLE __HAL_RCC_ETHMACTX_CLK_DISABLE +#define __ETHMACTX_CLK_ENABLE __HAL_RCC_ETHMACTX_CLK_ENABLE +#define __FIREWALL_CLK_DISABLE __HAL_RCC_FIREWALL_CLK_DISABLE +#define __FIREWALL_CLK_ENABLE __HAL_RCC_FIREWALL_CLK_ENABLE +#define __FLASH_CLK_DISABLE __HAL_RCC_FLASH_CLK_DISABLE +#define __FLASH_CLK_ENABLE __HAL_RCC_FLASH_CLK_ENABLE +#define __FLASH_CLK_SLEEP_DISABLE __HAL_RCC_FLASH_CLK_SLEEP_DISABLE +#define __FLASH_CLK_SLEEP_ENABLE __HAL_RCC_FLASH_CLK_SLEEP_ENABLE +#define __FLASH_FORCE_RESET __HAL_RCC_FLASH_FORCE_RESET +#define __FLASH_RELEASE_RESET __HAL_RCC_FLASH_RELEASE_RESET +#define __FLITF_CLK_DISABLE __HAL_RCC_FLITF_CLK_DISABLE +#define __FLITF_CLK_ENABLE __HAL_RCC_FLITF_CLK_ENABLE +#define __FLITF_FORCE_RESET __HAL_RCC_FLITF_FORCE_RESET +#define __FLITF_RELEASE_RESET __HAL_RCC_FLITF_RELEASE_RESET +#define __FLITF_CLK_SLEEP_ENABLE __HAL_RCC_FLITF_CLK_SLEEP_ENABLE +#define __FLITF_CLK_SLEEP_DISABLE __HAL_RCC_FLITF_CLK_SLEEP_DISABLE +#define __FMC_CLK_DISABLE __HAL_RCC_FMC_CLK_DISABLE +#define __FMC_CLK_ENABLE __HAL_RCC_FMC_CLK_ENABLE +#define __FMC_CLK_SLEEP_DISABLE __HAL_RCC_FMC_CLK_SLEEP_DISABLE +#define __FMC_CLK_SLEEP_ENABLE __HAL_RCC_FMC_CLK_SLEEP_ENABLE +#define __FMC_FORCE_RESET __HAL_RCC_FMC_FORCE_RESET +#define __FMC_RELEASE_RESET __HAL_RCC_FMC_RELEASE_RESET +#define __FSMC_CLK_DISABLE __HAL_RCC_FSMC_CLK_DISABLE +#define __FSMC_CLK_ENABLE __HAL_RCC_FSMC_CLK_ENABLE +#define __GPIOA_CLK_DISABLE __HAL_RCC_GPIOA_CLK_DISABLE +#define __GPIOA_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define __GPIOA_CLK_SLEEP_DISABLE __HAL_RCC_GPIOA_CLK_SLEEP_DISABLE +#define __GPIOA_CLK_SLEEP_ENABLE __HAL_RCC_GPIOA_CLK_SLEEP_ENABLE +#define __GPIOA_FORCE_RESET __HAL_RCC_GPIOA_FORCE_RESET +#define __GPIOA_RELEASE_RESET __HAL_RCC_GPIOA_RELEASE_RESET +#define __GPIOB_CLK_DISABLE __HAL_RCC_GPIOB_CLK_DISABLE +#define __GPIOB_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE +#define __GPIOB_CLK_SLEEP_DISABLE __HAL_RCC_GPIOB_CLK_SLEEP_DISABLE +#define __GPIOB_CLK_SLEEP_ENABLE __HAL_RCC_GPIOB_CLK_SLEEP_ENABLE +#define __GPIOB_FORCE_RESET __HAL_RCC_GPIOB_FORCE_RESET +#define __GPIOB_RELEASE_RESET __HAL_RCC_GPIOB_RELEASE_RESET +#define __GPIOC_CLK_DISABLE __HAL_RCC_GPIOC_CLK_DISABLE +#define __GPIOC_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE +#define __GPIOC_CLK_SLEEP_DISABLE __HAL_RCC_GPIOC_CLK_SLEEP_DISABLE +#define __GPIOC_CLK_SLEEP_ENABLE __HAL_RCC_GPIOC_CLK_SLEEP_ENABLE +#define __GPIOC_FORCE_RESET __HAL_RCC_GPIOC_FORCE_RESET +#define __GPIOC_RELEASE_RESET __HAL_RCC_GPIOC_RELEASE_RESET +#define __GPIOD_CLK_DISABLE __HAL_RCC_GPIOD_CLK_DISABLE +#define __GPIOD_CLK_ENABLE __HAL_RCC_GPIOD_CLK_ENABLE +#define __GPIOD_CLK_SLEEP_DISABLE __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE +#define __GPIOD_CLK_SLEEP_ENABLE __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE +#define __GPIOD_FORCE_RESET __HAL_RCC_GPIOD_FORCE_RESET +#define __GPIOD_RELEASE_RESET __HAL_RCC_GPIOD_RELEASE_RESET +#define __GPIOE_CLK_DISABLE __HAL_RCC_GPIOE_CLK_DISABLE +#define __GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE +#define __GPIOE_CLK_SLEEP_DISABLE __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE +#define __GPIOE_CLK_SLEEP_ENABLE __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE +#define __GPIOE_FORCE_RESET __HAL_RCC_GPIOE_FORCE_RESET +#define __GPIOE_RELEASE_RESET __HAL_RCC_GPIOE_RELEASE_RESET +#define __GPIOF_CLK_DISABLE __HAL_RCC_GPIOF_CLK_DISABLE +#define __GPIOF_CLK_ENABLE __HAL_RCC_GPIOF_CLK_ENABLE +#define __GPIOF_CLK_SLEEP_DISABLE __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE +#define __GPIOF_CLK_SLEEP_ENABLE __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE +#define __GPIOF_FORCE_RESET __HAL_RCC_GPIOF_FORCE_RESET +#define __GPIOF_RELEASE_RESET __HAL_RCC_GPIOF_RELEASE_RESET +#define __GPIOG_CLK_DISABLE __HAL_RCC_GPIOG_CLK_DISABLE +#define __GPIOG_CLK_ENABLE __HAL_RCC_GPIOG_CLK_ENABLE +#define __GPIOG_CLK_SLEEP_DISABLE __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE +#define __GPIOG_CLK_SLEEP_ENABLE __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE +#define __GPIOG_FORCE_RESET __HAL_RCC_GPIOG_FORCE_RESET +#define __GPIOG_RELEASE_RESET __HAL_RCC_GPIOG_RELEASE_RESET +#define __GPIOH_CLK_DISABLE __HAL_RCC_GPIOH_CLK_DISABLE +#define __GPIOH_CLK_ENABLE __HAL_RCC_GPIOH_CLK_ENABLE +#define __GPIOH_CLK_SLEEP_DISABLE __HAL_RCC_GPIOH_CLK_SLEEP_DISABLE +#define __GPIOH_CLK_SLEEP_ENABLE __HAL_RCC_GPIOH_CLK_SLEEP_ENABLE +#define __GPIOH_FORCE_RESET __HAL_RCC_GPIOH_FORCE_RESET +#define __GPIOH_RELEASE_RESET __HAL_RCC_GPIOH_RELEASE_RESET +#define __I2C1_CLK_DISABLE __HAL_RCC_I2C1_CLK_DISABLE +#define __I2C1_CLK_ENABLE __HAL_RCC_I2C1_CLK_ENABLE +#define __I2C1_CLK_SLEEP_DISABLE __HAL_RCC_I2C1_CLK_SLEEP_DISABLE +#define __I2C1_CLK_SLEEP_ENABLE __HAL_RCC_I2C1_CLK_SLEEP_ENABLE +#define __I2C1_FORCE_RESET __HAL_RCC_I2C1_FORCE_RESET +#define __I2C1_RELEASE_RESET __HAL_RCC_I2C1_RELEASE_RESET +#define __I2C2_CLK_DISABLE __HAL_RCC_I2C2_CLK_DISABLE +#define __I2C2_CLK_ENABLE __HAL_RCC_I2C2_CLK_ENABLE +#define __I2C2_CLK_SLEEP_DISABLE __HAL_RCC_I2C2_CLK_SLEEP_DISABLE +#define __I2C2_CLK_SLEEP_ENABLE __HAL_RCC_I2C2_CLK_SLEEP_ENABLE +#define __I2C2_FORCE_RESET __HAL_RCC_I2C2_FORCE_RESET +#define __I2C2_RELEASE_RESET __HAL_RCC_I2C2_RELEASE_RESET +#define __I2C3_CLK_DISABLE __HAL_RCC_I2C3_CLK_DISABLE +#define __I2C3_CLK_ENABLE __HAL_RCC_I2C3_CLK_ENABLE +#define __I2C3_CLK_SLEEP_DISABLE __HAL_RCC_I2C3_CLK_SLEEP_DISABLE +#define __I2C3_CLK_SLEEP_ENABLE __HAL_RCC_I2C3_CLK_SLEEP_ENABLE +#define __I2C3_FORCE_RESET __HAL_RCC_I2C3_FORCE_RESET +#define __I2C3_RELEASE_RESET __HAL_RCC_I2C3_RELEASE_RESET +#define __LCD_CLK_DISABLE __HAL_RCC_LCD_CLK_DISABLE +#define __LCD_CLK_ENABLE __HAL_RCC_LCD_CLK_ENABLE +#define __LCD_CLK_SLEEP_DISABLE __HAL_RCC_LCD_CLK_SLEEP_DISABLE +#define __LCD_CLK_SLEEP_ENABLE __HAL_RCC_LCD_CLK_SLEEP_ENABLE +#define __LCD_FORCE_RESET __HAL_RCC_LCD_FORCE_RESET +#define __LCD_RELEASE_RESET __HAL_RCC_LCD_RELEASE_RESET +#define __LPTIM1_CLK_DISABLE __HAL_RCC_LPTIM1_CLK_DISABLE +#define __LPTIM1_CLK_ENABLE __HAL_RCC_LPTIM1_CLK_ENABLE +#define __LPTIM1_CLK_SLEEP_DISABLE __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE +#define __LPTIM1_CLK_SLEEP_ENABLE __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE +#define __LPTIM1_FORCE_RESET __HAL_RCC_LPTIM1_FORCE_RESET +#define __LPTIM1_RELEASE_RESET __HAL_RCC_LPTIM1_RELEASE_RESET +#define __LPTIM2_CLK_DISABLE __HAL_RCC_LPTIM2_CLK_DISABLE +#define __LPTIM2_CLK_ENABLE __HAL_RCC_LPTIM2_CLK_ENABLE +#define __LPTIM2_CLK_SLEEP_DISABLE __HAL_RCC_LPTIM2_CLK_SLEEP_DISABLE +#define __LPTIM2_CLK_SLEEP_ENABLE __HAL_RCC_LPTIM2_CLK_SLEEP_ENABLE +#define __LPTIM2_FORCE_RESET __HAL_RCC_LPTIM2_FORCE_RESET +#define __LPTIM2_RELEASE_RESET __HAL_RCC_LPTIM2_RELEASE_RESET +#define __LPUART1_CLK_DISABLE __HAL_RCC_LPUART1_CLK_DISABLE +#define __LPUART1_CLK_ENABLE __HAL_RCC_LPUART1_CLK_ENABLE +#define __LPUART1_CLK_SLEEP_DISABLE __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE +#define __LPUART1_CLK_SLEEP_ENABLE __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE +#define __LPUART1_FORCE_RESET __HAL_RCC_LPUART1_FORCE_RESET +#define __LPUART1_RELEASE_RESET __HAL_RCC_LPUART1_RELEASE_RESET +#define __OPAMP_CLK_DISABLE __HAL_RCC_OPAMP_CLK_DISABLE +#define __OPAMP_CLK_ENABLE __HAL_RCC_OPAMP_CLK_ENABLE +#define __OPAMP_CLK_SLEEP_DISABLE __HAL_RCC_OPAMP_CLK_SLEEP_DISABLE +#define __OPAMP_CLK_SLEEP_ENABLE __HAL_RCC_OPAMP_CLK_SLEEP_ENABLE +#define __OPAMP_FORCE_RESET __HAL_RCC_OPAMP_FORCE_RESET +#define __OPAMP_RELEASE_RESET __HAL_RCC_OPAMP_RELEASE_RESET +#define __OTGFS_CLK_DISABLE __HAL_RCC_OTGFS_CLK_DISABLE +#define __OTGFS_CLK_ENABLE __HAL_RCC_OTGFS_CLK_ENABLE +#define __OTGFS_CLK_SLEEP_DISABLE __HAL_RCC_OTGFS_CLK_SLEEP_DISABLE +#define __OTGFS_CLK_SLEEP_ENABLE __HAL_RCC_OTGFS_CLK_SLEEP_ENABLE +#define __OTGFS_FORCE_RESET __HAL_RCC_OTGFS_FORCE_RESET +#define __OTGFS_RELEASE_RESET __HAL_RCC_OTGFS_RELEASE_RESET +#define __PWR_CLK_DISABLE __HAL_RCC_PWR_CLK_DISABLE +#define __PWR_CLK_ENABLE __HAL_RCC_PWR_CLK_ENABLE +#define __PWR_CLK_SLEEP_DISABLE __HAL_RCC_PWR_CLK_SLEEP_DISABLE +#define __PWR_CLK_SLEEP_ENABLE __HAL_RCC_PWR_CLK_SLEEP_ENABLE +#define __PWR_FORCE_RESET __HAL_RCC_PWR_FORCE_RESET +#define __PWR_RELEASE_RESET __HAL_RCC_PWR_RELEASE_RESET +#define __QSPI_CLK_DISABLE __HAL_RCC_QSPI_CLK_DISABLE +#define __QSPI_CLK_ENABLE __HAL_RCC_QSPI_CLK_ENABLE +#define __QSPI_CLK_SLEEP_DISABLE __HAL_RCC_QSPI_CLK_SLEEP_DISABLE +#define __QSPI_CLK_SLEEP_ENABLE __HAL_RCC_QSPI_CLK_SLEEP_ENABLE +#define __QSPI_FORCE_RESET __HAL_RCC_QSPI_FORCE_RESET +#define __QSPI_RELEASE_RESET __HAL_RCC_QSPI_RELEASE_RESET + +#if defined(STM32WB) +#define __HAL_RCC_QSPI_CLK_DISABLE __HAL_RCC_QUADSPI_CLK_DISABLE +#define __HAL_RCC_QSPI_CLK_ENABLE __HAL_RCC_QUADSPI_CLK_ENABLE +#define __HAL_RCC_QSPI_CLK_SLEEP_DISABLE __HAL_RCC_QUADSPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_QSPI_CLK_SLEEP_ENABLE __HAL_RCC_QUADSPI_CLK_SLEEP_ENABLE +#define __HAL_RCC_QSPI_FORCE_RESET __HAL_RCC_QUADSPI_FORCE_RESET +#define __HAL_RCC_QSPI_RELEASE_RESET __HAL_RCC_QUADSPI_RELEASE_RESET +#define __HAL_RCC_QSPI_IS_CLK_ENABLED __HAL_RCC_QUADSPI_IS_CLK_ENABLED +#define __HAL_RCC_QSPI_IS_CLK_DISABLED __HAL_RCC_QUADSPI_IS_CLK_DISABLED +#define __HAL_RCC_QSPI_IS_CLK_SLEEP_ENABLED __HAL_RCC_QUADSPI_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_QSPI_IS_CLK_SLEEP_DISABLED __HAL_RCC_QUADSPI_IS_CLK_SLEEP_DISABLED +#define QSPI_IRQHandler QUADSPI_IRQHandler +#endif /* __HAL_RCC_QUADSPI_CLK_ENABLE */ + +#define __RNG_CLK_DISABLE __HAL_RCC_RNG_CLK_DISABLE +#define __RNG_CLK_ENABLE __HAL_RCC_RNG_CLK_ENABLE +#define __RNG_CLK_SLEEP_DISABLE __HAL_RCC_RNG_CLK_SLEEP_DISABLE +#define __RNG_CLK_SLEEP_ENABLE __HAL_RCC_RNG_CLK_SLEEP_ENABLE +#define __RNG_FORCE_RESET __HAL_RCC_RNG_FORCE_RESET +#define __RNG_RELEASE_RESET __HAL_RCC_RNG_RELEASE_RESET +#define __SAI1_CLK_DISABLE __HAL_RCC_SAI1_CLK_DISABLE +#define __SAI1_CLK_ENABLE __HAL_RCC_SAI1_CLK_ENABLE +#define __SAI1_CLK_SLEEP_DISABLE __HAL_RCC_SAI1_CLK_SLEEP_DISABLE +#define __SAI1_CLK_SLEEP_ENABLE __HAL_RCC_SAI1_CLK_SLEEP_ENABLE +#define __SAI1_FORCE_RESET __HAL_RCC_SAI1_FORCE_RESET +#define __SAI1_RELEASE_RESET __HAL_RCC_SAI1_RELEASE_RESET +#define __SAI2_CLK_DISABLE __HAL_RCC_SAI2_CLK_DISABLE +#define __SAI2_CLK_ENABLE __HAL_RCC_SAI2_CLK_ENABLE +#define __SAI2_CLK_SLEEP_DISABLE __HAL_RCC_SAI2_CLK_SLEEP_DISABLE +#define __SAI2_CLK_SLEEP_ENABLE __HAL_RCC_SAI2_CLK_SLEEP_ENABLE +#define __SAI2_FORCE_RESET __HAL_RCC_SAI2_FORCE_RESET +#define __SAI2_RELEASE_RESET __HAL_RCC_SAI2_RELEASE_RESET +#define __SDIO_CLK_DISABLE __HAL_RCC_SDIO_CLK_DISABLE +#define __SDIO_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __SDMMC_CLK_DISABLE __HAL_RCC_SDMMC_CLK_DISABLE +#define __SDMMC_CLK_ENABLE __HAL_RCC_SDMMC_CLK_ENABLE +#define __SDMMC_CLK_SLEEP_DISABLE __HAL_RCC_SDMMC_CLK_SLEEP_DISABLE +#define __SDMMC_CLK_SLEEP_ENABLE __HAL_RCC_SDMMC_CLK_SLEEP_ENABLE +#define __SDMMC_FORCE_RESET __HAL_RCC_SDMMC_FORCE_RESET +#define __SDMMC_RELEASE_RESET __HAL_RCC_SDMMC_RELEASE_RESET +#define __SPI1_CLK_DISABLE __HAL_RCC_SPI1_CLK_DISABLE +#define __SPI1_CLK_ENABLE __HAL_RCC_SPI1_CLK_ENABLE +#define __SPI1_CLK_SLEEP_DISABLE __HAL_RCC_SPI1_CLK_SLEEP_DISABLE +#define __SPI1_CLK_SLEEP_ENABLE __HAL_RCC_SPI1_CLK_SLEEP_ENABLE +#define __SPI1_FORCE_RESET __HAL_RCC_SPI1_FORCE_RESET +#define __SPI1_RELEASE_RESET __HAL_RCC_SPI1_RELEASE_RESET +#define __SPI2_CLK_DISABLE __HAL_RCC_SPI2_CLK_DISABLE +#define __SPI2_CLK_ENABLE __HAL_RCC_SPI2_CLK_ENABLE +#define __SPI2_CLK_SLEEP_DISABLE __HAL_RCC_SPI2_CLK_SLEEP_DISABLE +#define __SPI2_CLK_SLEEP_ENABLE __HAL_RCC_SPI2_CLK_SLEEP_ENABLE +#define __SPI2_FORCE_RESET __HAL_RCC_SPI2_FORCE_RESET +#define __SPI2_RELEASE_RESET __HAL_RCC_SPI2_RELEASE_RESET +#define __SPI3_CLK_DISABLE __HAL_RCC_SPI3_CLK_DISABLE +#define __SPI3_CLK_ENABLE __HAL_RCC_SPI3_CLK_ENABLE +#define __SPI3_CLK_SLEEP_DISABLE __HAL_RCC_SPI3_CLK_SLEEP_DISABLE +#define __SPI3_CLK_SLEEP_ENABLE __HAL_RCC_SPI3_CLK_SLEEP_ENABLE +#define __SPI3_FORCE_RESET __HAL_RCC_SPI3_FORCE_RESET +#define __SPI3_RELEASE_RESET __HAL_RCC_SPI3_RELEASE_RESET +#define __SRAM_CLK_DISABLE __HAL_RCC_SRAM_CLK_DISABLE +#define __SRAM_CLK_ENABLE __HAL_RCC_SRAM_CLK_ENABLE +#define __SRAM1_CLK_SLEEP_DISABLE __HAL_RCC_SRAM1_CLK_SLEEP_DISABLE +#define __SRAM1_CLK_SLEEP_ENABLE __HAL_RCC_SRAM1_CLK_SLEEP_ENABLE +#define __SRAM2_CLK_SLEEP_DISABLE __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE +#define __SRAM2_CLK_SLEEP_ENABLE __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE +#define __SWPMI1_CLK_DISABLE __HAL_RCC_SWPMI1_CLK_DISABLE +#define __SWPMI1_CLK_ENABLE __HAL_RCC_SWPMI1_CLK_ENABLE +#define __SWPMI1_CLK_SLEEP_DISABLE __HAL_RCC_SWPMI1_CLK_SLEEP_DISABLE +#define __SWPMI1_CLK_SLEEP_ENABLE __HAL_RCC_SWPMI1_CLK_SLEEP_ENABLE +#define __SWPMI1_FORCE_RESET __HAL_RCC_SWPMI1_FORCE_RESET +#define __SWPMI1_RELEASE_RESET __HAL_RCC_SWPMI1_RELEASE_RESET +#define __SYSCFG_CLK_DISABLE __HAL_RCC_SYSCFG_CLK_DISABLE +#define __SYSCFG_CLK_ENABLE __HAL_RCC_SYSCFG_CLK_ENABLE +#define __SYSCFG_CLK_SLEEP_DISABLE __HAL_RCC_SYSCFG_CLK_SLEEP_DISABLE +#define __SYSCFG_CLK_SLEEP_ENABLE __HAL_RCC_SYSCFG_CLK_SLEEP_ENABLE +#define __SYSCFG_FORCE_RESET __HAL_RCC_SYSCFG_FORCE_RESET +#define __SYSCFG_RELEASE_RESET __HAL_RCC_SYSCFG_RELEASE_RESET +#define __TIM1_CLK_DISABLE __HAL_RCC_TIM1_CLK_DISABLE +#define __TIM1_CLK_ENABLE __HAL_RCC_TIM1_CLK_ENABLE +#define __TIM1_CLK_SLEEP_DISABLE __HAL_RCC_TIM1_CLK_SLEEP_DISABLE +#define __TIM1_CLK_SLEEP_ENABLE __HAL_RCC_TIM1_CLK_SLEEP_ENABLE +#define __TIM1_FORCE_RESET __HAL_RCC_TIM1_FORCE_RESET +#define __TIM1_RELEASE_RESET __HAL_RCC_TIM1_RELEASE_RESET +#define __TIM10_CLK_DISABLE __HAL_RCC_TIM10_CLK_DISABLE +#define __TIM10_CLK_ENABLE __HAL_RCC_TIM10_CLK_ENABLE +#define __TIM10_FORCE_RESET __HAL_RCC_TIM10_FORCE_RESET +#define __TIM10_RELEASE_RESET __HAL_RCC_TIM10_RELEASE_RESET +#define __TIM11_CLK_DISABLE __HAL_RCC_TIM11_CLK_DISABLE +#define __TIM11_CLK_ENABLE __HAL_RCC_TIM11_CLK_ENABLE +#define __TIM11_FORCE_RESET __HAL_RCC_TIM11_FORCE_RESET +#define __TIM11_RELEASE_RESET __HAL_RCC_TIM11_RELEASE_RESET +#define __TIM12_CLK_DISABLE __HAL_RCC_TIM12_CLK_DISABLE +#define __TIM12_CLK_ENABLE __HAL_RCC_TIM12_CLK_ENABLE +#define __TIM12_FORCE_RESET __HAL_RCC_TIM12_FORCE_RESET +#define __TIM12_RELEASE_RESET __HAL_RCC_TIM12_RELEASE_RESET +#define __TIM13_CLK_DISABLE __HAL_RCC_TIM13_CLK_DISABLE +#define __TIM13_CLK_ENABLE __HAL_RCC_TIM13_CLK_ENABLE +#define __TIM13_FORCE_RESET __HAL_RCC_TIM13_FORCE_RESET +#define __TIM13_RELEASE_RESET __HAL_RCC_TIM13_RELEASE_RESET +#define __TIM14_CLK_DISABLE __HAL_RCC_TIM14_CLK_DISABLE +#define __TIM14_CLK_ENABLE __HAL_RCC_TIM14_CLK_ENABLE +#define __TIM14_FORCE_RESET __HAL_RCC_TIM14_FORCE_RESET +#define __TIM14_RELEASE_RESET __HAL_RCC_TIM14_RELEASE_RESET +#define __TIM15_CLK_DISABLE __HAL_RCC_TIM15_CLK_DISABLE +#define __TIM15_CLK_ENABLE __HAL_RCC_TIM15_CLK_ENABLE +#define __TIM15_CLK_SLEEP_DISABLE __HAL_RCC_TIM15_CLK_SLEEP_DISABLE +#define __TIM15_CLK_SLEEP_ENABLE __HAL_RCC_TIM15_CLK_SLEEP_ENABLE +#define __TIM15_FORCE_RESET __HAL_RCC_TIM15_FORCE_RESET +#define __TIM15_RELEASE_RESET __HAL_RCC_TIM15_RELEASE_RESET +#define __TIM16_CLK_DISABLE __HAL_RCC_TIM16_CLK_DISABLE +#define __TIM16_CLK_ENABLE __HAL_RCC_TIM16_CLK_ENABLE +#define __TIM16_CLK_SLEEP_DISABLE __HAL_RCC_TIM16_CLK_SLEEP_DISABLE +#define __TIM16_CLK_SLEEP_ENABLE __HAL_RCC_TIM16_CLK_SLEEP_ENABLE +#define __TIM16_FORCE_RESET __HAL_RCC_TIM16_FORCE_RESET +#define __TIM16_RELEASE_RESET __HAL_RCC_TIM16_RELEASE_RESET +#define __TIM17_CLK_DISABLE __HAL_RCC_TIM17_CLK_DISABLE +#define __TIM17_CLK_ENABLE __HAL_RCC_TIM17_CLK_ENABLE +#define __TIM17_CLK_SLEEP_DISABLE __HAL_RCC_TIM17_CLK_SLEEP_DISABLE +#define __TIM17_CLK_SLEEP_ENABLE __HAL_RCC_TIM17_CLK_SLEEP_ENABLE +#define __TIM17_FORCE_RESET __HAL_RCC_TIM17_FORCE_RESET +#define __TIM17_RELEASE_RESET __HAL_RCC_TIM17_RELEASE_RESET +#define __TIM2_CLK_DISABLE __HAL_RCC_TIM2_CLK_DISABLE +#define __TIM2_CLK_ENABLE __HAL_RCC_TIM2_CLK_ENABLE +#define __TIM2_CLK_SLEEP_DISABLE __HAL_RCC_TIM2_CLK_SLEEP_DISABLE +#define __TIM2_CLK_SLEEP_ENABLE __HAL_RCC_TIM2_CLK_SLEEP_ENABLE +#define __TIM2_FORCE_RESET __HAL_RCC_TIM2_FORCE_RESET +#define __TIM2_RELEASE_RESET __HAL_RCC_TIM2_RELEASE_RESET +#define __TIM3_CLK_DISABLE __HAL_RCC_TIM3_CLK_DISABLE +#define __TIM3_CLK_ENABLE __HAL_RCC_TIM3_CLK_ENABLE +#define __TIM3_CLK_SLEEP_DISABLE __HAL_RCC_TIM3_CLK_SLEEP_DISABLE +#define __TIM3_CLK_SLEEP_ENABLE __HAL_RCC_TIM3_CLK_SLEEP_ENABLE +#define __TIM3_FORCE_RESET __HAL_RCC_TIM3_FORCE_RESET +#define __TIM3_RELEASE_RESET __HAL_RCC_TIM3_RELEASE_RESET +#define __TIM4_CLK_DISABLE __HAL_RCC_TIM4_CLK_DISABLE +#define __TIM4_CLK_ENABLE __HAL_RCC_TIM4_CLK_ENABLE +#define __TIM4_CLK_SLEEP_DISABLE __HAL_RCC_TIM4_CLK_SLEEP_DISABLE +#define __TIM4_CLK_SLEEP_ENABLE __HAL_RCC_TIM4_CLK_SLEEP_ENABLE +#define __TIM4_FORCE_RESET __HAL_RCC_TIM4_FORCE_RESET +#define __TIM4_RELEASE_RESET __HAL_RCC_TIM4_RELEASE_RESET +#define __TIM5_CLK_DISABLE __HAL_RCC_TIM5_CLK_DISABLE +#define __TIM5_CLK_ENABLE __HAL_RCC_TIM5_CLK_ENABLE +#define __TIM5_CLK_SLEEP_DISABLE __HAL_RCC_TIM5_CLK_SLEEP_DISABLE +#define __TIM5_CLK_SLEEP_ENABLE __HAL_RCC_TIM5_CLK_SLEEP_ENABLE +#define __TIM5_FORCE_RESET __HAL_RCC_TIM5_FORCE_RESET +#define __TIM5_RELEASE_RESET __HAL_RCC_TIM5_RELEASE_RESET +#define __TIM6_CLK_DISABLE __HAL_RCC_TIM6_CLK_DISABLE +#define __TIM6_CLK_ENABLE __HAL_RCC_TIM6_CLK_ENABLE +#define __TIM6_CLK_SLEEP_DISABLE __HAL_RCC_TIM6_CLK_SLEEP_DISABLE +#define __TIM6_CLK_SLEEP_ENABLE __HAL_RCC_TIM6_CLK_SLEEP_ENABLE +#define __TIM6_FORCE_RESET __HAL_RCC_TIM6_FORCE_RESET +#define __TIM6_RELEASE_RESET __HAL_RCC_TIM6_RELEASE_RESET +#define __TIM7_CLK_DISABLE __HAL_RCC_TIM7_CLK_DISABLE +#define __TIM7_CLK_ENABLE __HAL_RCC_TIM7_CLK_ENABLE +#define __TIM7_CLK_SLEEP_DISABLE __HAL_RCC_TIM7_CLK_SLEEP_DISABLE +#define __TIM7_CLK_SLEEP_ENABLE __HAL_RCC_TIM7_CLK_SLEEP_ENABLE +#define __TIM7_FORCE_RESET __HAL_RCC_TIM7_FORCE_RESET +#define __TIM7_RELEASE_RESET __HAL_RCC_TIM7_RELEASE_RESET +#define __TIM8_CLK_DISABLE __HAL_RCC_TIM8_CLK_DISABLE +#define __TIM8_CLK_ENABLE __HAL_RCC_TIM8_CLK_ENABLE +#define __TIM8_CLK_SLEEP_DISABLE __HAL_RCC_TIM8_CLK_SLEEP_DISABLE +#define __TIM8_CLK_SLEEP_ENABLE __HAL_RCC_TIM8_CLK_SLEEP_ENABLE +#define __TIM8_FORCE_RESET __HAL_RCC_TIM8_FORCE_RESET +#define __TIM8_RELEASE_RESET __HAL_RCC_TIM8_RELEASE_RESET +#define __TIM9_CLK_DISABLE __HAL_RCC_TIM9_CLK_DISABLE +#define __TIM9_CLK_ENABLE __HAL_RCC_TIM9_CLK_ENABLE +#define __TIM9_FORCE_RESET __HAL_RCC_TIM9_FORCE_RESET +#define __TIM9_RELEASE_RESET __HAL_RCC_TIM9_RELEASE_RESET +#define __TSC_CLK_DISABLE __HAL_RCC_TSC_CLK_DISABLE +#define __TSC_CLK_ENABLE __HAL_RCC_TSC_CLK_ENABLE +#define __TSC_CLK_SLEEP_DISABLE __HAL_RCC_TSC_CLK_SLEEP_DISABLE +#define __TSC_CLK_SLEEP_ENABLE __HAL_RCC_TSC_CLK_SLEEP_ENABLE +#define __TSC_FORCE_RESET __HAL_RCC_TSC_FORCE_RESET +#define __TSC_RELEASE_RESET __HAL_RCC_TSC_RELEASE_RESET +#define __UART4_CLK_DISABLE __HAL_RCC_UART4_CLK_DISABLE +#define __UART4_CLK_ENABLE __HAL_RCC_UART4_CLK_ENABLE +#define __UART4_CLK_SLEEP_DISABLE __HAL_RCC_UART4_CLK_SLEEP_DISABLE +#define __UART4_CLK_SLEEP_ENABLE __HAL_RCC_UART4_CLK_SLEEP_ENABLE +#define __UART4_FORCE_RESET __HAL_RCC_UART4_FORCE_RESET +#define __UART4_RELEASE_RESET __HAL_RCC_UART4_RELEASE_RESET +#define __UART5_CLK_DISABLE __HAL_RCC_UART5_CLK_DISABLE +#define __UART5_CLK_ENABLE __HAL_RCC_UART5_CLK_ENABLE +#define __UART5_CLK_SLEEP_DISABLE __HAL_RCC_UART5_CLK_SLEEP_DISABLE +#define __UART5_CLK_SLEEP_ENABLE __HAL_RCC_UART5_CLK_SLEEP_ENABLE +#define __UART5_FORCE_RESET __HAL_RCC_UART5_FORCE_RESET +#define __UART5_RELEASE_RESET __HAL_RCC_UART5_RELEASE_RESET +#define __USART1_CLK_DISABLE __HAL_RCC_USART1_CLK_DISABLE +#define __USART1_CLK_ENABLE __HAL_RCC_USART1_CLK_ENABLE +#define __USART1_CLK_SLEEP_DISABLE __HAL_RCC_USART1_CLK_SLEEP_DISABLE +#define __USART1_CLK_SLEEP_ENABLE __HAL_RCC_USART1_CLK_SLEEP_ENABLE +#define __USART1_FORCE_RESET __HAL_RCC_USART1_FORCE_RESET +#define __USART1_RELEASE_RESET __HAL_RCC_USART1_RELEASE_RESET +#define __USART2_CLK_DISABLE __HAL_RCC_USART2_CLK_DISABLE +#define __USART2_CLK_ENABLE __HAL_RCC_USART2_CLK_ENABLE +#define __USART2_CLK_SLEEP_DISABLE __HAL_RCC_USART2_CLK_SLEEP_DISABLE +#define __USART2_CLK_SLEEP_ENABLE __HAL_RCC_USART2_CLK_SLEEP_ENABLE +#define __USART2_FORCE_RESET __HAL_RCC_USART2_FORCE_RESET +#define __USART2_RELEASE_RESET __HAL_RCC_USART2_RELEASE_RESET +#define __USART3_CLK_DISABLE __HAL_RCC_USART3_CLK_DISABLE +#define __USART3_CLK_ENABLE __HAL_RCC_USART3_CLK_ENABLE +#define __USART3_CLK_SLEEP_DISABLE __HAL_RCC_USART3_CLK_SLEEP_DISABLE +#define __USART3_CLK_SLEEP_ENABLE __HAL_RCC_USART3_CLK_SLEEP_ENABLE +#define __USART3_FORCE_RESET __HAL_RCC_USART3_FORCE_RESET +#define __USART3_RELEASE_RESET __HAL_RCC_USART3_RELEASE_RESET +#define __USART4_CLK_DISABLE __HAL_RCC_UART4_CLK_DISABLE +#define __USART4_CLK_ENABLE __HAL_RCC_UART4_CLK_ENABLE +#define __USART4_CLK_SLEEP_ENABLE __HAL_RCC_UART4_CLK_SLEEP_ENABLE +#define __USART4_CLK_SLEEP_DISABLE __HAL_RCC_UART4_CLK_SLEEP_DISABLE +#define __USART4_FORCE_RESET __HAL_RCC_UART4_FORCE_RESET +#define __USART4_RELEASE_RESET __HAL_RCC_UART4_RELEASE_RESET +#define __USART5_CLK_DISABLE __HAL_RCC_UART5_CLK_DISABLE +#define __USART5_CLK_ENABLE __HAL_RCC_UART5_CLK_ENABLE +#define __USART5_CLK_SLEEP_ENABLE __HAL_RCC_UART5_CLK_SLEEP_ENABLE +#define __USART5_CLK_SLEEP_DISABLE __HAL_RCC_UART5_CLK_SLEEP_DISABLE +#define __USART5_FORCE_RESET __HAL_RCC_UART5_FORCE_RESET +#define __USART5_RELEASE_RESET __HAL_RCC_UART5_RELEASE_RESET +#define __USART7_CLK_DISABLE __HAL_RCC_UART7_CLK_DISABLE +#define __USART7_CLK_ENABLE __HAL_RCC_UART7_CLK_ENABLE +#define __USART7_FORCE_RESET __HAL_RCC_UART7_FORCE_RESET +#define __USART7_RELEASE_RESET __HAL_RCC_UART7_RELEASE_RESET +#define __USART8_CLK_DISABLE __HAL_RCC_UART8_CLK_DISABLE +#define __USART8_CLK_ENABLE __HAL_RCC_UART8_CLK_ENABLE +#define __USART8_FORCE_RESET __HAL_RCC_UART8_FORCE_RESET +#define __USART8_RELEASE_RESET __HAL_RCC_UART8_RELEASE_RESET +#define __USB_CLK_DISABLE __HAL_RCC_USB_CLK_DISABLE +#define __USB_CLK_ENABLE __HAL_RCC_USB_CLK_ENABLE +#define __USB_FORCE_RESET __HAL_RCC_USB_FORCE_RESET +#define __USB_CLK_SLEEP_ENABLE __HAL_RCC_USB_CLK_SLEEP_ENABLE +#define __USB_CLK_SLEEP_DISABLE __HAL_RCC_USB_CLK_SLEEP_DISABLE +#define __USB_OTG_FS_CLK_DISABLE __HAL_RCC_USB_OTG_FS_CLK_DISABLE +#define __USB_OTG_FS_CLK_ENABLE __HAL_RCC_USB_OTG_FS_CLK_ENABLE +#define __USB_RELEASE_RESET __HAL_RCC_USB_RELEASE_RESET + +#if defined(STM32H7) +#define __HAL_RCC_WWDG_CLK_DISABLE __HAL_RCC_WWDG1_CLK_DISABLE +#define __HAL_RCC_WWDG_CLK_ENABLE __HAL_RCC_WWDG1_CLK_ENABLE +#define __HAL_RCC_WWDG_CLK_SLEEP_DISABLE __HAL_RCC_WWDG1_CLK_SLEEP_DISABLE +#define __HAL_RCC_WWDG_CLK_SLEEP_ENABLE __HAL_RCC_WWDG1_CLK_SLEEP_ENABLE + +#define __HAL_RCC_WWDG_FORCE_RESET ((void)0U) /* Not available on the STM32H7*/ +#define __HAL_RCC_WWDG_RELEASE_RESET ((void)0U) /* Not available on the STM32H7*/ + + +#define __HAL_RCC_WWDG_IS_CLK_ENABLED __HAL_RCC_WWDG1_IS_CLK_ENABLED +#define __HAL_RCC_WWDG_IS_CLK_DISABLED __HAL_RCC_WWDG1_IS_CLK_DISABLED +#define RCC_SPI4CLKSOURCE_D2PCLK1 RCC_SPI4CLKSOURCE_D2PCLK2 +#define RCC_SPI5CLKSOURCE_D2PCLK1 RCC_SPI5CLKSOURCE_D2PCLK2 +#define RCC_SPI45CLKSOURCE_D2PCLK1 RCC_SPI45CLKSOURCE_D2PCLK2 +#define RCC_SPI45CLKSOURCE_CDPCLK1 RCC_SPI45CLKSOURCE_CDPCLK2 +#define RCC_SPI45CLKSOURCE_PCLK1 RCC_SPI45CLKSOURCE_PCLK2 +#endif + +#define __WWDG_CLK_DISABLE __HAL_RCC_WWDG_CLK_DISABLE +#define __WWDG_CLK_ENABLE __HAL_RCC_WWDG_CLK_ENABLE +#define __WWDG_CLK_SLEEP_DISABLE __HAL_RCC_WWDG_CLK_SLEEP_DISABLE +#define __WWDG_CLK_SLEEP_ENABLE __HAL_RCC_WWDG_CLK_SLEEP_ENABLE +#define __WWDG_FORCE_RESET __HAL_RCC_WWDG_FORCE_RESET +#define __WWDG_RELEASE_RESET __HAL_RCC_WWDG_RELEASE_RESET + +#define __TIM21_CLK_ENABLE __HAL_RCC_TIM21_CLK_ENABLE +#define __TIM21_CLK_DISABLE __HAL_RCC_TIM21_CLK_DISABLE +#define __TIM21_FORCE_RESET __HAL_RCC_TIM21_FORCE_RESET +#define __TIM21_RELEASE_RESET __HAL_RCC_TIM21_RELEASE_RESET +#define __TIM21_CLK_SLEEP_ENABLE __HAL_RCC_TIM21_CLK_SLEEP_ENABLE +#define __TIM21_CLK_SLEEP_DISABLE __HAL_RCC_TIM21_CLK_SLEEP_DISABLE +#define __TIM22_CLK_ENABLE __HAL_RCC_TIM22_CLK_ENABLE +#define __TIM22_CLK_DISABLE __HAL_RCC_TIM22_CLK_DISABLE +#define __TIM22_FORCE_RESET __HAL_RCC_TIM22_FORCE_RESET +#define __TIM22_RELEASE_RESET __HAL_RCC_TIM22_RELEASE_RESET +#define __TIM22_CLK_SLEEP_ENABLE __HAL_RCC_TIM22_CLK_SLEEP_ENABLE +#define __TIM22_CLK_SLEEP_DISABLE __HAL_RCC_TIM22_CLK_SLEEP_DISABLE +#define __CRS_CLK_DISABLE __HAL_RCC_CRS_CLK_DISABLE +#define __CRS_CLK_ENABLE __HAL_RCC_CRS_CLK_ENABLE +#define __CRS_CLK_SLEEP_DISABLE __HAL_RCC_CRS_CLK_SLEEP_DISABLE +#define __CRS_CLK_SLEEP_ENABLE __HAL_RCC_CRS_CLK_SLEEP_ENABLE +#define __CRS_FORCE_RESET __HAL_RCC_CRS_FORCE_RESET +#define __CRS_RELEASE_RESET __HAL_RCC_CRS_RELEASE_RESET +#define __RCC_BACKUPRESET_FORCE __HAL_RCC_BACKUPRESET_FORCE +#define __RCC_BACKUPRESET_RELEASE __HAL_RCC_BACKUPRESET_RELEASE + +#define __USB_OTG_FS_FORCE_RESET __HAL_RCC_USB_OTG_FS_FORCE_RESET +#define __USB_OTG_FS_RELEASE_RESET __HAL_RCC_USB_OTG_FS_RELEASE_RESET +#define __USB_OTG_FS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE +#define __USB_OTG_FS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE +#define __USB_OTG_HS_CLK_DISABLE __HAL_RCC_USB_OTG_HS_CLK_DISABLE +#define __USB_OTG_HS_CLK_ENABLE __HAL_RCC_USB_OTG_HS_CLK_ENABLE +#define __USB_OTG_HS_ULPI_CLK_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE +#define __USB_OTG_HS_ULPI_CLK_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE +#define __TIM9_CLK_SLEEP_ENABLE __HAL_RCC_TIM9_CLK_SLEEP_ENABLE +#define __TIM9_CLK_SLEEP_DISABLE __HAL_RCC_TIM9_CLK_SLEEP_DISABLE +#define __TIM10_CLK_SLEEP_ENABLE __HAL_RCC_TIM10_CLK_SLEEP_ENABLE +#define __TIM10_CLK_SLEEP_DISABLE __HAL_RCC_TIM10_CLK_SLEEP_DISABLE +#define __TIM11_CLK_SLEEP_ENABLE __HAL_RCC_TIM11_CLK_SLEEP_ENABLE +#define __TIM11_CLK_SLEEP_DISABLE __HAL_RCC_TIM11_CLK_SLEEP_DISABLE +#define __ETHMACPTP_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACPTP_CLK_SLEEP_ENABLE +#define __ETHMACPTP_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACPTP_CLK_SLEEP_DISABLE +#define __ETHMACPTP_CLK_ENABLE __HAL_RCC_ETHMACPTP_CLK_ENABLE +#define __ETHMACPTP_CLK_DISABLE __HAL_RCC_ETHMACPTP_CLK_DISABLE +#define __HASH_CLK_ENABLE __HAL_RCC_HASH_CLK_ENABLE +#define __HASH_FORCE_RESET __HAL_RCC_HASH_FORCE_RESET +#define __HASH_RELEASE_RESET __HAL_RCC_HASH_RELEASE_RESET +#define __HASH_CLK_SLEEP_ENABLE __HAL_RCC_HASH_CLK_SLEEP_ENABLE +#define __HASH_CLK_SLEEP_DISABLE __HAL_RCC_HASH_CLK_SLEEP_DISABLE +#define __HASH_CLK_DISABLE __HAL_RCC_HASH_CLK_DISABLE +#define __SPI5_CLK_ENABLE __HAL_RCC_SPI5_CLK_ENABLE +#define __SPI5_CLK_DISABLE __HAL_RCC_SPI5_CLK_DISABLE +#define __SPI5_FORCE_RESET __HAL_RCC_SPI5_FORCE_RESET +#define __SPI5_RELEASE_RESET __HAL_RCC_SPI5_RELEASE_RESET +#define __SPI5_CLK_SLEEP_ENABLE __HAL_RCC_SPI5_CLK_SLEEP_ENABLE +#define __SPI5_CLK_SLEEP_DISABLE __HAL_RCC_SPI5_CLK_SLEEP_DISABLE +#define __SPI6_CLK_ENABLE __HAL_RCC_SPI6_CLK_ENABLE +#define __SPI6_CLK_DISABLE __HAL_RCC_SPI6_CLK_DISABLE +#define __SPI6_FORCE_RESET __HAL_RCC_SPI6_FORCE_RESET +#define __SPI6_RELEASE_RESET __HAL_RCC_SPI6_RELEASE_RESET +#define __SPI6_CLK_SLEEP_ENABLE __HAL_RCC_SPI6_CLK_SLEEP_ENABLE +#define __SPI6_CLK_SLEEP_DISABLE __HAL_RCC_SPI6_CLK_SLEEP_DISABLE +#define __LTDC_CLK_ENABLE __HAL_RCC_LTDC_CLK_ENABLE +#define __LTDC_CLK_DISABLE __HAL_RCC_LTDC_CLK_DISABLE +#define __LTDC_FORCE_RESET __HAL_RCC_LTDC_FORCE_RESET +#define __LTDC_RELEASE_RESET __HAL_RCC_LTDC_RELEASE_RESET +#define __LTDC_CLK_SLEEP_ENABLE __HAL_RCC_LTDC_CLK_SLEEP_ENABLE +#define __ETHMAC_CLK_SLEEP_ENABLE __HAL_RCC_ETHMAC_CLK_SLEEP_ENABLE +#define __ETHMAC_CLK_SLEEP_DISABLE __HAL_RCC_ETHMAC_CLK_SLEEP_DISABLE +#define __ETHMACTX_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACTX_CLK_SLEEP_ENABLE +#define __ETHMACTX_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACTX_CLK_SLEEP_DISABLE +#define __ETHMACRX_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACRX_CLK_SLEEP_ENABLE +#define __ETHMACRX_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACRX_CLK_SLEEP_DISABLE +#define __TIM12_CLK_SLEEP_ENABLE __HAL_RCC_TIM12_CLK_SLEEP_ENABLE +#define __TIM12_CLK_SLEEP_DISABLE __HAL_RCC_TIM12_CLK_SLEEP_DISABLE +#define __TIM13_CLK_SLEEP_ENABLE __HAL_RCC_TIM13_CLK_SLEEP_ENABLE +#define __TIM13_CLK_SLEEP_DISABLE __HAL_RCC_TIM13_CLK_SLEEP_DISABLE +#define __TIM14_CLK_SLEEP_ENABLE __HAL_RCC_TIM14_CLK_SLEEP_ENABLE +#define __TIM14_CLK_SLEEP_DISABLE __HAL_RCC_TIM14_CLK_SLEEP_DISABLE +#define __BKPSRAM_CLK_ENABLE __HAL_RCC_BKPSRAM_CLK_ENABLE +#define __BKPSRAM_CLK_DISABLE __HAL_RCC_BKPSRAM_CLK_DISABLE +#define __BKPSRAM_CLK_SLEEP_ENABLE __HAL_RCC_BKPSRAM_CLK_SLEEP_ENABLE +#define __BKPSRAM_CLK_SLEEP_DISABLE __HAL_RCC_BKPSRAM_CLK_SLEEP_DISABLE +#define __CCMDATARAMEN_CLK_ENABLE __HAL_RCC_CCMDATARAMEN_CLK_ENABLE +#define __CCMDATARAMEN_CLK_DISABLE __HAL_RCC_CCMDATARAMEN_CLK_DISABLE +#define __USART6_CLK_ENABLE __HAL_RCC_USART6_CLK_ENABLE +#define __USART6_CLK_DISABLE __HAL_RCC_USART6_CLK_DISABLE +#define __USART6_FORCE_RESET __HAL_RCC_USART6_FORCE_RESET +#define __USART6_RELEASE_RESET __HAL_RCC_USART6_RELEASE_RESET +#define __USART6_CLK_SLEEP_ENABLE __HAL_RCC_USART6_CLK_SLEEP_ENABLE +#define __USART6_CLK_SLEEP_DISABLE __HAL_RCC_USART6_CLK_SLEEP_DISABLE +#define __SPI4_CLK_ENABLE __HAL_RCC_SPI4_CLK_ENABLE +#define __SPI4_CLK_DISABLE __HAL_RCC_SPI4_CLK_DISABLE +#define __SPI4_FORCE_RESET __HAL_RCC_SPI4_FORCE_RESET +#define __SPI4_RELEASE_RESET __HAL_RCC_SPI4_RELEASE_RESET +#define __SPI4_CLK_SLEEP_ENABLE __HAL_RCC_SPI4_CLK_SLEEP_ENABLE +#define __SPI4_CLK_SLEEP_DISABLE __HAL_RCC_SPI4_CLK_SLEEP_DISABLE +#define __GPIOI_CLK_ENABLE __HAL_RCC_GPIOI_CLK_ENABLE +#define __GPIOI_CLK_DISABLE __HAL_RCC_GPIOI_CLK_DISABLE +#define __GPIOI_FORCE_RESET __HAL_RCC_GPIOI_FORCE_RESET +#define __GPIOI_RELEASE_RESET __HAL_RCC_GPIOI_RELEASE_RESET +#define __GPIOI_CLK_SLEEP_ENABLE __HAL_RCC_GPIOI_CLK_SLEEP_ENABLE +#define __GPIOI_CLK_SLEEP_DISABLE __HAL_RCC_GPIOI_CLK_SLEEP_DISABLE +#define __GPIOJ_CLK_ENABLE __HAL_RCC_GPIOJ_CLK_ENABLE +#define __GPIOJ_CLK_DISABLE __HAL_RCC_GPIOJ_CLK_DISABLE +#define __GPIOJ_FORCE_RESET __HAL_RCC_GPIOJ_FORCE_RESET +#define __GPIOJ_RELEASE_RESET __HAL_RCC_GPIOJ_RELEASE_RESET +#define __GPIOJ_CLK_SLEEP_ENABLE __HAL_RCC_GPIOJ_CLK_SLEEP_ENABLE +#define __GPIOJ_CLK_SLEEP_DISABLE __HAL_RCC_GPIOJ_CLK_SLEEP_DISABLE +#define __GPIOK_CLK_ENABLE __HAL_RCC_GPIOK_CLK_ENABLE +#define __GPIOK_CLK_DISABLE __HAL_RCC_GPIOK_CLK_DISABLE +#define __GPIOK_RELEASE_RESET __HAL_RCC_GPIOK_RELEASE_RESET +#define __GPIOK_CLK_SLEEP_ENABLE __HAL_RCC_GPIOK_CLK_SLEEP_ENABLE +#define __GPIOK_CLK_SLEEP_DISABLE __HAL_RCC_GPIOK_CLK_SLEEP_DISABLE +#define __ETH_CLK_ENABLE __HAL_RCC_ETH_CLK_ENABLE +#define __ETH_CLK_DISABLE __HAL_RCC_ETH_CLK_DISABLE +#define __DCMI_CLK_ENABLE __HAL_RCC_DCMI_CLK_ENABLE +#define __DCMI_CLK_DISABLE __HAL_RCC_DCMI_CLK_DISABLE +#define __DCMI_FORCE_RESET __HAL_RCC_DCMI_FORCE_RESET +#define __DCMI_RELEASE_RESET __HAL_RCC_DCMI_RELEASE_RESET +#define __DCMI_CLK_SLEEP_ENABLE __HAL_RCC_DCMI_CLK_SLEEP_ENABLE +#define __DCMI_CLK_SLEEP_DISABLE __HAL_RCC_DCMI_CLK_SLEEP_DISABLE +#define __UART7_CLK_ENABLE __HAL_RCC_UART7_CLK_ENABLE +#define __UART7_CLK_DISABLE __HAL_RCC_UART7_CLK_DISABLE +#define __UART7_RELEASE_RESET __HAL_RCC_UART7_RELEASE_RESET +#define __UART7_FORCE_RESET __HAL_RCC_UART7_FORCE_RESET +#define __UART7_CLK_SLEEP_ENABLE __HAL_RCC_UART7_CLK_SLEEP_ENABLE +#define __UART7_CLK_SLEEP_DISABLE __HAL_RCC_UART7_CLK_SLEEP_DISABLE +#define __UART8_CLK_ENABLE __HAL_RCC_UART8_CLK_ENABLE +#define __UART8_CLK_DISABLE __HAL_RCC_UART8_CLK_DISABLE +#define __UART8_FORCE_RESET __HAL_RCC_UART8_FORCE_RESET +#define __UART8_RELEASE_RESET __HAL_RCC_UART8_RELEASE_RESET +#define __UART8_CLK_SLEEP_ENABLE __HAL_RCC_UART8_CLK_SLEEP_ENABLE +#define __UART8_CLK_SLEEP_DISABLE __HAL_RCC_UART8_CLK_SLEEP_DISABLE +#define __OTGHS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE +#define __OTGHS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE +#define __OTGHS_FORCE_RESET __HAL_RCC_USB_OTG_HS_FORCE_RESET +#define __OTGHS_RELEASE_RESET __HAL_RCC_USB_OTG_HS_RELEASE_RESET +#define __OTGHSULPI_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE +#define __OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE +#define __HAL_RCC_OTGHS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHS_IS_CLK_SLEEP_ENABLED __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_OTGHS_IS_CLK_SLEEP_DISABLED __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_DISABLED +#define __HAL_RCC_OTGHS_FORCE_RESET __HAL_RCC_USB_OTG_HS_FORCE_RESET +#define __HAL_RCC_OTGHS_RELEASE_RESET __HAL_RCC_USB_OTG_HS_RELEASE_RESET +#define __HAL_RCC_OTGHSULPI_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE +#define __HAL_RCC_OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_ENABLED \ + __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_DISABLED \ + __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_DISABLED +#define __SRAM3_CLK_SLEEP_ENABLE __HAL_RCC_SRAM3_CLK_SLEEP_ENABLE +#define __CAN2_CLK_SLEEP_ENABLE __HAL_RCC_CAN2_CLK_SLEEP_ENABLE +#define __CAN2_CLK_SLEEP_DISABLE __HAL_RCC_CAN2_CLK_SLEEP_DISABLE +#define __DAC_CLK_SLEEP_ENABLE __HAL_RCC_DAC_CLK_SLEEP_ENABLE +#define __DAC_CLK_SLEEP_DISABLE __HAL_RCC_DAC_CLK_SLEEP_DISABLE +#define __ADC2_CLK_SLEEP_ENABLE __HAL_RCC_ADC2_CLK_SLEEP_ENABLE +#define __ADC2_CLK_SLEEP_DISABLE __HAL_RCC_ADC2_CLK_SLEEP_DISABLE +#define __ADC3_CLK_SLEEP_ENABLE __HAL_RCC_ADC3_CLK_SLEEP_ENABLE +#define __ADC3_CLK_SLEEP_DISABLE __HAL_RCC_ADC3_CLK_SLEEP_DISABLE +#define __FSMC_FORCE_RESET __HAL_RCC_FSMC_FORCE_RESET +#define __FSMC_RELEASE_RESET __HAL_RCC_FSMC_RELEASE_RESET +#define __FSMC_CLK_SLEEP_ENABLE __HAL_RCC_FSMC_CLK_SLEEP_ENABLE +#define __FSMC_CLK_SLEEP_DISABLE __HAL_RCC_FSMC_CLK_SLEEP_DISABLE +#define __SDIO_FORCE_RESET __HAL_RCC_SDIO_FORCE_RESET +#define __SDIO_RELEASE_RESET __HAL_RCC_SDIO_RELEASE_RESET +#define __SDIO_CLK_SLEEP_DISABLE __HAL_RCC_SDIO_CLK_SLEEP_DISABLE +#define __SDIO_CLK_SLEEP_ENABLE __HAL_RCC_SDIO_CLK_SLEEP_ENABLE +#define __DMA2D_CLK_ENABLE __HAL_RCC_DMA2D_CLK_ENABLE +#define __DMA2D_CLK_DISABLE __HAL_RCC_DMA2D_CLK_DISABLE +#define __DMA2D_FORCE_RESET __HAL_RCC_DMA2D_FORCE_RESET +#define __DMA2D_RELEASE_RESET __HAL_RCC_DMA2D_RELEASE_RESET +#define __DMA2D_CLK_SLEEP_ENABLE __HAL_RCC_DMA2D_CLK_SLEEP_ENABLE +#define __DMA2D_CLK_SLEEP_DISABLE __HAL_RCC_DMA2D_CLK_SLEEP_DISABLE + +/* alias define maintained for legacy */ +#define __HAL_RCC_OTGFS_FORCE_RESET __HAL_RCC_USB_OTG_FS_FORCE_RESET +#define __HAL_RCC_OTGFS_RELEASE_RESET __HAL_RCC_USB_OTG_FS_RELEASE_RESET + +#define __ADC12_CLK_ENABLE __HAL_RCC_ADC12_CLK_ENABLE +#define __ADC12_CLK_DISABLE __HAL_RCC_ADC12_CLK_DISABLE +#define __ADC34_CLK_ENABLE __HAL_RCC_ADC34_CLK_ENABLE +#define __ADC34_CLK_DISABLE __HAL_RCC_ADC34_CLK_DISABLE +#define __DAC2_CLK_ENABLE __HAL_RCC_DAC2_CLK_ENABLE +#define __DAC2_CLK_DISABLE __HAL_RCC_DAC2_CLK_DISABLE +#define __TIM18_CLK_ENABLE __HAL_RCC_TIM18_CLK_ENABLE +#define __TIM18_CLK_DISABLE __HAL_RCC_TIM18_CLK_DISABLE +#define __TIM19_CLK_ENABLE __HAL_RCC_TIM19_CLK_ENABLE +#define __TIM19_CLK_DISABLE __HAL_RCC_TIM19_CLK_DISABLE +#define __TIM20_CLK_ENABLE __HAL_RCC_TIM20_CLK_ENABLE +#define __TIM20_CLK_DISABLE __HAL_RCC_TIM20_CLK_DISABLE +#define __HRTIM1_CLK_ENABLE __HAL_RCC_HRTIM1_CLK_ENABLE +#define __HRTIM1_CLK_DISABLE __HAL_RCC_HRTIM1_CLK_DISABLE +#define __SDADC1_CLK_ENABLE __HAL_RCC_SDADC1_CLK_ENABLE +#define __SDADC2_CLK_ENABLE __HAL_RCC_SDADC2_CLK_ENABLE +#define __SDADC3_CLK_ENABLE __HAL_RCC_SDADC3_CLK_ENABLE +#define __SDADC1_CLK_DISABLE __HAL_RCC_SDADC1_CLK_DISABLE +#define __SDADC2_CLK_DISABLE __HAL_RCC_SDADC2_CLK_DISABLE +#define __SDADC3_CLK_DISABLE __HAL_RCC_SDADC3_CLK_DISABLE + +#define __ADC12_FORCE_RESET __HAL_RCC_ADC12_FORCE_RESET +#define __ADC12_RELEASE_RESET __HAL_RCC_ADC12_RELEASE_RESET +#define __ADC34_FORCE_RESET __HAL_RCC_ADC34_FORCE_RESET +#define __ADC34_RELEASE_RESET __HAL_RCC_ADC34_RELEASE_RESET +#define __DAC2_FORCE_RESET __HAL_RCC_DAC2_FORCE_RESET +#define __DAC2_RELEASE_RESET __HAL_RCC_DAC2_RELEASE_RESET +#define __TIM18_FORCE_RESET __HAL_RCC_TIM18_FORCE_RESET +#define __TIM18_RELEASE_RESET __HAL_RCC_TIM18_RELEASE_RESET +#define __TIM19_FORCE_RESET __HAL_RCC_TIM19_FORCE_RESET +#define __TIM19_RELEASE_RESET __HAL_RCC_TIM19_RELEASE_RESET +#define __TIM20_FORCE_RESET __HAL_RCC_TIM20_FORCE_RESET +#define __TIM20_RELEASE_RESET __HAL_RCC_TIM20_RELEASE_RESET +#define __HRTIM1_FORCE_RESET __HAL_RCC_HRTIM1_FORCE_RESET +#define __HRTIM1_RELEASE_RESET __HAL_RCC_HRTIM1_RELEASE_RESET +#define __SDADC1_FORCE_RESET __HAL_RCC_SDADC1_FORCE_RESET +#define __SDADC2_FORCE_RESET __HAL_RCC_SDADC2_FORCE_RESET +#define __SDADC3_FORCE_RESET __HAL_RCC_SDADC3_FORCE_RESET +#define __SDADC1_RELEASE_RESET __HAL_RCC_SDADC1_RELEASE_RESET +#define __SDADC2_RELEASE_RESET __HAL_RCC_SDADC2_RELEASE_RESET +#define __SDADC3_RELEASE_RESET __HAL_RCC_SDADC3_RELEASE_RESET + +#define __ADC1_IS_CLK_ENABLED __HAL_RCC_ADC1_IS_CLK_ENABLED +#define __ADC1_IS_CLK_DISABLED __HAL_RCC_ADC1_IS_CLK_DISABLED +#define __ADC12_IS_CLK_ENABLED __HAL_RCC_ADC12_IS_CLK_ENABLED +#define __ADC12_IS_CLK_DISABLED __HAL_RCC_ADC12_IS_CLK_DISABLED +#define __ADC34_IS_CLK_ENABLED __HAL_RCC_ADC34_IS_CLK_ENABLED +#define __ADC34_IS_CLK_DISABLED __HAL_RCC_ADC34_IS_CLK_DISABLED +#define __CEC_IS_CLK_ENABLED __HAL_RCC_CEC_IS_CLK_ENABLED +#define __CEC_IS_CLK_DISABLED __HAL_RCC_CEC_IS_CLK_DISABLED +#define __CRC_IS_CLK_ENABLED __HAL_RCC_CRC_IS_CLK_ENABLED +#define __CRC_IS_CLK_DISABLED __HAL_RCC_CRC_IS_CLK_DISABLED +#define __DAC1_IS_CLK_ENABLED __HAL_RCC_DAC1_IS_CLK_ENABLED +#define __DAC1_IS_CLK_DISABLED __HAL_RCC_DAC1_IS_CLK_DISABLED +#define __DAC2_IS_CLK_ENABLED __HAL_RCC_DAC2_IS_CLK_ENABLED +#define __DAC2_IS_CLK_DISABLED __HAL_RCC_DAC2_IS_CLK_DISABLED +#define __DMA1_IS_CLK_ENABLED __HAL_RCC_DMA1_IS_CLK_ENABLED +#define __DMA1_IS_CLK_DISABLED __HAL_RCC_DMA1_IS_CLK_DISABLED +#define __DMA2_IS_CLK_ENABLED __HAL_RCC_DMA2_IS_CLK_ENABLED +#define __DMA2_IS_CLK_DISABLED __HAL_RCC_DMA2_IS_CLK_DISABLED +#define __FLITF_IS_CLK_ENABLED __HAL_RCC_FLITF_IS_CLK_ENABLED +#define __FLITF_IS_CLK_DISABLED __HAL_RCC_FLITF_IS_CLK_DISABLED +#define __FMC_IS_CLK_ENABLED __HAL_RCC_FMC_IS_CLK_ENABLED +#define __FMC_IS_CLK_DISABLED __HAL_RCC_FMC_IS_CLK_DISABLED +#define __GPIOA_IS_CLK_ENABLED __HAL_RCC_GPIOA_IS_CLK_ENABLED +#define __GPIOA_IS_CLK_DISABLED __HAL_RCC_GPIOA_IS_CLK_DISABLED +#define __GPIOB_IS_CLK_ENABLED __HAL_RCC_GPIOB_IS_CLK_ENABLED +#define __GPIOB_IS_CLK_DISABLED __HAL_RCC_GPIOB_IS_CLK_DISABLED +#define __GPIOC_IS_CLK_ENABLED __HAL_RCC_GPIOC_IS_CLK_ENABLED +#define __GPIOC_IS_CLK_DISABLED __HAL_RCC_GPIOC_IS_CLK_DISABLED +#define __GPIOD_IS_CLK_ENABLED __HAL_RCC_GPIOD_IS_CLK_ENABLED +#define __GPIOD_IS_CLK_DISABLED __HAL_RCC_GPIOD_IS_CLK_DISABLED +#define __GPIOE_IS_CLK_ENABLED __HAL_RCC_GPIOE_IS_CLK_ENABLED +#define __GPIOE_IS_CLK_DISABLED __HAL_RCC_GPIOE_IS_CLK_DISABLED +#define __GPIOF_IS_CLK_ENABLED __HAL_RCC_GPIOF_IS_CLK_ENABLED +#define __GPIOF_IS_CLK_DISABLED __HAL_RCC_GPIOF_IS_CLK_DISABLED +#define __GPIOG_IS_CLK_ENABLED __HAL_RCC_GPIOG_IS_CLK_ENABLED +#define __GPIOG_IS_CLK_DISABLED __HAL_RCC_GPIOG_IS_CLK_DISABLED +#define __GPIOH_IS_CLK_ENABLED __HAL_RCC_GPIOH_IS_CLK_ENABLED +#define __GPIOH_IS_CLK_DISABLED __HAL_RCC_GPIOH_IS_CLK_DISABLED +#define __HRTIM1_IS_CLK_ENABLED __HAL_RCC_HRTIM1_IS_CLK_ENABLED +#define __HRTIM1_IS_CLK_DISABLED __HAL_RCC_HRTIM1_IS_CLK_DISABLED +#define __I2C1_IS_CLK_ENABLED __HAL_RCC_I2C1_IS_CLK_ENABLED +#define __I2C1_IS_CLK_DISABLED __HAL_RCC_I2C1_IS_CLK_DISABLED +#define __I2C2_IS_CLK_ENABLED __HAL_RCC_I2C2_IS_CLK_ENABLED +#define __I2C2_IS_CLK_DISABLED __HAL_RCC_I2C2_IS_CLK_DISABLED +#define __I2C3_IS_CLK_ENABLED __HAL_RCC_I2C3_IS_CLK_ENABLED +#define __I2C3_IS_CLK_DISABLED __HAL_RCC_I2C3_IS_CLK_DISABLED +#define __PWR_IS_CLK_ENABLED __HAL_RCC_PWR_IS_CLK_ENABLED +#define __PWR_IS_CLK_DISABLED __HAL_RCC_PWR_IS_CLK_DISABLED +#define __SYSCFG_IS_CLK_ENABLED __HAL_RCC_SYSCFG_IS_CLK_ENABLED +#define __SYSCFG_IS_CLK_DISABLED __HAL_RCC_SYSCFG_IS_CLK_DISABLED +#define __SPI1_IS_CLK_ENABLED __HAL_RCC_SPI1_IS_CLK_ENABLED +#define __SPI1_IS_CLK_DISABLED __HAL_RCC_SPI1_IS_CLK_DISABLED +#define __SPI2_IS_CLK_ENABLED __HAL_RCC_SPI2_IS_CLK_ENABLED +#define __SPI2_IS_CLK_DISABLED __HAL_RCC_SPI2_IS_CLK_DISABLED +#define __SPI3_IS_CLK_ENABLED __HAL_RCC_SPI3_IS_CLK_ENABLED +#define __SPI3_IS_CLK_DISABLED __HAL_RCC_SPI3_IS_CLK_DISABLED +#define __SPI4_IS_CLK_ENABLED __HAL_RCC_SPI4_IS_CLK_ENABLED +#define __SPI4_IS_CLK_DISABLED __HAL_RCC_SPI4_IS_CLK_DISABLED +#define __SDADC1_IS_CLK_ENABLED __HAL_RCC_SDADC1_IS_CLK_ENABLED +#define __SDADC1_IS_CLK_DISABLED __HAL_RCC_SDADC1_IS_CLK_DISABLED +#define __SDADC2_IS_CLK_ENABLED __HAL_RCC_SDADC2_IS_CLK_ENABLED +#define __SDADC2_IS_CLK_DISABLED __HAL_RCC_SDADC2_IS_CLK_DISABLED +#define __SDADC3_IS_CLK_ENABLED __HAL_RCC_SDADC3_IS_CLK_ENABLED +#define __SDADC3_IS_CLK_DISABLED __HAL_RCC_SDADC3_IS_CLK_DISABLED +#define __SRAM_IS_CLK_ENABLED __HAL_RCC_SRAM_IS_CLK_ENABLED +#define __SRAM_IS_CLK_DISABLED __HAL_RCC_SRAM_IS_CLK_DISABLED +#define __TIM1_IS_CLK_ENABLED __HAL_RCC_TIM1_IS_CLK_ENABLED +#define __TIM1_IS_CLK_DISABLED __HAL_RCC_TIM1_IS_CLK_DISABLED +#define __TIM2_IS_CLK_ENABLED __HAL_RCC_TIM2_IS_CLK_ENABLED +#define __TIM2_IS_CLK_DISABLED __HAL_RCC_TIM2_IS_CLK_DISABLED +#define __TIM3_IS_CLK_ENABLED __HAL_RCC_TIM3_IS_CLK_ENABLED +#define __TIM3_IS_CLK_DISABLED __HAL_RCC_TIM3_IS_CLK_DISABLED +#define __TIM4_IS_CLK_ENABLED __HAL_RCC_TIM4_IS_CLK_ENABLED +#define __TIM4_IS_CLK_DISABLED __HAL_RCC_TIM4_IS_CLK_DISABLED +#define __TIM5_IS_CLK_ENABLED __HAL_RCC_TIM5_IS_CLK_ENABLED +#define __TIM5_IS_CLK_DISABLED __HAL_RCC_TIM5_IS_CLK_DISABLED +#define __TIM6_IS_CLK_ENABLED __HAL_RCC_TIM6_IS_CLK_ENABLED +#define __TIM6_IS_CLK_DISABLED __HAL_RCC_TIM6_IS_CLK_DISABLED +#define __TIM7_IS_CLK_ENABLED __HAL_RCC_TIM7_IS_CLK_ENABLED +#define __TIM7_IS_CLK_DISABLED __HAL_RCC_TIM7_IS_CLK_DISABLED +#define __TIM8_IS_CLK_ENABLED __HAL_RCC_TIM8_IS_CLK_ENABLED +#define __TIM8_IS_CLK_DISABLED __HAL_RCC_TIM8_IS_CLK_DISABLED +#define __TIM12_IS_CLK_ENABLED __HAL_RCC_TIM12_IS_CLK_ENABLED +#define __TIM12_IS_CLK_DISABLED __HAL_RCC_TIM12_IS_CLK_DISABLED +#define __TIM13_IS_CLK_ENABLED __HAL_RCC_TIM13_IS_CLK_ENABLED +#define __TIM13_IS_CLK_DISABLED __HAL_RCC_TIM13_IS_CLK_DISABLED +#define __TIM14_IS_CLK_ENABLED __HAL_RCC_TIM14_IS_CLK_ENABLED +#define __TIM14_IS_CLK_DISABLED __HAL_RCC_TIM14_IS_CLK_DISABLED +#define __TIM15_IS_CLK_ENABLED __HAL_RCC_TIM15_IS_CLK_ENABLED +#define __TIM15_IS_CLK_DISABLED __HAL_RCC_TIM15_IS_CLK_DISABLED +#define __TIM16_IS_CLK_ENABLED __HAL_RCC_TIM16_IS_CLK_ENABLED +#define __TIM16_IS_CLK_DISABLED __HAL_RCC_TIM16_IS_CLK_DISABLED +#define __TIM17_IS_CLK_ENABLED __HAL_RCC_TIM17_IS_CLK_ENABLED +#define __TIM17_IS_CLK_DISABLED __HAL_RCC_TIM17_IS_CLK_DISABLED +#define __TIM18_IS_CLK_ENABLED __HAL_RCC_TIM18_IS_CLK_ENABLED +#define __TIM18_IS_CLK_DISABLED __HAL_RCC_TIM18_IS_CLK_DISABLED +#define __TIM19_IS_CLK_ENABLED __HAL_RCC_TIM19_IS_CLK_ENABLED +#define __TIM19_IS_CLK_DISABLED __HAL_RCC_TIM19_IS_CLK_DISABLED +#define __TIM20_IS_CLK_ENABLED __HAL_RCC_TIM20_IS_CLK_ENABLED +#define __TIM20_IS_CLK_DISABLED __HAL_RCC_TIM20_IS_CLK_DISABLED +#define __TSC_IS_CLK_ENABLED __HAL_RCC_TSC_IS_CLK_ENABLED +#define __TSC_IS_CLK_DISABLED __HAL_RCC_TSC_IS_CLK_DISABLED +#define __UART4_IS_CLK_ENABLED __HAL_RCC_UART4_IS_CLK_ENABLED +#define __UART4_IS_CLK_DISABLED __HAL_RCC_UART4_IS_CLK_DISABLED +#define __UART5_IS_CLK_ENABLED __HAL_RCC_UART5_IS_CLK_ENABLED +#define __UART5_IS_CLK_DISABLED __HAL_RCC_UART5_IS_CLK_DISABLED +#define __USART1_IS_CLK_ENABLED __HAL_RCC_USART1_IS_CLK_ENABLED +#define __USART1_IS_CLK_DISABLED __HAL_RCC_USART1_IS_CLK_DISABLED +#define __USART2_IS_CLK_ENABLED __HAL_RCC_USART2_IS_CLK_ENABLED +#define __USART2_IS_CLK_DISABLED __HAL_RCC_USART2_IS_CLK_DISABLED +#define __USART3_IS_CLK_ENABLED __HAL_RCC_USART3_IS_CLK_ENABLED +#define __USART3_IS_CLK_DISABLED __HAL_RCC_USART3_IS_CLK_DISABLED +#define __USB_IS_CLK_ENABLED __HAL_RCC_USB_IS_CLK_ENABLED +#define __USB_IS_CLK_DISABLED __HAL_RCC_USB_IS_CLK_DISABLED +#define __WWDG_IS_CLK_ENABLED __HAL_RCC_WWDG_IS_CLK_ENABLED +#define __WWDG_IS_CLK_DISABLED __HAL_RCC_WWDG_IS_CLK_DISABLED + +#if defined(STM32L1) +#define __HAL_RCC_CRYP_CLK_DISABLE __HAL_RCC_AES_CLK_DISABLE +#define __HAL_RCC_CRYP_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE +#define __HAL_RCC_CRYP_CLK_SLEEP_DISABLE __HAL_RCC_AES_CLK_SLEEP_DISABLE +#define __HAL_RCC_CRYP_CLK_SLEEP_ENABLE __HAL_RCC_AES_CLK_SLEEP_ENABLE +#define __HAL_RCC_CRYP_FORCE_RESET __HAL_RCC_AES_FORCE_RESET +#define __HAL_RCC_CRYP_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET +#endif /* STM32L1 */ + +#if defined(STM32F4) +#define __HAL_RCC_SDMMC1_FORCE_RESET __HAL_RCC_SDIO_FORCE_RESET +#define __HAL_RCC_SDMMC1_RELEASE_RESET __HAL_RCC_SDIO_RELEASE_RESET +#define __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE __HAL_RCC_SDIO_CLK_SLEEP_ENABLE +#define __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE __HAL_RCC_SDIO_CLK_SLEEP_DISABLE +#define __HAL_RCC_SDMMC1_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __HAL_RCC_SDMMC1_CLK_DISABLE __HAL_RCC_SDIO_CLK_DISABLE +#define __HAL_RCC_SDMMC1_IS_CLK_ENABLED __HAL_RCC_SDIO_IS_CLK_ENABLED +#define __HAL_RCC_SDMMC1_IS_CLK_DISABLED __HAL_RCC_SDIO_IS_CLK_DISABLED +#define Sdmmc1ClockSelection SdioClockSelection +#define RCC_PERIPHCLK_SDMMC1 RCC_PERIPHCLK_SDIO +#define RCC_SDMMC1CLKSOURCE_CLK48 RCC_SDIOCLKSOURCE_CK48 +#define RCC_SDMMC1CLKSOURCE_SYSCLK RCC_SDIOCLKSOURCE_SYSCLK +#define __HAL_RCC_SDMMC1_CONFIG __HAL_RCC_SDIO_CONFIG +#define __HAL_RCC_GET_SDMMC1_SOURCE __HAL_RCC_GET_SDIO_SOURCE +#endif + +#if defined(STM32F7) || defined(STM32L4) +#define __HAL_RCC_SDIO_FORCE_RESET __HAL_RCC_SDMMC1_FORCE_RESET +#define __HAL_RCC_SDIO_RELEASE_RESET __HAL_RCC_SDMMC1_RELEASE_RESET +#define __HAL_RCC_SDIO_CLK_SLEEP_ENABLE __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE +#define __HAL_RCC_SDIO_CLK_SLEEP_DISABLE __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE +#define __HAL_RCC_SDIO_CLK_ENABLE __HAL_RCC_SDMMC1_CLK_ENABLE +#define __HAL_RCC_SDIO_CLK_DISABLE __HAL_RCC_SDMMC1_CLK_DISABLE +#define __HAL_RCC_SDIO_IS_CLK_ENABLED __HAL_RCC_SDMMC1_IS_CLK_ENABLED +#define __HAL_RCC_SDIO_IS_CLK_DISABLED __HAL_RCC_SDMMC1_IS_CLK_DISABLED +#define SdioClockSelection Sdmmc1ClockSelection +#define RCC_PERIPHCLK_SDIO RCC_PERIPHCLK_SDMMC1 +#define __HAL_RCC_SDIO_CONFIG __HAL_RCC_SDMMC1_CONFIG +#define __HAL_RCC_GET_SDIO_SOURCE __HAL_RCC_GET_SDMMC1_SOURCE +#endif + +#if defined(STM32F7) +#define RCC_SDIOCLKSOURCE_CLK48 RCC_SDMMC1CLKSOURCE_CLK48 +#define RCC_SDIOCLKSOURCE_SYSCLK RCC_SDMMC1CLKSOURCE_SYSCLK +#endif + +#if defined(STM32H7) +#define __HAL_RCC_USB_OTG_HS_CLK_ENABLE() __HAL_RCC_USB1_OTG_HS_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_HS_CLK_DISABLE() __HAL_RCC_USB1_OTG_HS_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_HS_FORCE_RESET() __HAL_RCC_USB1_OTG_HS_FORCE_RESET() +#define __HAL_RCC_USB_OTG_HS_RELEASE_RESET() __HAL_RCC_USB1_OTG_HS_RELEASE_RESET() +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE() __HAL_RCC_USB1_OTG_HS_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE() \ + __HAL_RCC_USB1_OTG_HS_ULPI_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE() __HAL_RCC_USB1_OTG_HS_CLK_SLEEP_DISABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE() \ + __HAL_RCC_USB1_OTG_HS_ULPI_CLK_SLEEP_DISABLE() + +#define __HAL_RCC_USB_OTG_FS_CLK_ENABLE() __HAL_RCC_USB2_OTG_FS_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_ENABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_FS_CLK_DISABLE() __HAL_RCC_USB2_OTG_FS_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_DISABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_FS_FORCE_RESET() __HAL_RCC_USB2_OTG_FS_FORCE_RESET() +#define __HAL_RCC_USB_OTG_FS_RELEASE_RESET() __HAL_RCC_USB2_OTG_FS_RELEASE_RESET() +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE() __HAL_RCC_USB2_OTG_FS_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_SLEEP_ENABLE() \ + __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE() __HAL_RCC_USB2_OTG_FS_CLK_SLEEP_DISABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_SLEEP_DISABLE() \ + __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_DISABLE() +#endif + +#define __HAL_RCC_I2SCLK __HAL_RCC_I2S_CONFIG +#define __HAL_RCC_I2SCLK_CONFIG __HAL_RCC_I2S_CONFIG + +#define __RCC_PLLSRC RCC_GET_PLL_OSCSOURCE + +#define IS_RCC_MSIRANGE IS_RCC_MSI_CLOCK_RANGE +#define IS_RCC_RTCCLK_SOURCE IS_RCC_RTCCLKSOURCE +#define IS_RCC_SYSCLK_DIV IS_RCC_HCLK +#define IS_RCC_HCLK_DIV IS_RCC_PCLK +#define IS_RCC_PERIPHCLK IS_RCC_PERIPHCLOCK + +#define RCC_IT_HSI14 RCC_IT_HSI14RDY + +#define RCC_IT_CSSLSE RCC_IT_LSECSS +#define RCC_IT_CSSHSE RCC_IT_CSS + +#define RCC_PLLMUL_3 RCC_PLL_MUL3 +#define RCC_PLLMUL_4 RCC_PLL_MUL4 +#define RCC_PLLMUL_6 RCC_PLL_MUL6 +#define RCC_PLLMUL_8 RCC_PLL_MUL8 +#define RCC_PLLMUL_12 RCC_PLL_MUL12 +#define RCC_PLLMUL_16 RCC_PLL_MUL16 +#define RCC_PLLMUL_24 RCC_PLL_MUL24 +#define RCC_PLLMUL_32 RCC_PLL_MUL32 +#define RCC_PLLMUL_48 RCC_PLL_MUL48 + +#define RCC_PLLDIV_2 RCC_PLL_DIV2 +#define RCC_PLLDIV_3 RCC_PLL_DIV3 +#define RCC_PLLDIV_4 RCC_PLL_DIV4 + +#define IS_RCC_MCOSOURCE IS_RCC_MCO1SOURCE +#define __HAL_RCC_MCO_CONFIG __HAL_RCC_MCO1_CONFIG +#define RCC_MCO_NODIV RCC_MCODIV_1 +#define RCC_MCO_DIV1 RCC_MCODIV_1 +#define RCC_MCO_DIV2 RCC_MCODIV_2 +#define RCC_MCO_DIV4 RCC_MCODIV_4 +#define RCC_MCO_DIV8 RCC_MCODIV_8 +#define RCC_MCO_DIV16 RCC_MCODIV_16 +#define RCC_MCO_DIV32 RCC_MCODIV_32 +#define RCC_MCO_DIV64 RCC_MCODIV_64 +#define RCC_MCO_DIV128 RCC_MCODIV_128 +#define RCC_MCOSOURCE_NONE RCC_MCO1SOURCE_NOCLOCK +#define RCC_MCOSOURCE_LSI RCC_MCO1SOURCE_LSI +#define RCC_MCOSOURCE_LSE RCC_MCO1SOURCE_LSE +#define RCC_MCOSOURCE_SYSCLK RCC_MCO1SOURCE_SYSCLK +#define RCC_MCOSOURCE_HSI RCC_MCO1SOURCE_HSI +#define RCC_MCOSOURCE_HSI14 RCC_MCO1SOURCE_HSI14 +#define RCC_MCOSOURCE_HSI48 RCC_MCO1SOURCE_HSI48 +#define RCC_MCOSOURCE_HSE RCC_MCO1SOURCE_HSE +#define RCC_MCOSOURCE_PLLCLK_DIV1 RCC_MCO1SOURCE_PLLCLK +#define RCC_MCOSOURCE_PLLCLK_NODIV RCC_MCO1SOURCE_PLLCLK +#define RCC_MCOSOURCE_PLLCLK_DIV2 RCC_MCO1SOURCE_PLLCLK_DIV2 + +#if defined(STM32L4) || defined(STM32WB) || defined(STM32G0) || defined(STM32G4) || \ + defined(STM32L5) || defined(STM32WL) || defined(STM32C0) +#define RCC_RTCCLKSOURCE_NO_CLK RCC_RTCCLKSOURCE_NONE +#else +#define RCC_RTCCLKSOURCE_NONE RCC_RTCCLKSOURCE_NO_CLK +#endif + +#define RCC_USBCLK_PLLSAI1 RCC_USBCLKSOURCE_PLLSAI1 +#define RCC_USBCLK_PLL RCC_USBCLKSOURCE_PLL +#define RCC_USBCLK_MSI RCC_USBCLKSOURCE_MSI +#define RCC_USBCLKSOURCE_PLLCLK RCC_USBCLKSOURCE_PLL +#define RCC_USBPLLCLK_DIV1 RCC_USBCLKSOURCE_PLL +#define RCC_USBPLLCLK_DIV1_5 RCC_USBCLKSOURCE_PLL_DIV1_5 +#define RCC_USBPLLCLK_DIV2 RCC_USBCLKSOURCE_PLL_DIV2 +#define RCC_USBPLLCLK_DIV3 RCC_USBCLKSOURCE_PLL_DIV3 + +#define HSION_BitNumber RCC_HSION_BIT_NUMBER +#define HSION_BITNUMBER RCC_HSION_BIT_NUMBER +#define HSEON_BitNumber RCC_HSEON_BIT_NUMBER +#define HSEON_BITNUMBER RCC_HSEON_BIT_NUMBER +#define MSION_BITNUMBER RCC_MSION_BIT_NUMBER +#define CSSON_BitNumber RCC_CSSON_BIT_NUMBER +#define CSSON_BITNUMBER RCC_CSSON_BIT_NUMBER +#define PLLON_BitNumber RCC_PLLON_BIT_NUMBER +#define PLLON_BITNUMBER RCC_PLLON_BIT_NUMBER +#define PLLI2SON_BitNumber RCC_PLLI2SON_BIT_NUMBER +#define I2SSRC_BitNumber RCC_I2SSRC_BIT_NUMBER +#define RTCEN_BitNumber RCC_RTCEN_BIT_NUMBER +#define RTCEN_BITNUMBER RCC_RTCEN_BIT_NUMBER +#define BDRST_BitNumber RCC_BDRST_BIT_NUMBER +#define BDRST_BITNUMBER RCC_BDRST_BIT_NUMBER +#define RTCRST_BITNUMBER RCC_RTCRST_BIT_NUMBER +#define LSION_BitNumber RCC_LSION_BIT_NUMBER +#define LSION_BITNUMBER RCC_LSION_BIT_NUMBER +#define LSEON_BitNumber RCC_LSEON_BIT_NUMBER +#define LSEON_BITNUMBER RCC_LSEON_BIT_NUMBER +#define LSEBYP_BITNUMBER RCC_LSEBYP_BIT_NUMBER +#define PLLSAION_BitNumber RCC_PLLSAION_BIT_NUMBER +#define TIMPRE_BitNumber RCC_TIMPRE_BIT_NUMBER +#define RMVF_BitNumber RCC_RMVF_BIT_NUMBER +#define RMVF_BITNUMBER RCC_RMVF_BIT_NUMBER +#define RCC_CR2_HSI14TRIM_BitNumber RCC_HSI14TRIM_BIT_NUMBER +#define CR_BYTE2_ADDRESS RCC_CR_BYTE2_ADDRESS +#define CIR_BYTE1_ADDRESS RCC_CIR_BYTE1_ADDRESS +#define CIR_BYTE2_ADDRESS RCC_CIR_BYTE2_ADDRESS +#define BDCR_BYTE0_ADDRESS RCC_BDCR_BYTE0_ADDRESS +#define DBP_TIMEOUT_VALUE RCC_DBP_TIMEOUT_VALUE +#define LSE_TIMEOUT_VALUE RCC_LSE_TIMEOUT_VALUE + +#define CR_HSION_BB RCC_CR_HSION_BB +#define CR_CSSON_BB RCC_CR_CSSON_BB +#define CR_PLLON_BB RCC_CR_PLLON_BB +#define CR_PLLI2SON_BB RCC_CR_PLLI2SON_BB +#define CR_MSION_BB RCC_CR_MSION_BB +#define CSR_LSION_BB RCC_CSR_LSION_BB +#define CSR_LSEON_BB RCC_CSR_LSEON_BB +#define CSR_LSEBYP_BB RCC_CSR_LSEBYP_BB +#define CSR_RTCEN_BB RCC_CSR_RTCEN_BB +#define CSR_RTCRST_BB RCC_CSR_RTCRST_BB +#define CFGR_I2SSRC_BB RCC_CFGR_I2SSRC_BB +#define BDCR_RTCEN_BB RCC_BDCR_RTCEN_BB +#define BDCR_BDRST_BB RCC_BDCR_BDRST_BB +#define CR_HSEON_BB RCC_CR_HSEON_BB +#define CSR_RMVF_BB RCC_CSR_RMVF_BB +#define CR_PLLSAION_BB RCC_CR_PLLSAION_BB +#define DCKCFGR_TIMPRE_BB RCC_DCKCFGR_TIMPRE_BB + +#define __HAL_RCC_CRS_ENABLE_FREQ_ERROR_COUNTER __HAL_RCC_CRS_FREQ_ERROR_COUNTER_ENABLE +#define __HAL_RCC_CRS_DISABLE_FREQ_ERROR_COUNTER __HAL_RCC_CRS_FREQ_ERROR_COUNTER_DISABLE +#define __HAL_RCC_CRS_ENABLE_AUTOMATIC_CALIB __HAL_RCC_CRS_AUTOMATIC_CALIB_ENABLE +#define __HAL_RCC_CRS_DISABLE_AUTOMATIC_CALIB __HAL_RCC_CRS_AUTOMATIC_CALIB_DISABLE +#define __HAL_RCC_CRS_CALCULATE_RELOADVALUE __HAL_RCC_CRS_RELOADVALUE_CALCULATE + +#define __HAL_RCC_GET_IT_SOURCE __HAL_RCC_GET_IT + +#define RCC_CRS_SYNCWARM RCC_CRS_SYNCWARN +#define RCC_CRS_TRIMOV RCC_CRS_TRIMOVF + +#define RCC_PERIPHCLK_CK48 RCC_PERIPHCLK_CLK48 +#define RCC_CK48CLKSOURCE_PLLQ RCC_CLK48CLKSOURCE_PLLQ +#define RCC_CK48CLKSOURCE_PLLSAIP RCC_CLK48CLKSOURCE_PLLSAIP +#define RCC_CK48CLKSOURCE_PLLI2SQ RCC_CLK48CLKSOURCE_PLLI2SQ +#define IS_RCC_CK48CLKSOURCE IS_RCC_CLK48CLKSOURCE +#define RCC_SDIOCLKSOURCE_CK48 RCC_SDIOCLKSOURCE_CLK48 + +#define __HAL_RCC_DFSDM_CLK_ENABLE __HAL_RCC_DFSDM1_CLK_ENABLE +#define __HAL_RCC_DFSDM_CLK_DISABLE __HAL_RCC_DFSDM1_CLK_DISABLE +#define __HAL_RCC_DFSDM_IS_CLK_ENABLED __HAL_RCC_DFSDM1_IS_CLK_ENABLED +#define __HAL_RCC_DFSDM_IS_CLK_DISABLED __HAL_RCC_DFSDM1_IS_CLK_DISABLED +#define __HAL_RCC_DFSDM_FORCE_RESET __HAL_RCC_DFSDM1_FORCE_RESET +#define __HAL_RCC_DFSDM_RELEASE_RESET __HAL_RCC_DFSDM1_RELEASE_RESET +#define __HAL_RCC_DFSDM_CLK_SLEEP_ENABLE __HAL_RCC_DFSDM1_CLK_SLEEP_ENABLE +#define __HAL_RCC_DFSDM_CLK_SLEEP_DISABLE __HAL_RCC_DFSDM1_CLK_SLEEP_DISABLE +#define __HAL_RCC_DFSDM_IS_CLK_SLEEP_ENABLED __HAL_RCC_DFSDM1_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_DFSDM_IS_CLK_SLEEP_DISABLED __HAL_RCC_DFSDM1_IS_CLK_SLEEP_DISABLED +#define DfsdmClockSelection Dfsdm1ClockSelection +#define RCC_PERIPHCLK_DFSDM RCC_PERIPHCLK_DFSDM1 +#define RCC_DFSDMCLKSOURCE_PCLK RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_DFSDMCLKSOURCE_SYSCLK RCC_DFSDM1CLKSOURCE_SYSCLK +#define __HAL_RCC_DFSDM_CONFIG __HAL_RCC_DFSDM1_CONFIG +#define __HAL_RCC_GET_DFSDM_SOURCE __HAL_RCC_GET_DFSDM1_SOURCE +#define RCC_DFSDM1CLKSOURCE_PCLK RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_SWPMI1CLKSOURCE_PCLK RCC_SWPMI1CLKSOURCE_PCLK1 +#define RCC_LPTIM1CLKSOURCE_PCLK RCC_LPTIM1CLKSOURCE_PCLK1 +#define RCC_LPTIM2CLKSOURCE_PCLK RCC_LPTIM2CLKSOURCE_PCLK1 + +#define RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB1 RCC_DFSDM1AUDIOCLKSOURCE_I2S1 +#define RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB2 RCC_DFSDM1AUDIOCLKSOURCE_I2S2 +#define RCC_DFSDM2AUDIOCLKSOURCE_I2SAPB1 RCC_DFSDM2AUDIOCLKSOURCE_I2S1 +#define RCC_DFSDM2AUDIOCLKSOURCE_I2SAPB2 RCC_DFSDM2AUDIOCLKSOURCE_I2S2 +#define RCC_DFSDM1CLKSOURCE_APB2 RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_DFSDM2CLKSOURCE_APB2 RCC_DFSDM2CLKSOURCE_PCLK2 +#define RCC_FMPI2C1CLKSOURCE_APB RCC_FMPI2C1CLKSOURCE_PCLK1 +#if defined(STM32U5) +#define MSIKPLLModeSEL RCC_MSIKPLL_MODE_SEL +#define MSISPLLModeSEL RCC_MSISPLL_MODE_SEL +#define __HAL_RCC_AHB21_CLK_DISABLE __HAL_RCC_AHB2_1_CLK_DISABLE +#define __HAL_RCC_AHB22_CLK_DISABLE __HAL_RCC_AHB2_2_CLK_DISABLE +#define __HAL_RCC_AHB1_CLK_Disable_Clear __HAL_RCC_AHB1_CLK_ENABLE +#define __HAL_RCC_AHB21_CLK_Disable_Clear __HAL_RCC_AHB2_1_CLK_ENABLE +#define __HAL_RCC_AHB22_CLK_Disable_Clear __HAL_RCC_AHB2_2_CLK_ENABLE +#define __HAL_RCC_AHB3_CLK_Disable_Clear __HAL_RCC_AHB3_CLK_ENABLE +#define __HAL_RCC_APB1_CLK_Disable_Clear __HAL_RCC_APB1_CLK_ENABLE +#define __HAL_RCC_APB2_CLK_Disable_Clear __HAL_RCC_APB2_CLK_ENABLE +#define __HAL_RCC_APB3_CLK_Disable_Clear __HAL_RCC_APB3_CLK_ENABLE +#define IS_RCC_MSIPLLModeSelection IS_RCC_MSIPLLMODE_SELECT +#define RCC_PERIPHCLK_CLK48 RCC_PERIPHCLK_ICLK +#define RCC_CLK48CLKSOURCE_HSI48 RCC_ICLK_CLKSOURCE_HSI48 +#define RCC_CLK48CLKSOURCE_PLL2 RCC_ICLK_CLKSOURCE_PLL2 +#define RCC_CLK48CLKSOURCE_PLL1 RCC_ICLK_CLKSOURCE_PLL1 +#define RCC_CLK48CLKSOURCE_MSIK RCC_ICLK_CLKSOURCE_MSIK +#define __HAL_RCC_ADC1_CLK_ENABLE __HAL_RCC_ADC12_CLK_ENABLE +#define __HAL_RCC_ADC1_CLK_DISABLE __HAL_RCC_ADC12_CLK_DISABLE +#define __HAL_RCC_ADC1_IS_CLK_ENABLED __HAL_RCC_ADC12_IS_CLK_ENABLED +#define __HAL_RCC_ADC1_IS_CLK_DISABLED __HAL_RCC_ADC12_IS_CLK_DISABLED +#define __HAL_RCC_ADC1_FORCE_RESET __HAL_RCC_ADC12_FORCE_RESET +#define __HAL_RCC_ADC1_RELEASE_RESET __HAL_RCC_ADC12_RELEASE_RESET +#define __HAL_RCC_ADC1_CLK_SLEEP_ENABLE __HAL_RCC_ADC12_CLK_SLEEP_ENABLE +#define __HAL_RCC_ADC1_CLK_SLEEP_DISABLE __HAL_RCC_ADC12_CLK_SLEEP_DISABLE +#define __HAL_RCC_GET_CLK48_SOURCE __HAL_RCC_GET_ICLK_SOURCE +#define __HAL_RCC_PLLFRACN_ENABLE __HAL_RCC_PLL_FRACN_ENABLE +#define __HAL_RCC_PLLFRACN_DISABLE __HAL_RCC_PLL_FRACN_DISABLE +#define __HAL_RCC_PLLFRACN_CONFIG __HAL_RCC_PLL_FRACN_CONFIG +#define IS_RCC_PLLFRACN_VALUE IS_RCC_PLL_FRACN_VALUE +#endif /* STM32U5 */ + +#if defined(STM32H5) +#define __HAL_RCC_PLLFRACN_ENABLE __HAL_RCC_PLL_FRACN_ENABLE +#define __HAL_RCC_PLLFRACN_DISABLE __HAL_RCC_PLL_FRACN_DISABLE +#define __HAL_RCC_PLLFRACN_CONFIG __HAL_RCC_PLL_FRACN_CONFIG +#define IS_RCC_PLLFRACN_VALUE IS_RCC_PLL_FRACN_VALUE + +#define RCC_PLLSOURCE_NONE RCC_PLL1_SOURCE_NONE +#define RCC_PLLSOURCE_HSI RCC_PLL1_SOURCE_HSI +#define RCC_PLLSOURCE_CSI RCC_PLL1_SOURCE_CSI +#define RCC_PLLSOURCE_HSE RCC_PLL1_SOURCE_HSE +#define RCC_PLLVCIRANGE_0 RCC_PLL1_VCIRANGE_0 +#define RCC_PLLVCIRANGE_1 RCC_PLL1_VCIRANGE_1 +#define RCC_PLLVCIRANGE_2 RCC_PLL1_VCIRANGE_2 +#define RCC_PLLVCIRANGE_3 RCC_PLL1_VCIRANGE_3 +#define RCC_PLL1VCOWIDE RCC_PLL1_VCORANGE_WIDE +#define RCC_PLL1VCOMEDIUM RCC_PLL1_VCORANGE_MEDIUM + +#define IS_RCC_PLLSOURCE IS_RCC_PLL1_SOURCE +#define IS_RCC_PLLRGE_VALUE IS_RCC_PLL1_VCIRGE_VALUE +#define IS_RCC_PLLVCORGE_VALUE IS_RCC_PLL1_VCORGE_VALUE +#define IS_RCC_PLLCLOCKOUT_VALUE IS_RCC_PLL1_CLOCKOUT_VALUE +#define IS_RCC_PLL_FRACN_VALUE IS_RCC_PLL1_FRACN_VALUE +#define IS_RCC_PLLM_VALUE IS_RCC_PLL1_DIVM_VALUE +#define IS_RCC_PLLN_VALUE IS_RCC_PLL1_MULN_VALUE +#define IS_RCC_PLLP_VALUE IS_RCC_PLL1_DIVP_VALUE +#define IS_RCC_PLLQ_VALUE IS_RCC_PLL1_DIVQ_VALUE +#define IS_RCC_PLLR_VALUE IS_RCC_PLL1_DIVR_VALUE + +#define __HAL_RCC_PLL_ENABLE __HAL_RCC_PLL1_ENABLE +#define __HAL_RCC_PLL_DISABLE __HAL_RCC_PLL1_DISABLE +#define __HAL_RCC_PLL_FRACN_ENABLE __HAL_RCC_PLL1_FRACN_ENABLE +#define __HAL_RCC_PLL_FRACN_DISABLE __HAL_RCC_PLL1_FRACN_DISABLE +#define __HAL_RCC_PLL_CONFIG __HAL_RCC_PLL1_CONFIG +#define __HAL_RCC_PLL_PLLSOURCE_CONFIG __HAL_RCC_PLL1_PLLSOURCE_CONFIG +#define __HAL_RCC_PLL_DIVM_CONFIG __HAL_RCC_PLL1_DIVM_CONFIG +#define __HAL_RCC_PLL_FRACN_CONFIG __HAL_RCC_PLL1_FRACN_CONFIG +#define __HAL_RCC_PLL_VCIRANGE __HAL_RCC_PLL1_VCIRANGE +#define __HAL_RCC_PLL_VCORANGE __HAL_RCC_PLL1_VCORANGE +#define __HAL_RCC_GET_PLL_OSCSOURCE __HAL_RCC_GET_PLL1_OSCSOURCE +#define __HAL_RCC_PLLCLKOUT_ENABLE __HAL_RCC_PLL1_CLKOUT_ENABLE +#define __HAL_RCC_PLLCLKOUT_DISABLE __HAL_RCC_PLL1_CLKOUT_DISABLE +#define __HAL_RCC_GET_PLLCLKOUT_CONFIG __HAL_RCC_GET_PLL1_CLKOUT_CONFIG + +#define __HAL_RCC_PLL2FRACN_ENABLE __HAL_RCC_PLL2_FRACN_ENABLE +#define __HAL_RCC_PLL2FRACN_DISABLE __HAL_RCC_PLL2_FRACN_DISABLE +#define __HAL_RCC_PLL2CLKOUT_ENABLE __HAL_RCC_PLL2_CLKOUT_ENABLE +#define __HAL_RCC_PLL2CLKOUT_DISABLE __HAL_RCC_PLL2_CLKOUT_DISABLE +#define __HAL_RCC_PLL2FRACN_CONFIG __HAL_RCC_PLL2_FRACN_CONFIG +#define __HAL_RCC_GET_PLL2CLKOUT_CONFIG __HAL_RCC_GET_PLL2_CLKOUT_CONFIG + +#define __HAL_RCC_PLL3FRACN_ENABLE __HAL_RCC_PLL3_FRACN_ENABLE +#define __HAL_RCC_PLL3FRACN_DISABLE __HAL_RCC_PLL3_FRACN_DISABLE +#define __HAL_RCC_PLL3CLKOUT_ENABLE __HAL_RCC_PLL3_CLKOUT_ENABLE +#define __HAL_RCC_PLL3CLKOUT_DISABLE __HAL_RCC_PLL3_CLKOUT_DISABLE +#define __HAL_RCC_PLL3FRACN_CONFIG __HAL_RCC_PLL3_FRACN_CONFIG +#define __HAL_RCC_GET_PLL3CLKOUT_CONFIG __HAL_RCC_GET_PLL3_CLKOUT_CONFIG + +#define RCC_PLL2VCIRANGE_0 RCC_PLL2_VCIRANGE_0 +#define RCC_PLL2VCIRANGE_1 RCC_PLL2_VCIRANGE_1 +#define RCC_PLL2VCIRANGE_2 RCC_PLL2_VCIRANGE_2 +#define RCC_PLL2VCIRANGE_3 RCC_PLL2_VCIRANGE_3 + +#define RCC_PLL2VCOWIDE RCC_PLL2_VCORANGE_WIDE +#define RCC_PLL2VCOMEDIUM RCC_PLL2_VCORANGE_MEDIUM + +#define RCC_PLL2SOURCE_NONE RCC_PLL2_SOURCE_NONE +#define RCC_PLL2SOURCE_HSI RCC_PLL2_SOURCE_HSI +#define RCC_PLL2SOURCE_CSI RCC_PLL2_SOURCE_CSI +#define RCC_PLL2SOURCE_HSE RCC_PLL2_SOURCE_HSE + +#define RCC_PLL3VCIRANGE_0 RCC_PLL3_VCIRANGE_0 +#define RCC_PLL3VCIRANGE_1 RCC_PLL3_VCIRANGE_1 +#define RCC_PLL3VCIRANGE_2 RCC_PLL3_VCIRANGE_2 +#define RCC_PLL3VCIRANGE_3 RCC_PLL3_VCIRANGE_3 + +#define RCC_PLL3VCOWIDE RCC_PLL3_VCORANGE_WIDE +#define RCC_PLL3VCOMEDIUM RCC_PLL3_VCORANGE_MEDIUM + +#define RCC_PLL3SOURCE_NONE RCC_PLL3_SOURCE_NONE +#define RCC_PLL3SOURCE_HSI RCC_PLL3_SOURCE_HSI +#define RCC_PLL3SOURCE_CSI RCC_PLL3_SOURCE_CSI +#define RCC_PLL3SOURCE_HSE RCC_PLL3_SOURCE_HSE + + +#endif /* STM32H5 */ + +/** + * @} + */ + +/** @defgroup HAL_RNG_Aliased_Macros HAL RNG Aliased Macros maintained for legacy purpose + * @{ + */ +#define HAL_RNG_ReadyCallback(__HANDLE__) \ + HAL_RNG_ReadyDataCallback((__HANDLE__), uint32_t random32bit) + +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Macros HAL RTC Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined(STM32G0) || defined(STM32L5) || defined(STM32L412xx) || \ + defined(STM32L422xx) || defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ + defined(STM32G4) || defined(STM32WL) || defined(STM32U5) || defined(STM32WBA) || \ + defined(STM32H5) || defined(STM32C0) +#else +#define __HAL_RTC_CLEAR_FLAG __HAL_RTC_EXTI_CLEAR_FLAG +#endif +#define __HAL_RTC_DISABLE_IT __HAL_RTC_EXTI_DISABLE_IT +#define __HAL_RTC_ENABLE_IT __HAL_RTC_EXTI_ENABLE_IT + +#if defined(STM32F1) +#define __HAL_RTC_EXTI_CLEAR_FLAG(RTC_EXTI_LINE_ALARM_EVENT) \ + __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() + +#define __HAL_RTC_EXTI_ENABLE_IT(RTC_EXTI_LINE_ALARM_EVENT) \ + __HAL_RTC_ALARM_EXTI_ENABLE_IT() + +#define __HAL_RTC_EXTI_DISABLE_IT(RTC_EXTI_LINE_ALARM_EVENT) \ + __HAL_RTC_ALARM_EXTI_DISABLE_IT() + +#define __HAL_RTC_EXTI_GET_FLAG(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_GET_FLAG() + +#define __HAL_RTC_EXTI_GENERATE_SWIT(RTC_EXTI_LINE_ALARM_EVENT) \ + __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() +#else +#define __HAL_RTC_EXTI_CLEAR_FLAG(__EXTI_LINE__) \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) \ + ? __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() \ + : (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) \ + ? __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG() \ + : __HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG())) +#define __HAL_RTC_EXTI_ENABLE_IT(__EXTI_LINE__) \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) \ + ? __HAL_RTC_ALARM_EXTI_ENABLE_IT() \ + : (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) \ + ? __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT() \ + : __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_IT())) +#define __HAL_RTC_EXTI_DISABLE_IT(__EXTI_LINE__) \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) \ + ? __HAL_RTC_ALARM_EXTI_DISABLE_IT() \ + : (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) \ + ? __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_IT() \ + : __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_IT())) +#define __HAL_RTC_EXTI_GET_FLAG(__EXTI_LINE__) \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) \ + ? __HAL_RTC_ALARM_EXTI_GET_FLAG() \ + : (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) \ + ? __HAL_RTC_WAKEUPTIMER_EXTI_GET_FLAG() \ + : __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GET_FLAG())) +#define __HAL_RTC_EXTI_GENERATE_SWIT(__EXTI_LINE__) \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) \ + ? __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() \ + : (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) \ + ? __HAL_RTC_WAKEUPTIMER_EXTI_GENERATE_SWIT() \ + : __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GENERATE_SWIT())) +#endif /* STM32F1 */ + +#define IS_ALARM IS_RTC_ALARM +#define IS_ALARM_MASK IS_RTC_ALARM_MASK +#define IS_TAMPER IS_RTC_TAMPER +#define IS_TAMPER_ERASE_MODE IS_RTC_TAMPER_ERASE_MODE +#define IS_TAMPER_FILTER IS_RTC_TAMPER_FILTER +#define IS_TAMPER_INTERRUPT IS_RTC_TAMPER_INTERRUPT +#define IS_TAMPER_MASKFLAG_STATE IS_RTC_TAMPER_MASKFLAG_STATE +#define IS_TAMPER_PRECHARGE_DURATION IS_RTC_TAMPER_PRECHARGE_DURATION +#define IS_TAMPER_PULLUP_STATE IS_RTC_TAMPER_PULLUP_STATE +#define IS_TAMPER_SAMPLING_FREQ IS_RTC_TAMPER_SAMPLING_FREQ +#define IS_TAMPER_TIMESTAMPONTAMPER_DETECTION IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION +#define IS_TAMPER_TRIGGER IS_RTC_TAMPER_TRIGGER +#define IS_WAKEUP_CLOCK IS_RTC_WAKEUP_CLOCK +#define IS_WAKEUP_COUNTER IS_RTC_WAKEUP_COUNTER + +#define __RTC_WRITEPROTECTION_ENABLE __HAL_RTC_WRITEPROTECTION_ENABLE +#define __RTC_WRITEPROTECTION_DISABLE __HAL_RTC_WRITEPROTECTION_DISABLE + +#if defined(STM32H5) +#define __HAL_RCC_RTCAPB_CLK_ENABLE __HAL_RCC_RTC_CLK_ENABLE +#define __HAL_RCC_RTCAPB_CLK_DISABLE __HAL_RCC_RTC_CLK_DISABLE +#endif /* STM32H5 */ + + /** + * @} + */ + + /** @defgroup HAL_SD_Aliased_Macros HAL SD/MMC Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define SD_OCR_CID_CSD_OVERWRIETE SD_OCR_CID_CSD_OVERWRITE +#define SD_CMD_SD_APP_STAUS SD_CMD_SD_APP_STATUS + +#if !defined(STM32F1) && !defined(STM32F2) && !defined(STM32F4) && !defined(STM32L1) +#define eMMC_HIGH_VOLTAGE_RANGE EMMC_HIGH_VOLTAGE_RANGE +#define eMMC_DUAL_VOLTAGE_RANGE EMMC_DUAL_VOLTAGE_RANGE +#define eMMC_LOW_VOLTAGE_RANGE EMMC_LOW_VOLTAGE_RANGE + +#define SDMMC_NSpeed_CLK_DIV SDMMC_NSPEED_CLK_DIV +#define SDMMC_HSpeed_CLK_DIV SDMMC_HSPEED_CLK_DIV +#endif + +#if defined(STM32F4) || defined(STM32F2) +#define SD_SDMMC_DISABLED SD_SDIO_DISABLED +#define SD_SDMMC_FUNCTION_BUSY SD_SDIO_FUNCTION_BUSY +#define SD_SDMMC_FUNCTION_FAILED SD_SDIO_FUNCTION_FAILED +#define SD_SDMMC_UNKNOWN_FUNCTION SD_SDIO_UNKNOWN_FUNCTION +#define SD_CMD_SDMMC_SEN_OP_COND SD_CMD_SDIO_SEN_OP_COND +#define SD_CMD_SDMMC_RW_DIRECT SD_CMD_SDIO_RW_DIRECT +#define SD_CMD_SDMMC_RW_EXTENDED SD_CMD_SDIO_RW_EXTENDED +#define __HAL_SD_SDMMC_ENABLE __HAL_SD_SDIO_ENABLE +#define __HAL_SD_SDMMC_DISABLE __HAL_SD_SDIO_DISABLE +#define __HAL_SD_SDMMC_DMA_ENABLE __HAL_SD_SDIO_DMA_ENABLE +#define __HAL_SD_SDMMC_DMA_DISABLE __HAL_SD_SDIO_DMA_DISABL +#define __HAL_SD_SDMMC_ENABLE_IT __HAL_SD_SDIO_ENABLE_IT +#define __HAL_SD_SDMMC_DISABLE_IT __HAL_SD_SDIO_DISABLE_IT +#define __HAL_SD_SDMMC_GET_FLAG __HAL_SD_SDIO_GET_FLAG +#define __HAL_SD_SDMMC_CLEAR_FLAG __HAL_SD_SDIO_CLEAR_FLAG +#define __HAL_SD_SDMMC_GET_IT __HAL_SD_SDIO_GET_IT +#define __HAL_SD_SDMMC_CLEAR_IT __HAL_SD_SDIO_CLEAR_IT +#define SDMMC_STATIC_FLAGS SDIO_STATIC_FLAGS +#define SDMMC_CMD0TIMEOUT SDIO_CMD0TIMEOUT +#define SD_SDMMC_SEND_IF_COND SD_SDIO_SEND_IF_COND +/* alias CMSIS */ +#define SDMMC1_IRQn SDIO_IRQn +#define SDMMC1_IRQHandler SDIO_IRQHandler +#endif + +#if defined(STM32F7) || defined(STM32L4) +#define SD_SDIO_DISABLED SD_SDMMC_DISABLED +#define SD_SDIO_FUNCTION_BUSY SD_SDMMC_FUNCTION_BUSY +#define SD_SDIO_FUNCTION_FAILED SD_SDMMC_FUNCTION_FAILED +#define SD_SDIO_UNKNOWN_FUNCTION SD_SDMMC_UNKNOWN_FUNCTION +#define SD_CMD_SDIO_SEN_OP_COND SD_CMD_SDMMC_SEN_OP_COND +#define SD_CMD_SDIO_RW_DIRECT SD_CMD_SDMMC_RW_DIRECT +#define SD_CMD_SDIO_RW_EXTENDED SD_CMD_SDMMC_RW_EXTENDED +#define __HAL_SD_SDIO_ENABLE __HAL_SD_SDMMC_ENABLE +#define __HAL_SD_SDIO_DISABLE __HAL_SD_SDMMC_DISABLE +#define __HAL_SD_SDIO_DMA_ENABLE __HAL_SD_SDMMC_DMA_ENABLE +#define __HAL_SD_SDIO_DMA_DISABL __HAL_SD_SDMMC_DMA_DISABLE +#define __HAL_SD_SDIO_ENABLE_IT __HAL_SD_SDMMC_ENABLE_IT +#define __HAL_SD_SDIO_DISABLE_IT __HAL_SD_SDMMC_DISABLE_IT +#define __HAL_SD_SDIO_GET_FLAG __HAL_SD_SDMMC_GET_FLAG +#define __HAL_SD_SDIO_CLEAR_FLAG __HAL_SD_SDMMC_CLEAR_FLAG +#define __HAL_SD_SDIO_GET_IT __HAL_SD_SDMMC_GET_IT +#define __HAL_SD_SDIO_CLEAR_IT __HAL_SD_SDMMC_CLEAR_IT +#define SDIO_STATIC_FLAGS SDMMC_STATIC_FLAGS +#define SDIO_CMD0TIMEOUT SDMMC_CMD0TIMEOUT +#define SD_SDIO_SEND_IF_COND SD_SDMMC_SEND_IF_COND +/* alias CMSIS for compatibilities */ +#define SDIO_IRQn SDMMC1_IRQn +#define SDIO_IRQHandler SDMMC1_IRQHandler +#endif + +#if defined(STM32F7) || defined(STM32F4) || defined(STM32F2) || defined(STM32L4) || \ + defined(STM32H7) +#define HAL_SD_CardCIDTypedef HAL_SD_CardCIDTypeDef +#define HAL_SD_CardCSDTypedef HAL_SD_CardCSDTypeDef +#define HAL_SD_CardStatusTypedef HAL_SD_CardStatusTypeDef +#define HAL_SD_CardStateTypedef HAL_SD_CardStateTypeDef +#endif + +#if defined(STM32H7) || defined(STM32L5) +#define HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback \ + HAL_MMCEx_Read_DMADoubleBuf0CpltCallback +#define HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback \ + HAL_MMCEx_Read_DMADoubleBuf1CpltCallback +#define HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback \ + HAL_MMCEx_Write_DMADoubleBuf0CpltCallback +#define HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback \ + HAL_MMCEx_Write_DMADoubleBuf1CpltCallback +#define HAL_SDEx_Read_DMADoubleBuffer0CpltCallback HAL_SDEx_Read_DMADoubleBuf0CpltCallback +#define HAL_SDEx_Read_DMADoubleBuffer1CpltCallback HAL_SDEx_Read_DMADoubleBuf1CpltCallback +#define HAL_SDEx_Write_DMADoubleBuffer0CpltCallback \ + HAL_SDEx_Write_DMADoubleBuf0CpltCallback +#define HAL_SDEx_Write_DMADoubleBuffer1CpltCallback \ + HAL_SDEx_Write_DMADoubleBuf1CpltCallback +#define HAL_SD_DriveTransciver_1_8V_Callback HAL_SD_DriveTransceiver_1_8V_Callback +#endif + /** + * @} + */ + + /** @defgroup HAL_SMARTCARD_Aliased_Macros HAL SMARTCARD Aliased Macros maintained for + * legacy purpose + * @{ + */ + +#define __SMARTCARD_ENABLE_IT __HAL_SMARTCARD_ENABLE_IT +#define __SMARTCARD_DISABLE_IT __HAL_SMARTCARD_DISABLE_IT +#define __SMARTCARD_ENABLE __HAL_SMARTCARD_ENABLE +#define __SMARTCARD_DISABLE __HAL_SMARTCARD_DISABLE +#define __SMARTCARD_DMA_REQUEST_ENABLE __HAL_SMARTCARD_DMA_REQUEST_ENABLE +#define __SMARTCARD_DMA_REQUEST_DISABLE __HAL_SMARTCARD_DMA_REQUEST_DISABLE + +#define __HAL_SMARTCARD_GETCLOCKSOURCE SMARTCARD_GETCLOCKSOURCE +#define __SMARTCARD_GETCLOCKSOURCE SMARTCARD_GETCLOCKSOURCE + +#define IS_SMARTCARD_ONEBIT_SAMPLING IS_SMARTCARD_ONE_BIT_SAMPLE + +/** + * @} + */ + +/** @defgroup HAL_SMBUS_Aliased_Macros HAL SMBUS Aliased Macros maintained for legacy + * purpose + * @{ + */ +#define __HAL_SMBUS_RESET_CR1 SMBUS_RESET_CR1 +#define __HAL_SMBUS_RESET_CR2 SMBUS_RESET_CR2 +#define __HAL_SMBUS_GENERATE_START SMBUS_GENERATE_START +#define __HAL_SMBUS_GET_ADDR_MATCH SMBUS_GET_ADDR_MATCH +#define __HAL_SMBUS_GET_DIR SMBUS_GET_DIR +#define __HAL_SMBUS_GET_STOP_MODE SMBUS_GET_STOP_MODE +#define __HAL_SMBUS_GET_PEC_MODE SMBUS_GET_PEC_MODE +#define __HAL_SMBUS_GET_ALERT_ENABLED SMBUS_GET_ALERT_ENABLED + /** + * @} + */ + + /** @defgroup HAL_SPI_Aliased_Macros HAL SPI Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define __HAL_SPI_1LINE_TX SPI_1LINE_TX +#define __HAL_SPI_1LINE_RX SPI_1LINE_RX +#define __HAL_SPI_RESET_CRC SPI_RESET_CRC + + /** + * @} + */ + + /** @defgroup HAL_UART_Aliased_Macros HAL UART Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define __HAL_UART_GETCLOCKSOURCE UART_GETCLOCKSOURCE +#define __HAL_UART_MASK_COMPUTATION UART_MASK_COMPUTATION +#define __UART_GETCLOCKSOURCE UART_GETCLOCKSOURCE +#define __UART_MASK_COMPUTATION UART_MASK_COMPUTATION + +#define IS_UART_WAKEUPMETHODE IS_UART_WAKEUPMETHOD + +#define IS_UART_ONEBIT_SAMPLE IS_UART_ONE_BIT_SAMPLE +#define IS_UART_ONEBIT_SAMPLING IS_UART_ONE_BIT_SAMPLE + + /** + * @} + */ + + + /** @defgroup HAL_USART_Aliased_Macros HAL USART Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define __USART_ENABLE_IT __HAL_USART_ENABLE_IT +#define __USART_DISABLE_IT __HAL_USART_DISABLE_IT +#define __USART_ENABLE __HAL_USART_ENABLE +#define __USART_DISABLE __HAL_USART_DISABLE + +#define __HAL_USART_GETCLOCKSOURCE USART_GETCLOCKSOURCE +#define __USART_GETCLOCKSOURCE USART_GETCLOCKSOURCE + +#if defined(STM32F0) || defined(STM32F3) || defined(STM32F7) +#define USART_OVERSAMPLING_16 0x00000000U +#define USART_OVERSAMPLING_8 USART_CR1_OVER8 + +#define IS_USART_OVERSAMPLING(__SAMPLING__) \ + (((__SAMPLING__) == USART_OVERSAMPLING_16) || \ + ((__SAMPLING__) == USART_OVERSAMPLING_8)) +#endif /* STM32F0 || STM32F3 || STM32F7 */ +/** + * @} + */ + +/** @defgroup HAL_USB_Aliased_Macros HAL USB Aliased Macros maintained for legacy purpose + * @{ + */ +#define USB_EXTI_LINE_WAKEUP USB_WAKEUP_EXTI_LINE + +#define USB_FS_EXTI_TRIGGER_RISING_EDGE USB_OTG_FS_WAKEUP_EXTI_RISING_EDGE +#define USB_FS_EXTI_TRIGGER_FALLING_EDGE USB_OTG_FS_WAKEUP_EXTI_FALLING_EDGE +#define USB_FS_EXTI_TRIGGER_BOTH_EDGE USB_OTG_FS_WAKEUP_EXTI_RISING_FALLING_EDGE +#define USB_FS_EXTI_LINE_WAKEUP USB_OTG_FS_WAKEUP_EXTI_LINE + +#define USB_HS_EXTI_TRIGGER_RISING_EDGE USB_OTG_HS_WAKEUP_EXTI_RISING_EDGE +#define USB_HS_EXTI_TRIGGER_FALLING_EDGE USB_OTG_HS_WAKEUP_EXTI_FALLING_EDGE +#define USB_HS_EXTI_TRIGGER_BOTH_EDGE USB_OTG_HS_WAKEUP_EXTI_RISING_FALLING_EDGE +#define USB_HS_EXTI_LINE_WAKEUP USB_OTG_HS_WAKEUP_EXTI_LINE + +#define __HAL_USB_EXTI_ENABLE_IT __HAL_USB_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_EXTI_DISABLE_IT __HAL_USB_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_EXTI_GET_FLAG __HAL_USB_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_EXTI_CLEAR_FLAG __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_EXTI_SET_RISING_EDGE_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_EXTI_SET_FALLING_EDGE_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_EXTI_SET_FALLINGRISING_TRIGGER \ + __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE + +#define __HAL_USB_FS_EXTI_ENABLE_IT __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_FS_EXTI_DISABLE_IT __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_FS_EXTI_GET_FLAG __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_FS_EXTI_CLEAR_FLAG __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_FS_EXTI_SET_RISING_EGDE_TRIGGER \ + __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_FS_EXTI_SET_FALLING_EGDE_TRIGGER \ + __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_FS_EXTI_SET_FALLINGRISING_TRIGGER \ + __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE +#define __HAL_USB_FS_EXTI_GENERATE_SWIT __HAL_USB_OTG_FS_WAKEUP_EXTI_GENERATE_SWIT + +#define __HAL_USB_HS_EXTI_ENABLE_IT __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_HS_EXTI_DISABLE_IT __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_HS_EXTI_GET_FLAG __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_HS_EXTI_CLEAR_FLAG __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_HS_EXTI_SET_RISING_EGDE_TRIGGER \ + __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_HS_EXTI_SET_FALLING_EGDE_TRIGGER \ + __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_HS_EXTI_SET_FALLINGRISING_TRIGGER \ + __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE +#define __HAL_USB_HS_EXTI_GENERATE_SWIT __HAL_USB_OTG_HS_WAKEUP_EXTI_GENERATE_SWIT + +#define HAL_PCD_ActiveRemoteWakeup HAL_PCD_ActivateRemoteWakeup +#define HAL_PCD_DeActiveRemoteWakeup HAL_PCD_DeActivateRemoteWakeup + +#define HAL_PCD_SetTxFiFo HAL_PCDEx_SetTxFiFo +#define HAL_PCD_SetRxFiFo HAL_PCDEx_SetRxFiFo +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Macros HAL TIM Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_TIM_SetICPrescalerValue TIM_SET_ICPRESCALERVALUE +#define __HAL_TIM_ResetICPrescalerValue TIM_RESET_ICPRESCALERVALUE + +#define TIM_GET_ITSTATUS __HAL_TIM_GET_IT_SOURCE +#define TIM_GET_CLEAR_IT __HAL_TIM_CLEAR_IT + +#define __HAL_TIM_GET_ITSTATUS __HAL_TIM_GET_IT_SOURCE + +#define __HAL_TIM_DIRECTION_STATUS __HAL_TIM_IS_TIM_COUNTING_DOWN +#define __HAL_TIM_PRESCALER __HAL_TIM_SET_PRESCALER +#define __HAL_TIM_SetCounter __HAL_TIM_SET_COUNTER +#define __HAL_TIM_GetCounter __HAL_TIM_GET_COUNTER +#define __HAL_TIM_SetAutoreload __HAL_TIM_SET_AUTORELOAD +#define __HAL_TIM_GetAutoreload __HAL_TIM_GET_AUTORELOAD +#define __HAL_TIM_SetClockDivision __HAL_TIM_SET_CLOCKDIVISION +#define __HAL_TIM_GetClockDivision __HAL_TIM_GET_CLOCKDIVISION +#define __HAL_TIM_SetICPrescaler __HAL_TIM_SET_ICPRESCALER +#define __HAL_TIM_GetICPrescaler __HAL_TIM_GET_ICPRESCALER +#define __HAL_TIM_SetCompare __HAL_TIM_SET_COMPARE +#define __HAL_TIM_GetCompare __HAL_TIM_GET_COMPARE + +#define TIM_BREAKINPUTSOURCE_DFSDM TIM_BREAKINPUTSOURCE_DFSDM1 + /** + * @} + */ + + /** @defgroup HAL_ETH_Aliased_Macros HAL ETH Aliased Macros maintained for legacy + * purpose + * @{ + */ + +#define __HAL_ETH_EXTI_ENABLE_IT __HAL_ETH_WAKEUP_EXTI_ENABLE_IT +#define __HAL_ETH_EXTI_DISABLE_IT __HAL_ETH_WAKEUP_EXTI_DISABLE_IT +#define __HAL_ETH_EXTI_GET_FLAG __HAL_ETH_WAKEUP_EXTI_GET_FLAG +#define __HAL_ETH_EXTI_CLEAR_FLAG __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_ETH_EXTI_SET_RISING_EGDE_TRIGGER \ + __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE_TRIGGER +#define __HAL_ETH_EXTI_SET_FALLING_EGDE_TRIGGER \ + __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE_TRIGGER +#define __HAL_ETH_EXTI_SET_FALLINGRISING_TRIGGER \ + __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLINGRISING_TRIGGER + +#define ETH_PROMISCIOUSMODE_ENABLE ETH_PROMISCUOUS_MODE_ENABLE +#define ETH_PROMISCIOUSMODE_DISABLE ETH_PROMISCUOUS_MODE_DISABLE +#define IS_ETH_PROMISCIOUS_MODE IS_ETH_PROMISCUOUS_MODE +/** + * @} + */ + +/** @defgroup HAL_LTDC_Aliased_Macros HAL LTDC Aliased Macros maintained for legacy + * purpose + * @{ + */ +#define __HAL_LTDC_LAYER LTDC_LAYER +#define __HAL_LTDC_RELOAD_CONFIG __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG +/** + * @} + */ + +/** @defgroup HAL_SAI_Aliased_Macros HAL SAI Aliased Macros maintained for legacy purpose + * @{ + */ +#define SAI_OUTPUTDRIVE_DISABLED SAI_OUTPUTDRIVE_DISABLE +#define SAI_OUTPUTDRIVE_ENABLED SAI_OUTPUTDRIVE_ENABLE +#define SAI_MASTERDIVIDER_ENABLED SAI_MASTERDIVIDER_ENABLE +#define SAI_MASTERDIVIDER_DISABLED SAI_MASTERDIVIDER_DISABLE +#define SAI_STREOMODE SAI_STEREOMODE +#define SAI_FIFOStatus_Empty SAI_FIFOSTATUS_EMPTY +#define SAI_FIFOStatus_Less1QuarterFull SAI_FIFOSTATUS_LESS1QUARTERFULL +#define SAI_FIFOStatus_1QuarterFull SAI_FIFOSTATUS_1QUARTERFULL +#define SAI_FIFOStatus_HalfFull SAI_FIFOSTATUS_HALFFULL +#define SAI_FIFOStatus_3QuartersFull SAI_FIFOSTATUS_3QUARTERFULL +#define SAI_FIFOStatus_Full SAI_FIFOSTATUS_FULL +#define IS_SAI_BLOCK_MONO_STREO_MODE IS_SAI_BLOCK_MONO_STEREO_MODE +#define SAI_SYNCHRONOUS_EXT SAI_SYNCHRONOUS_EXT_SAI1 +#define SAI_SYNCEXT_IN_ENABLE SAI_SYNCEXT_OUTBLOCKA_ENABLE +/** + * @} + */ + +/** @defgroup HAL_SPDIFRX_Aliased_Macros HAL SPDIFRX Aliased Macros maintained for legacy + * purpose + * @{ + */ +#if defined(STM32H7) +#define HAL_SPDIFRX_ReceiveControlFlow HAL_SPDIFRX_ReceiveCtrlFlow +#define HAL_SPDIFRX_ReceiveControlFlow_IT HAL_SPDIFRX_ReceiveCtrlFlow_IT +#define HAL_SPDIFRX_ReceiveControlFlow_DMA HAL_SPDIFRX_ReceiveCtrlFlow_DMA +#endif +/** + * @} + */ + +/** @defgroup HAL_HRTIM_Aliased_Functions HAL HRTIM Aliased Functions maintained for + * legacy purpose + * @{ + */ +#if defined(STM32H7) || defined(STM32G4) || defined(STM32F3) +#define HAL_HRTIM_WaveformCounterStart_IT HAL_HRTIM_WaveformCountStart_IT +#define HAL_HRTIM_WaveformCounterStart_DMA HAL_HRTIM_WaveformCountStart_DMA +#define HAL_HRTIM_WaveformCounterStart HAL_HRTIM_WaveformCountStart +#define HAL_HRTIM_WaveformCounterStop_IT HAL_HRTIM_WaveformCountStop_IT +#define HAL_HRTIM_WaveformCounterStop_DMA HAL_HRTIM_WaveformCountStop_DMA +#define HAL_HRTIM_WaveformCounterStop HAL_HRTIM_WaveformCountStop +#endif +/** + * @} + */ + +/** @defgroup HAL_QSPI_Aliased_Macros HAL QSPI Aliased Macros maintained for legacy + * purpose + * @{ + */ +#if defined(STM32L4) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7) +#define HAL_QPSI_TIMEOUT_DEFAULT_VALUE HAL_QSPI_TIMEOUT_DEFAULT_VALUE +#endif /* STM32L4 || STM32F4 || STM32F7 */ +/** + * @} + */ + +/** @defgroup HAL_Generic_Aliased_Macros HAL Generic Aliased Macros maintained for legacy + * purpose + * @{ + */ +#if defined(STM32F7) +#define ART_ACCLERATOR_ENABLE ART_ACCELERATOR_ENABLE +#endif /* STM32F7 */ + /** + * @} + */ + + /** @defgroup HAL_PPP_Aliased_Macros HAL PPP Aliased Macros maintained for legacy + * purpose + * @{ + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32_HAL_LEGACY */ diff --git a/src/firmware/motor/stm32f0xx/stm32f031x6.h b/src/firmware/motor/stm32f0xx/stm32f031x6.h new file mode 100644 index 0000000000..4687d4db7b --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f031x6.h @@ -0,0 +1,6074 @@ +/** + ****************************************************************************** + * @file stm32f031x6.h + * @author MCD Application Team + * @brief CMSIS Cortex-M0 Device Peripheral Access Layer Header File. + * This file contains all the peripheral register's definitions, bits + * definitions and memory mapping for STM32F0xx devices. + * + * This file contains: + * - Data structures and the address mapping for all peripherals + * - Peripheral's registers declarations and bits definition + * - Macros to access peripheral's registers hardware + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f031x6 + * @{ + */ + +#ifndef __STM32F031x6_H +#define __STM32F031x6_H + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ +/** + * @brief Configuration of the Cortex-M0 Processor and Core Peripherals + */ +#define __CM0_REV 0 /*!< Core Revision r0p0 */ +#define __MPU_PRESENT 0 /*!< STM32F0xx do not provide MPU */ +#define __NVIC_PRIO_BITS 2 /*!< STM32F0xx uses 2 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + + /** + * @} + */ + + /** @addtogroup Peripheral_interrupt_number_definition + * @{ + */ + + /** + * @brief STM32F0xx Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ + + /*!< Interrupt Number Definition */ + typedef enum + { + /****** Cortex-M0 Processor Exceptions Numbers + **************************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */ + + /****** STM32F0 specific Interrupt Numbers + ******************************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD Interrupt through EXTI Lines 16 */ + RTC_IRQn = 2, /*!< RTC Interrupt through EXTI Lines 17, 19 and 20 */ + FLASH_IRQn = 3, /*!< FLASH global Interrupt */ + RCC_IRQn = 4, /*!< RCC global Interrupt */ + EXTI0_1_IRQn = 5, /*!< EXTI Line 0 and 1 Interrupt */ + EXTI2_3_IRQn = 6, /*!< EXTI Line 2 and 3 Interrupt */ + EXTI4_15_IRQn = 7, /*!< EXTI Line 4 to 15 Interrupt */ + DMA1_Channel1_IRQn = 9, /*!< DMA1 Channel 1 Interrupt */ + DMA1_Channel2_3_IRQn = 10, /*!< DMA1 Channel 2 and Channel 3 Interrupt */ + DMA1_Channel4_5_IRQn = 11, /*!< DMA1 Channel 4 and Channel 5 Interrupt */ + ADC1_IRQn = 12, /*!< ADC1 Interrupt */ + TIM1_BRK_UP_TRG_COM_IRQn = + 13, /*!< TIM1 Break, Update, Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 14, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 15, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 16, /*!< TIM3 global Interrupt */ + TIM14_IRQn = 19, /*!< TIM14 global Interrupt */ + TIM16_IRQn = 21, /*!< TIM16 global Interrupt */ + TIM17_IRQn = 22, /*!< TIM17 global Interrupt */ + I2C1_IRQn = 23, /*!< I2C1 Event Interrupt & EXTI Line23 Interrupt (I2C1 wakeup) */ + SPI1_IRQn = 25, /*!< SPI1 global Interrupt */ + USART1_IRQn = + 27 /*!< USART1 global Interrupt & EXTI Line25 Interrupt (USART1 wakeup) */ + } IRQn_Type; + + /** + * @} + */ + +#include + +#include "firmware/motor/cmsis/core_cm0.h" /* Cortex-M0 processor and core peripherals */ +#include "firmware/motor/stm32f0xx/system_stm32f0xx.h" /* STM32F0xx System Header */ + + /** @addtogroup Peripheral_registers_structures + * @{ + */ + + /** + * @brief Analog to Digital Converter + */ + + typedef struct + { + __IO uint32_t ISR; /*!< ADC interrupt and status register, Address + offset: 0x00 */ + __IO uint32_t IER; /*!< ADC interrupt enable register, Address + offset: 0x04 */ + __IO uint32_t CR; /*!< ADC control register, Address + offset: 0x08 */ + __IO uint32_t CFGR1; /*!< ADC configuration register 1, Address + offset: 0x0C */ + __IO uint32_t CFGR2; /*!< ADC configuration register 2, Address + offset: 0x10 */ + __IO uint32_t SMPR; /*!< ADC sampling time register, Address + offset: 0x14 */ + uint32_t RESERVED1; /*!< Reserved, 0x18 */ + uint32_t RESERVED2; /*!< Reserved, 0x1C */ + __IO uint32_t TR; /*!< ADC analog watchdog 1 threshold register, Address + offset: 0x20 */ + uint32_t RESERVED3; /*!< Reserved, 0x24 */ + __IO uint32_t CHSELR; /*!< ADC group regular sequencer register, Address + offset: 0x28 */ + uint32_t RESERVED4[5]; /*!< Reserved, 0x2C */ + __IO uint32_t DR; /*!< ADC group regular data register, Address + offset: 0x40 */ + } ADC_TypeDef; + + typedef struct + { + __IO uint32_t CCR; /*!< ADC common configuration register, Address + offset: ADC1 base address + 0x308 */ + } ADC_Common_TypeDef; + + /** + * @brief CRC calculation unit + */ + + typedef struct + { + __IO uint32_t + DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t + IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t + CR; /*!< CRC Control register, Address offset: 0x08 */ + uint32_t RESERVED2; /*!< Reserved, 0x0C */ + __IO uint32_t INIT; /*!< Initial CRC value register, Address + offset: 0x10 */ + __IO uint32_t RESERVED3; /*!< Reserved, 0x14 */ + } CRC_TypeDef; + + /** + * @brief Debug MCU + */ + + typedef struct + { + __IO uint32_t IDCODE; /*!< MCU device ID code, Address + offset: 0x00 */ + __IO uint32_t + CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address + offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address + offset: 0x0C */ + } DBGMCU_TypeDef; + + /** + * @brief DMA Controller + */ + + typedef struct + { + __IO uint32_t CCR; /*!< DMA channel x configuration register */ + __IO uint32_t CNDTR; /*!< DMA channel x number of data register */ + __IO uint32_t CPAR; /*!< DMA channel x peripheral address register */ + __IO uint32_t CMAR; /*!< DMA channel x memory address register */ + } DMA_Channel_TypeDef; + + typedef struct + { + __IO uint32_t + ISR; /*!< DMA interrupt status register, Address offset: 0x00 */ + __IO uint32_t IFCR; /*!< DMA interrupt flag clear register, Address + offset: 0x04 */ + } DMA_TypeDef; + + /** + * @brief External Interrupt/Event Controller + */ + + typedef struct + { + __IO uint32_t + IMR; /*! 0U) + { + return HAL_ERROR; + } + + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); + uwTickPrio = TickPriority; + } + else + { + return HAL_ERROR; + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions + * @brief HAL Control functions + * +@verbatim + =============================================================================== + ##### HAL Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Provide a tick value in millisecond + (+) Provide a blocking delay in millisecond + (+) Suspend the time base source interrupt + (+) Resume the time base source interrupt + (+) Get the HAL API driver version + (+) Get the device identifier + (+) Get the device revision identifier + (+) Enable/Disable Debug module during Sleep mode + (+) Enable/Disable Debug module during STOP mode + (+) Enable/Disable Debug module during STANDBY mode + +@endverbatim + * @{ + */ + +/** + * @brief This function is called to increment a global variable "uwTick" + * used as application time base. + * @note In the default implementation, this variable is incremented each 1ms + * in SysTick ISR. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_IncTick(void) +{ + uwTick += uwTickFreq; +} + +/** + * @brief Provides a tick value in millisecond. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval tick value + */ +__weak uint32_t HAL_GetTick(void) +{ + return uwTick; +} + +/** + * @brief This function returns a tick priority. + * @retval tick priority + */ +uint32_t HAL_GetTickPrio(void) +{ + return uwTickPrio; +} + +/** + * @brief Set new tick Freq. + * @retval status + */ +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_TickFreqTypeDef prevTickFreq; + + assert_param(IS_TICKFREQ(Freq)); + + if (uwTickFreq != Freq) + { + /* Back up uwTickFreq frequency */ + prevTickFreq = uwTickFreq; + + /* Update uwTickFreq global variable used by HAL_InitTick() */ + uwTickFreq = Freq; + + /* Apply the new tick Freq */ + status = HAL_InitTick(uwTickPrio); + + if (status != HAL_OK) + { + /* Restore previous tick frequency */ + uwTickFreq = prevTickFreq; + } + } + + return status; +} + +/** + * @brief return tick frequency. + * @retval Tick frequency. + * Value of @ref HAL_TickFreqTypeDef. + */ +HAL_TickFreqTypeDef HAL_GetTickFreq(void) +{ + return uwTickFreq; +} + +/** + * @brief This function provides accurate delay (in milliseconds) based + * on variable incremented. + * @note In the default implementation , SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals where uwTick + * is incremented. + * @note ThiS function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @param Delay specifies the delay time length, in milliseconds. + * @retval None + */ +__weak void HAL_Delay(uint32_t Delay) +{ + uint32_t tickstart = HAL_GetTick(); + uint32_t wait = Delay; + + /* Add a freq to guarantee minimum wait */ + if (wait < HAL_MAX_DELAY) + { + wait += (uint32_t)(uwTickFreq); + } + + while ((HAL_GetTick() - tickstart) < wait) + { + } +} + +/** + * @brief Suspend Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_SuspendTick() + * is called, the the SysTick interrupt will be disabled and so Tick increment + * is suspended. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_SuspendTick(void) + +{ + /* Disable SysTick Interrupt */ + CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); +} + +/** + * @brief Resume Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_ResumeTick() + * is called, the the SysTick interrupt will be enabled and so Tick increment + * is resumed. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_ResumeTick(void) +{ + /* Enable SysTick Interrupt */ + SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); +} + +/** + * @brief This method returns the HAL revision + * @retval version 0xXYZR (8bits for each decimal, R for RC) + */ +uint32_t HAL_GetHalVersion(void) +{ + return __STM32F0xx_HAL_VERSION; +} + +/** + * @brief Returns the device revision identifier. + * @retval Device revision identifier + */ +uint32_t HAL_GetREVID(void) +{ + return ((DBGMCU->IDCODE) >> 16U); +} + +/** + * @brief Returns the device identifier. + * @retval Device identifier + */ +uint32_t HAL_GetDEVID(void) +{ + return ((DBGMCU->IDCODE) & IDCODE_DEVID_MASK); +} + +/** + * @brief Returns first word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw0(void) +{ + return (READ_REG(*((uint32_t *)UID_BASE))); +} + +/** + * @brief Returns second word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw1(void) +{ + return (READ_REG(*((uint32_t *)(UID_BASE + 4U)))); +} + +/** + * @brief Returns third word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw2(void) +{ + return (READ_REG(*((uint32_t *)(UID_BASE + 8U)))); +} + +/** + * @brief Enable the Debug Module during STOP mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGStopMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Disable the Debug Module during STOP mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGStopMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Enable the Debug Module during STANDBY mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGStandbyMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @brief Disable the Debug Module during STANDBY mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGStandbyMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal.h new file mode 100644 index 0000000000..61ccdd7992 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal.h @@ -0,0 +1,784 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the HAL + * module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_H +#define __STM32F0xx_HAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_conf.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup HAL + * @{ + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup HAL_Private_Macros + * @{ + */ +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F042x6) || \ + defined(STM32F048xx) || defined(STM32F030x6) || defined(STM32F031x6) || \ + defined(STM32F038xx) || defined(STM32F070x6) || defined(STM32F070xB) || \ + defined(STM32F030x6) +#define IS_SYSCFG_FASTMODEPLUS(__PIN__) \ + ((((__PIN__)&SYSCFG_FASTMODEPLUS_PA9) == SYSCFG_FASTMODEPLUS_PA9) || \ + (((__PIN__)&SYSCFG_FASTMODEPLUS_PA10) == SYSCFG_FASTMODEPLUS_PA10) || \ + (((__PIN__)&SYSCFG_FASTMODEPLUS_PB6) == SYSCFG_FASTMODEPLUS_PB6) || \ + (((__PIN__)&SYSCFG_FASTMODEPLUS_PB7) == SYSCFG_FASTMODEPLUS_PB7) || \ + (((__PIN__)&SYSCFG_FASTMODEPLUS_PB8) == SYSCFG_FASTMODEPLUS_PB8) || \ + (((__PIN__)&SYSCFG_FASTMODEPLUS_PB9) == SYSCFG_FASTMODEPLUS_PB9)) +#else +#define IS_SYSCFG_FASTMODEPLUS(__PIN__) \ + ((((__PIN__)&SYSCFG_FASTMODEPLUS_PB6) == SYSCFG_FASTMODEPLUS_PB6) || \ + (((__PIN__)&SYSCFG_FASTMODEPLUS_PB7) == SYSCFG_FASTMODEPLUS_PB7) || \ + (((__PIN__)&SYSCFG_FASTMODEPLUS_PB8) == SYSCFG_FASTMODEPLUS_PB8) || \ + (((__PIN__)&SYSCFG_FASTMODEPLUS_PB9) == SYSCFG_FASTMODEPLUS_PB9)) +#endif +#if defined(SYSCFG_CFGR1_PA11_PA12_RMP) +#define IS_HAL_REMAP_PIN(RMP) ((RMP) == HAL_REMAP_PA11_PA12) +#endif /* SYSCFG_CFGR1_PA11_PA12_RMP */ +#if defined(STM32F091xC) || defined(STM32F098xx) +#define IS_HAL_SYSCFG_IRDA_ENV_SEL(SEL) \ + (((SEL) == HAL_SYSCFG_IRDA_ENV_SEL_TIM16) || \ + ((SEL) == HAL_SYSCFG_IRDA_ENV_SEL_USART1) || \ + ((SEL) == HAL_SYSCFG_IRDA_ENV_SEL_USART4)) +#endif /* STM32F091xC || STM32F098xx */ + /** + * @} + */ + + /* Exported types ------------------------------------------------------------*/ + /* Exported constants --------------------------------------------------------*/ + /** @defgroup HAL_Exported_Constants HAL Exported Constants + * @{ + */ + + /** @defgroup HAL_TICK_FREQ Tick Frequency + * @{ + */ + typedef enum + { + HAL_TICK_FREQ_10HZ = 100U, + HAL_TICK_FREQ_100HZ = 10U, + HAL_TICK_FREQ_1KHZ = 1U, + HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ + } HAL_TickFreqTypeDef; + + /** + * @} + */ + +#if defined(SYSCFG_CFGR1_PA11_PA12_RMP) +/** @defgroup HAL_Pin_remapping HAL Pin remapping + * @{ + */ +#define HAL_REMAP_PA11_PA12 \ + (SYSCFG_CFGR1_PA11_PA12_RMP) /*!< PA11 and PA12 remapping bit for small packages (28 \ + and 20 pins). 0: No remap (pin pair PA9/10 mapped on \ + the pins) 1: Remap (pin pair PA11/12 mapped instead of \ + PA9/10) */ + +/** + * @} + */ +#endif /* SYSCFG_CFGR1_PA11_PA12_RMP */ + +#if defined(STM32F091xC) || defined(STM32F098xx) +/** @defgroup HAL_IRDA_ENV_SEL HAL IRDA Envelope Selection + * @note Applicable on STM32F09x + * @{ + */ +#define HAL_SYSCFG_IRDA_ENV_SEL_TIM16 \ + (SYSCFG_CFGR1_IRDA_ENV_SEL_0 & \ + SYSCFG_CFGR1_IRDA_ENV_SEL_1) /* 00: Timer16 is selected as IRDA Modulation envelope \ + source */ +#define HAL_SYSCFG_IRDA_ENV_SEL_USART1 \ + (SYSCFG_CFGR1_IRDA_ENV_SEL_0) /* 01: USART1 is selected as IRDA Modulation envelope \ + source */ +#define HAL_SYSCFG_IRDA_ENV_SEL_USART4 \ + (SYSCFG_CFGR1_IRDA_ENV_SEL_1) /* 10: USART4 is selected as IRDA Modulation envelope \ + source */ + +/** + * @} + */ +#endif /* STM32F091xC || STM32F098xx */ + + +/** @defgroup SYSCFG_FastModePlus_GPIO Fast-mode Plus on GPIO + * @{ + */ + +/** @brief Fast-mode Plus driving capability on a specific GPIO + */ +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F042x6) || \ + defined(STM32F048xx) || defined(STM32F030x6) || defined(STM32F031x6) || \ + defined(STM32F038xx) || defined(STM32F070x6) || defined(STM32F070xB) || \ + defined(STM32F030x6) +#define SYSCFG_FASTMODEPLUS_PA9 \ + SYSCFG_CFGR1_I2C_FMP_PA9 /*!< Enable Fast-mode Plus on PA9 */ +#define SYSCFG_FASTMODEPLUS_PA10 \ + SYSCFG_CFGR1_I2C_FMP_PA10 /*!< Enable Fast-mode Plus on PA10 */ +#endif +#define SYSCFG_FASTMODEPLUS_PB6 \ + SYSCFG_CFGR1_I2C_FMP_PB6 /*!< Enable Fast-mode Plus on PB6 */ +#define SYSCFG_FASTMODEPLUS_PB7 \ + SYSCFG_CFGR1_I2C_FMP_PB7 /*!< Enable Fast-mode Plus on PB7 */ +#define SYSCFG_FASTMODEPLUS_PB8 \ + SYSCFG_CFGR1_I2C_FMP_PB8 /*!< Enable Fast-mode Plus on PB8 */ +#define SYSCFG_FASTMODEPLUS_PB9 \ + SYSCFG_CFGR1_I2C_FMP_PB9 /*!< Enable Fast-mode Plus on PB9 */ + + /** + * @} + */ + + +#if defined(STM32F091xC) || defined(STM32F098xx) +/** @defgroup HAL_ISR_Wrapper HAL ISR Wrapper + * @brief ISR Wrapper + * @note applicable on STM32F09x + * @{ + */ +#define HAL_SYSCFG_ITLINE0 (0x00000000U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE1 (0x00000001U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE2 (0x00000002U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE3 (0x00000003U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE4 (0x00000004U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE5 (0x00000005U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE6 (0x00000006U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE7 (0x00000007U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE8 (0x00000008U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE9 (0x00000009U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE10 (0x0000000AU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE11 (0x0000000BU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE12 (0x0000000CU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE13 (0x0000000DU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE14 (0x0000000EU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE15 (0x0000000FU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE16 (0x00000010U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE17 (0x00000011U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE18 (0x00000012U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE19 (0x00000013U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE20 (0x00000014U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE21 (0x00000015U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE22 (0x00000016U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE23 (0x00000017U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE24 (0x00000018U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE25 (0x00000019U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE26 (0x0000001AU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE27 (0x0000001BU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE28 (0x0000001CU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE29 (0x0000001DU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE30 (0x0000001EU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE31 (0x0000001FU) /*!< Internal define for macro handling */ + +#define HAL_ITLINE_EWDG \ + ((uint32_t)((HAL_SYSCFG_ITLINE0 << 0x18U) | \ + SYSCFG_ITLINE0_SR_EWDG)) /*!< EWDG has expired .... */ +#if defined(STM32F091xC) +#define HAL_ITLINE_PVDOUT \ + ((uint32_t)((HAL_SYSCFG_ITLINE1 << 0x18U) | \ + SYSCFG_ITLINE1_SR_PVDOUT)) /*!< Power voltage detection Interrupt .... \ + */ +#endif +#define HAL_ITLINE_VDDIO2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE1 << 0x18U) | \ + SYSCFG_ITLINE1_SR_VDDIO2)) /*!< VDDIO2 Interrupt .... */ +#define HAL_ITLINE_RTC_WAKEUP \ + ((uint32_t)((HAL_SYSCFG_ITLINE2 << 0x18U) | \ + SYSCFG_ITLINE2_SR_RTC_WAKEUP)) /*!< RTC WAKEUP -> exti[20] Interrupt */ +#define HAL_ITLINE_RTC_TSTAMP \ + ((uint32_t)((HAL_SYSCFG_ITLINE2 << 0x18U) | \ + SYSCFG_ITLINE2_SR_RTC_TSTAMP)) /*!< RTC Time Stamp -> exti[19] interrupt \ + */ +#define HAL_ITLINE_RTC_ALRA \ + ((uint32_t)((HAL_SYSCFG_ITLINE2 << 0x18U) | \ + SYSCFG_ITLINE2_SR_RTC_ALRA)) /*!< RTC Alarm -> exti[17] interrupt .... \ + */ +#define HAL_ITLINE_FLASH_ITF \ + ((uint32_t)((HAL_SYSCFG_ITLINE3 << 0x18U) | \ + SYSCFG_ITLINE3_SR_FLASH_ITF)) /*!< Flash ITF Interrupt */ +#define HAL_ITLINE_CRS \ + ((uint32_t)((HAL_SYSCFG_ITLINE4 << 0x18U) | \ + SYSCFG_ITLINE4_SR_CRS)) /*!< CRS Interrupt */ +#define HAL_ITLINE_CLK_CTRL \ + ((uint32_t)((HAL_SYSCFG_ITLINE4 << 0x18U) | \ + SYSCFG_ITLINE4_SR_CLK_CTRL)) /*!< CLK Control Interrupt */ +#define HAL_ITLINE_EXTI0 \ + ((uint32_t)((HAL_SYSCFG_ITLINE5 << 0x18U) | \ + SYSCFG_ITLINE5_SR_EXTI0)) /*!< External Interrupt 0 */ +#define HAL_ITLINE_EXTI1 \ + ((uint32_t)((HAL_SYSCFG_ITLINE5 << 0x18U) | \ + SYSCFG_ITLINE5_SR_EXTI1)) /*!< External Interrupt 1 */ +#define HAL_ITLINE_EXTI2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE6 << 0x18U) | \ + SYSCFG_ITLINE6_SR_EXTI2)) /*!< External Interrupt 2 */ +#define HAL_ITLINE_EXTI3 \ + ((uint32_t)((HAL_SYSCFG_ITLINE6 << 0x18U) | \ + SYSCFG_ITLINE6_SR_EXTI3)) /*!< External Interrupt 3 */ +#define HAL_ITLINE_EXTI4 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI4)) /*!< EXTI4 Interrupt */ +#define HAL_ITLINE_EXTI5 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI5)) /*!< EXTI5 Interrupt */ +#define HAL_ITLINE_EXTI6 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI6)) /*!< EXTI6 Interrupt */ +#define HAL_ITLINE_EXTI7 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI7)) /*!< EXTI7 Interrupt */ +#define HAL_ITLINE_EXTI8 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI8)) /*!< EXTI8 Interrupt */ +#define HAL_ITLINE_EXTI9 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI9)) /*!< EXTI9 Interrupt */ +#define HAL_ITLINE_EXTI10 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI10)) /*!< EXTI10 Interrupt */ +#define HAL_ITLINE_EXTI11 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI11)) /*!< EXTI11 Interrupt */ +#define HAL_ITLINE_EXTI12 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI12)) /*!< EXTI12 Interrupt */ +#define HAL_ITLINE_EXTI13 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI13)) /*!< EXTI13 Interrupt */ +#define HAL_ITLINE_EXTI14 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI14)) /*!< EXTI14 Interrupt */ +#define HAL_ITLINE_EXTI15 \ + ((uint32_t)((HAL_SYSCFG_ITLINE7 << 0x18U) | \ + SYSCFG_ITLINE7_SR_EXTI15)) /*!< EXTI15 Interrupt */ +#define HAL_ITLINE_TSC_EOA \ + ((uint32_t)((HAL_SYSCFG_ITLINE8 << 0x18U) | \ + SYSCFG_ITLINE8_SR_TSC_EOA)) /*!< Touch control EOA Interrupt */ +#define HAL_ITLINE_TSC_MCE \ + ((uint32_t)((HAL_SYSCFG_ITLINE8 << 0x18U) | \ + SYSCFG_ITLINE8_SR_TSC_MCE)) /*!< Touch control MCE Interrupt */ +#define HAL_ITLINE_DMA1_CH1 \ + ((uint32_t)((HAL_SYSCFG_ITLINE9 << 0x18U) | \ + SYSCFG_ITLINE9_SR_DMA1_CH1)) /*!< DMA1 Channel 1 Interrupt */ +#define HAL_ITLINE_DMA1_CH2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE10 << 0x18U) | \ + SYSCFG_ITLINE10_SR_DMA1_CH2)) /*!< DMA1 Channel 2 Interrupt */ +#define HAL_ITLINE_DMA1_CH3 \ + ((uint32_t)((HAL_SYSCFG_ITLINE10 << 0x18U) | \ + SYSCFG_ITLINE10_SR_DMA1_CH3)) /*!< DMA1 Channel 3 Interrupt */ +#define HAL_ITLINE_DMA2_CH1 \ + ((uint32_t)((HAL_SYSCFG_ITLINE10 << 0x18U) | \ + SYSCFG_ITLINE10_SR_DMA2_CH1)) /*!< DMA2 Channel 1 Interrupt */ +#define HAL_ITLINE_DMA2_CH2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE10 << 0x18U) | \ + SYSCFG_ITLINE10_SR_DMA2_CH2)) /*!< DMA2 Channel 2 Interrupt */ +#define HAL_ITLINE_DMA1_CH4 \ + ((uint32_t)((HAL_SYSCFG_ITLINE11 << 0x18U) | \ + SYSCFG_ITLINE11_SR_DMA1_CH4)) /*!< DMA1 Channel 4 Interrupt */ +#define HAL_ITLINE_DMA1_CH5 \ + ((uint32_t)((HAL_SYSCFG_ITLINE11 << 0x18U) | \ + SYSCFG_ITLINE11_SR_DMA1_CH5)) /*!< DMA1 Channel 5 Interrupt */ +#define HAL_ITLINE_DMA1_CH6 \ + ((uint32_t)((HAL_SYSCFG_ITLINE11 << 0x18U) | \ + SYSCFG_ITLINE11_SR_DMA1_CH6)) /*!< DMA1 Channel 6 Interrupt */ +#define HAL_ITLINE_DMA1_CH7 \ + ((uint32_t)((HAL_SYSCFG_ITLINE11 << 0x18U) | \ + SYSCFG_ITLINE11_SR_DMA1_CH7)) /*!< DMA1 Channel 7 Interrupt */ +#define HAL_ITLINE_DMA2_CH3 \ + ((uint32_t)((HAL_SYSCFG_ITLINE11 << 0x18U) | \ + SYSCFG_ITLINE11_SR_DMA2_CH3)) /*!< DMA2 Channel 3 Interrupt */ +#define HAL_ITLINE_DMA2_CH4 \ + ((uint32_t)((HAL_SYSCFG_ITLINE11 << 0x18U) | \ + SYSCFG_ITLINE11_SR_DMA2_CH4)) /*!< DMA2 Channel 4 Interrupt */ +#define HAL_ITLINE_DMA2_CH5 \ + ((uint32_t)((HAL_SYSCFG_ITLINE11 << 0x18U) | \ + SYSCFG_ITLINE11_SR_DMA2_CH5)) /*!< DMA2 Channel 5 Interrupt */ +#define HAL_ITLINE_ADC \ + ((uint32_t)((HAL_SYSCFG_ITLINE12 << 0x18U) | \ + SYSCFG_ITLINE12_SR_ADC)) /*!< ADC Interrupt */ +#define HAL_ITLINE_COMP1 \ + ((uint32_t)((HAL_SYSCFG_ITLINE12 << 0x18U) | \ + SYSCFG_ITLINE12_SR_COMP1)) /*!< COMP1 Interrupt -> exti[21] */ +#define HAL_ITLINE_COMP2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE12 << 0x18U) | \ + SYSCFG_ITLINE12_SR_COMP2)) /*!< COMP2 Interrupt -> exti[21] */ +#define HAL_ITLINE_TIM1_BRK \ + ((uint32_t)((HAL_SYSCFG_ITLINE13 << 0x18U) | \ + SYSCFG_ITLINE13_SR_TIM1_BRK)) /*!< TIM1 BRK Interrupt */ +#define HAL_ITLINE_TIM1_UPD \ + ((uint32_t)((HAL_SYSCFG_ITLINE13 << 0x18U) | \ + SYSCFG_ITLINE13_SR_TIM1_UPD)) /*!< TIM1 UPD Interrupt */ +#define HAL_ITLINE_TIM1_TRG \ + ((uint32_t)((HAL_SYSCFG_ITLINE13 << 0x18U) | \ + SYSCFG_ITLINE13_SR_TIM1_TRG)) /*!< TIM1 TRG Interrupt */ +#define HAL_ITLINE_TIM1_CCU \ + ((uint32_t)((HAL_SYSCFG_ITLINE13 << 0x18U) | \ + SYSCFG_ITLINE13_SR_TIM1_CCU)) /*!< TIM1 CCU Interrupt */ +#define HAL_ITLINE_TIM1_CC \ + ((uint32_t)((HAL_SYSCFG_ITLINE14 << 0x18U) | \ + SYSCFG_ITLINE14_SR_TIM1_CC)) /*!< TIM1 CC Interrupt */ +#define HAL_ITLINE_TIM2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE15 << 0x18U) | \ + SYSCFG_ITLINE15_SR_TIM2_GLB)) /*!< TIM2 Interrupt */ +#define HAL_ITLINE_TIM3 \ + ((uint32_t)((HAL_SYSCFG_ITLINE16 << 0x18U) | \ + SYSCFG_ITLINE16_SR_TIM3_GLB)) /*!< TIM3 Interrupt */ +#define HAL_ITLINE_DAC \ + ((uint32_t)((HAL_SYSCFG_ITLINE17 << 0x18U) | \ + SYSCFG_ITLINE17_SR_DAC)) /*!< DAC Interrupt */ +#define HAL_ITLINE_TIM6 \ + ((uint32_t)((HAL_SYSCFG_ITLINE17 << 0x18U) | \ + SYSCFG_ITLINE17_SR_TIM6_GLB)) /*!< TIM6 Interrupt */ +#define HAL_ITLINE_TIM7 \ + ((uint32_t)((HAL_SYSCFG_ITLINE18 << 0x18U) | \ + SYSCFG_ITLINE18_SR_TIM7_GLB)) /*!< TIM7 Interrupt */ +#define HAL_ITLINE_TIM14 \ + ((uint32_t)((HAL_SYSCFG_ITLINE19 << 0x18U) | \ + SYSCFG_ITLINE19_SR_TIM14_GLB)) /*!< TIM14 Interrupt */ +#define HAL_ITLINE_TIM15 \ + ((uint32_t)((HAL_SYSCFG_ITLINE20 << 0x18U) | \ + SYSCFG_ITLINE20_SR_TIM15_GLB)) /*!< TIM15 Interrupt */ +#define HAL_ITLINE_TIM16 \ + ((uint32_t)((HAL_SYSCFG_ITLINE21 << 0x18U) | \ + SYSCFG_ITLINE21_SR_TIM16_GLB)) /*!< TIM16 Interrupt */ +#define HAL_ITLINE_TIM17 \ + ((uint32_t)((HAL_SYSCFG_ITLINE22 << 0x18U) | \ + SYSCFG_ITLINE22_SR_TIM17_GLB)) /*!< TIM17 Interrupt */ +#define HAL_ITLINE_I2C1 \ + ((uint32_t)((HAL_SYSCFG_ITLINE23 << 0x18U) | \ + SYSCFG_ITLINE23_SR_I2C1_GLB)) /*!< I2C1 Interrupt -> exti[23] */ +#define HAL_ITLINE_I2C2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE24 << 0x18U) | \ + SYSCFG_ITLINE24_SR_I2C2_GLB)) /*!< I2C2 Interrupt */ +#define HAL_ITLINE_SPI1 \ + ((uint32_t)((HAL_SYSCFG_ITLINE25 << 0x18U) | \ + SYSCFG_ITLINE25_SR_SPI1)) /*!< I2C1 Interrupt -> exti[23] */ +#define HAL_ITLINE_SPI2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE26 << 0x18U) | \ + SYSCFG_ITLINE26_SR_SPI2)) /*!< SPI1 Interrupt */ +#define HAL_ITLINE_USART1 \ + ((uint32_t)((HAL_SYSCFG_ITLINE27 << 0x18U) | \ + SYSCFG_ITLINE27_SR_USART1_GLB)) /*!< USART1 GLB Interrupt -> exti[25] */ +#define HAL_ITLINE_USART2 \ + ((uint32_t)((HAL_SYSCFG_ITLINE28 << 0x18U) | \ + SYSCFG_ITLINE28_SR_USART2_GLB)) /*!< USART2 GLB Interrupt -> exti[26] */ +#define HAL_ITLINE_USART3 \ + ((uint32_t)((HAL_SYSCFG_ITLINE29 << 0x18U) | \ + SYSCFG_ITLINE29_SR_USART3_GLB)) /*!< USART3 Interrupt .... */ +#define HAL_ITLINE_USART4 \ + ((uint32_t)((HAL_SYSCFG_ITLINE29 << 0x18U) | \ + SYSCFG_ITLINE29_SR_USART4_GLB)) /*!< USART4 Interrupt .... */ +#define HAL_ITLINE_USART5 \ + ((uint32_t)((HAL_SYSCFG_ITLINE29 << 0x18U) | \ + SYSCFG_ITLINE29_SR_USART5_GLB)) /*!< USART5 Interrupt .... */ +#define HAL_ITLINE_USART6 \ + ((uint32_t)((HAL_SYSCFG_ITLINE29 << 0x18U) | \ + SYSCFG_ITLINE29_SR_USART6_GLB)) /*!< USART6 Interrupt .... */ +#define HAL_ITLINE_USART7 \ + ((uint32_t)((HAL_SYSCFG_ITLINE29 << 0x18U) | \ + SYSCFG_ITLINE29_SR_USART7_GLB)) /*!< USART7 Interrupt .... */ +#define HAL_ITLINE_USART8 \ + ((uint32_t)((HAL_SYSCFG_ITLINE29 << 0x18U) | \ + SYSCFG_ITLINE29_SR_USART8_GLB)) /*!< USART8 Interrupt .... */ +#define HAL_ITLINE_CAN \ + ((uint32_t)((HAL_SYSCFG_ITLINE30 << 0x18U) | \ + SYSCFG_ITLINE30_SR_CAN)) /*!< CAN Interrupt */ +#define HAL_ITLINE_CEC \ + ((uint32_t)((HAL_SYSCFG_ITLINE30 << 0x18U) | \ + SYSCFG_ITLINE30_SR_CEC)) /*!< CEC Interrupt -> exti[27] */ +/** + * @} + */ +#endif /* STM32F091xC || STM32F098xx */ + + /** + * @} + */ + + /* Exported macros -----------------------------------------------------------*/ + /** @defgroup HAL_Exported_Macros HAL Exported Macros + * @{ + */ + + /** @defgroup HAL_Freeze_Unfreeze_Peripherals HAL Freeze Unfreeze Peripherals + * @brief Freeze/Unfreeze Peripherals in Debug mode + * @{ + */ + +#if defined(DBGMCU_APB1_FZ_DBG_CAN_STOP) +#define __HAL_FREEZE_CAN_DBGMCU() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_CAN_STOP)) +#define __HAL_UNFREEZE_CAN_DBGMCU() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_CAN_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_CAN_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_RTC_STOP) +#define __HAL_DBGMCU_FREEZE_RTC() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_RTC_STOP)) +#define __HAL_DBGMCU_UNFREEZE_RTC() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_RTC_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_RTC_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT) +#define __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT() \ + (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT)) +#define __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT() \ + (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT)) +#endif /* DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT */ + +#if defined(DBGMCU_APB1_FZ_DBG_IWDG_STOP) +#define __HAL_DBGMCU_FREEZE_IWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_IWDG_STOP)) +#define __HAL_DBGMCU_UNFREEZE_IWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_IWDG_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_IWDG_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_WWDG_STOP) +#define __HAL_DBGMCU_FREEZE_WWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_WWDG_STOP)) +#define __HAL_DBGMCU_UNFREEZE_WWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_WWDG_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_WWDG_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM2_STOP) +#define __HAL_DBGMCU_FREEZE_TIM2() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM2_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM2() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM2_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM2_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM3_STOP) +#define __HAL_DBGMCU_FREEZE_TIM3() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM3_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM3() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM3_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM3_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM6_STOP) +#define __HAL_DBGMCU_FREEZE_TIM6() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM6_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM6() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM6_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM6_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM7_STOP) +#define __HAL_DBGMCU_FREEZE_TIM7() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM7_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM7() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM7_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM7_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM14_STOP) +#define __HAL_DBGMCU_FREEZE_TIM14() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM14_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM14() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM14_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM14_STOP */ + +#if defined(DBGMCU_APB2_FZ_DBG_TIM1_STOP) +#define __HAL_DBGMCU_FREEZE_TIM1() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM1_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM1() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM1_STOP)) +#endif /* DBGMCU_APB2_FZ_DBG_TIM1_STOP */ + +#if defined(DBGMCU_APB2_FZ_DBG_TIM15_STOP) +#define __HAL_DBGMCU_FREEZE_TIM15() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM15_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM15() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM15_STOP)) +#endif /* DBGMCU_APB2_FZ_DBG_TIM15_STOP */ + +#if defined(DBGMCU_APB2_FZ_DBG_TIM16_STOP) +#define __HAL_DBGMCU_FREEZE_TIM16() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM16_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM16() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM16_STOP)) +#endif /* DBGMCU_APB2_FZ_DBG_TIM16_STOP */ + +#if defined(DBGMCU_APB2_FZ_DBG_TIM17_STOP) +#define __HAL_DBGMCU_FREEZE_TIM17() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM17_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM17() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM17_STOP)) +#endif /* DBGMCU_APB2_FZ_DBG_TIM17_STOP */ + +/** + * @} + */ + +/** @defgroup Memory_Mapping_Selection Memory Mapping Selection + * @{ + */ +#if defined(SYSCFG_CFGR1_MEM_MODE) +/** @brief Main Flash memory mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_FLASH() (SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE)) +#endif /* SYSCFG_CFGR1_MEM_MODE */ + +#if defined(SYSCFG_CFGR1_MEM_MODE_0) +/** @brief System Flash memory mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH() \ + do \ + { \ + SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE); \ + SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE_0; \ + } while (0) +#endif /* SYSCFG_CFGR1_MEM_MODE_0 */ + +#if defined(SYSCFG_CFGR1_MEM_MODE_0) && defined(SYSCFG_CFGR1_MEM_MODE_1) +/** @brief Embedded SRAM mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_SRAM() \ + do \ + { \ + SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE); \ + SYSCFG->CFGR1 |= (SYSCFG_CFGR1_MEM_MODE_0 | SYSCFG_CFGR1_MEM_MODE_1); \ + } while (0) +#endif /* SYSCFG_CFGR1_MEM_MODE_0 && SYSCFG_CFGR1_MEM_MODE_1 */ + /** + * @} + */ + + +#if defined(SYSCFG_CFGR1_PA11_PA12_RMP) +/** @defgroup HAL_Pin_remap HAL Pin remap + * @brief Pin remapping enable/disable macros + * @param __PIN_REMAP__ This parameter can be a value of @ref HAL_Pin_remapping + * @{ + */ +#define __HAL_REMAP_PIN_ENABLE(__PIN_REMAP__) \ + do \ + { \ + assert_param(IS_HAL_REMAP_PIN((__PIN_REMAP__))); \ + SYSCFG->CFGR1 |= (__PIN_REMAP__); \ + } while (0) +#define __HAL_REMAP_PIN_DISABLE(__PIN_REMAP__) \ + do \ + { \ + assert_param(IS_HAL_REMAP_PIN((__PIN_REMAP__))); \ + SYSCFG->CFGR1 &= ~(__PIN_REMAP__); \ + } while (0) +/** + * @} + */ +#endif /* SYSCFG_CFGR1_PA11_PA12_RMP */ + +/** @brief Fast-mode Plus driving capability enable/disable macros + * @param __FASTMODEPLUS__ This parameter can be a value of @ref SYSCFG_FastModePlus_GPIO + * values. That you can find above these macros. + */ +#define __HAL_SYSCFG_FASTMODEPLUS_ENABLE(__FASTMODEPLUS__) \ + do \ + { \ + assert_param(IS_SYSCFG_FASTMODEPLUS((__FASTMODEPLUS__))); \ + SET_BIT(SYSCFG->CFGR1, (__FASTMODEPLUS__)); \ + } while (0) + +#define __HAL_SYSCFG_FASTMODEPLUS_DISABLE(__FASTMODEPLUS__) \ + do \ + { \ + assert_param(IS_SYSCFG_FASTMODEPLUS((__FASTMODEPLUS__))); \ + CLEAR_BIT(SYSCFG->CFGR1, (__FASTMODEPLUS__)); \ + } while (0) +#if defined(SYSCFG_CFGR2_LOCKUP_LOCK) +/** @defgroup Cortex_Lockup_Enable Cortex Lockup Enable + * @{ + */ +/** @brief SYSCFG Break Lockup lock + * Enables and locks the connection of Cortex-M0 LOCKUP (Hardfault) output to + * TIM1/15/16/17 Break input + * @note The selected configuration is locked and can be unlocked by system reset + */ +#define __HAL_SYSCFG_BREAK_LOCKUP_LOCK() \ + do \ + { \ + SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_LOCKUP_LOCK); \ + SYSCFG->CFGR2 |= SYSCFG_CFGR2_LOCKUP_LOCK; \ + } while (0) +/** + * @} + */ +#endif /* SYSCFG_CFGR2_LOCKUP_LOCK */ + +#if defined(SYSCFG_CFGR2_PVD_LOCK) +/** @defgroup PVD_Lock_Enable PVD Lock + * @{ + */ +/** @brief SYSCFG Break PVD lock + * Enables and locks the PVD connection with Timer1/8/15/16/17 Break Input, , as + * well as the PVDE and PLS[2:0] in the PWR_CR register + * @note The selected configuration is locked and can be unlocked by system reset + */ +#define __HAL_SYSCFG_BREAK_PVD_LOCK() \ + do \ + { \ + SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_PVD_LOCK); \ + SYSCFG->CFGR2 |= SYSCFG_CFGR2_PVD_LOCK; \ + } while (0) +/** + * @} + */ +#endif /* SYSCFG_CFGR2_PVD_LOCK */ + +#if defined(SYSCFG_CFGR2_SRAM_PARITY_LOCK) +/** @defgroup SRAM_Parity_Lock SRAM Parity Lock + * @{ + */ +/** @brief SYSCFG Break SRAM PARITY lock + * Enables and locks the SRAM_PARITY error signal with Break Input of + * TIMER1/8/15/16/17 + * @note The selected configuration is locked and can be unlocked by system reset + */ +#define __HAL_SYSCFG_BREAK_SRAMPARITY_LOCK() \ + do \ + { \ + SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_SRAM_PARITY_LOCK); \ + SYSCFG->CFGR2 |= SYSCFG_CFGR2_SRAM_PARITY_LOCK; \ + } while (0) +/** + * @} + */ +#endif /* SYSCFG_CFGR2_SRAM_PARITY_LOCK */ + +#if defined(SYSCFG_CFGR2_SRAM_PEF) +/** @defgroup HAL_SYSCFG_Parity_check_on_RAM HAL SYSCFG Parity check on RAM + * @brief Parity check on RAM disable macro + * @note Disabling the parity check on RAM locks the configuration bit. + * To re-enable the parity check on RAM perform a system reset. + * @{ + */ +#define __HAL_SYSCFG_RAM_PARITYCHECK_DISABLE() (SYSCFG->CFGR2 |= SYSCFG_CFGR2_SRAM_PEF) +/** + * @} + */ +#endif /* SYSCFG_CFGR2_SRAM_PEF */ + + +#if defined(STM32F091xC) || defined(STM32F098xx) +/** @defgroup HAL_ISR_wrapper_check HAL ISR wrapper check + * @brief ISR wrapper check + * @note This feature is applicable on STM32F09x + * @note Allow to determine interrupt source per line. + * @{ + */ +#define __HAL_GET_PENDING_IT(__SOURCE__) \ + (SYSCFG->IT_LINE_SR[((__SOURCE__) >> 0x18U)] & ((__SOURCE__)&0x00FFFFFF)) +/** + * @} + */ +#endif /* (STM32F091xC) || defined (STM32F098xx)*/ + +#if defined(STM32F091xC) || defined(STM32F098xx) +/** @defgroup HAL_SYSCFG_IRDA_modulation_envelope_selection HAL SYSCFG IRDA modulation + * envelope selection + * @brief selection of the modulation envelope signal macro, using bits [7:6] of + * SYS_CTRL(CFGR1) register + * @note This feature is applicable on STM32F09x + * @param __SOURCE__ This parameter can be a value of @ref HAL_IRDA_ENV_SEL + * @{ + */ +#define __HAL_SYSCFG_IRDA_ENV_SELECTION(__SOURCE__) \ + do \ + { \ + assert_param(IS_HAL_SYSCFG_IRDA_ENV_SEL((__SOURCE__))); \ + SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_IRDA_ENV_SEL); \ + SYSCFG->CFGR1 |= (__SOURCE__); \ + } while (0) + +#define __HAL_SYSCFG_GET_IRDA_ENV_SELECTION() ((SYSCFG->CFGR1) & 0x000000C0) +/** + * @} + */ +#endif /* (STM32F091xC) || defined (STM32F098xx)*/ + +/** + * @} + */ + +/** @defgroup HAL_Private_Macros HAL Private Macros + * @{ + */ +#define IS_TICKFREQ(FREQ) \ + (((FREQ) == HAL_TICK_FREQ_10HZ) || ((FREQ) == HAL_TICK_FREQ_100HZ) || \ + ((FREQ) == HAL_TICK_FREQ_1KHZ)) + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + + /** @addtogroup HAL_Exported_Functions + * @{ + */ + + /** @addtogroup HAL_Exported_Functions_Group1 + * @{ + */ + /* Initialization and de-initialization functions ******************************/ + HAL_StatusTypeDef HAL_Init(void); + HAL_StatusTypeDef HAL_DeInit(void); + void HAL_MspInit(void); + void HAL_MspDeInit(void); + HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority); + /** + * @} + */ + + /* Exported variables ---------------------------------------------------------*/ + /** @addtogroup HAL_Exported_Variables + * @{ + */ + extern __IO uint32_t uwTick; + extern uint32_t uwTickPrio; + extern HAL_TickFreqTypeDef uwTickFreq; + /** + * @} + */ + + /** @addtogroup HAL_Exported_Functions_Group2 + * @{ + */ + + /* Peripheral Control functions ************************************************/ + void HAL_IncTick(void); + void HAL_Delay(uint32_t Delay); + uint32_t HAL_GetTick(void); + uint32_t HAL_GetTickPrio(void); + HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq); + HAL_TickFreqTypeDef HAL_GetTickFreq(void); + void HAL_SuspendTick(void); + void HAL_ResumeTick(void); + uint32_t HAL_GetHalVersion(void); + uint32_t HAL_GetREVID(void); + uint32_t HAL_GetDEVID(void); + uint32_t HAL_GetUIDw0(void); + uint32_t HAL_GetUIDw1(void); + uint32_t HAL_GetUIDw2(void); + void HAL_DBGMCU_EnableDBGStopMode(void); + void HAL_DBGMCU_DisableDBGStopMode(void); + void HAL_DBGMCU_EnableDBGStandbyMode(void); + void HAL_DBGMCU_DisableDBGStandbyMode(void); + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_adc.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_adc.h new file mode 100644 index 0000000000..c5cc9e35e2 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_adc.h @@ -0,0 +1,1164 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_adc.h + * @author MCD Application Team + * @brief Header file containing functions prototypes of ADC HAL library. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_ADC_H +#define STM32F0xx_HAL_ADC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup ADC + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /** @defgroup ADC_Exported_Types ADC Exported Types + * @{ + */ + + /** + * @brief Structure definition of ADC initialization and regular group + * @note The setting of these parameters with function HAL_ADC_Init() is conditioned + * to ADC state. ADC state can be either: + * - For all parameters: ADC disabled (this is the only possible ADC state to + * modify parameter 'ClockPrescaler') + * - For all parameters except 'ClockPrescaler' and 'resolution': ADC enabled + * without conversion on going on regular group. If ADC is not in the appropriate + * state to modify some parameters, these parameters setting is bypassed without error + * reporting (as it can be the expected behaviour in case of intended action to update + * another parameter (which fulfills the ADC state condition) on the fly). + */ + typedef struct + { + uint32_t + ClockPrescaler; /*!< Select ADC clock source (synchronous clock derived from + APB clock or asynchronous clock derived from ADC dedicated + HSI RC oscillator 14MHz) and clock prescaler. This + parameter can be a value of @ref ADC_ClockPrescaler Note: + In case of usage of the ADC dedicated HSI RC oscillator, it + must be preliminarily enabled at RCC top level. Note: This + parameter can be modified only if the ADC is disabled */ + uint32_t Resolution; /*!< Configures the ADC resolution. + This parameter can be a value of @ref ADC_Resolution */ + uint32_t + DataAlign; /*!< Specifies whether the ADC data alignment is left or right. + This parameter can be a value of @ref ADC_Data_align */ + uint32_t ScanConvMode; /*!< Configures the sequencer of regular group. + This parameter can be associated to parameter + 'DiscontinuousConvMode' to have main sequence subdivided + in successive parts. Sequencer is automatically + enabled if several channels are set (sequencer cannot be + disabled, as it can be the case on other STM32 devices): + If only 1 channel is set: Conversion is performed + in single mode. If several channels are set: + Conversions are performed in sequence mode (ranks + defined by each channel number: channel 0 fixed on + rank 0, channel 1 fixed on rank1, + ...). Scan direction can be set to + forward (from channel 0 to channel 18) or backward + (from channel 18 to channel 0). This parameter + can be a value of @ref ADC_Scan_mode */ + uint32_t EOCSelection; /*!< Specifies what EOC (End Of Conversion) flag is used + for conversion by polling and interruption: end of + conversion of each rank or complete sequence. This + parameter can be a value of @ref ADC_EOCSelection. */ + FunctionalState + LowPowerAutoWait; /*!< Selects the dynamic low power Auto Delay: new + conversion start only when the previous conversion (for + regular group) has been treated by user software, using + function HAL_ADC_GetValue(). This feature automatically adapts + the ADC conversions trigs to the speed of the system that + reads the data. Moreover, this avoids risk of overrun for low + frequency applications. This parameter can be set to ENABLE or + DISABLE. Note: Do not use with interruption or DMA + (HAL_ADC_Start_IT(), HAL_ADC_Start_DMA()) since they have to + clear immediately the EOC flag to free the IRQ vector + sequencer. Do use with polling: 1. Start conversion with + HAL_ADC_Start(), 2. Later on, when conversion data is needed: + use HAL_ADC_PollForConversion() to ensure that conversion is + completed and use HAL_ADC_GetValue() to retrieve conversion + result and trig another conversion. */ + FunctionalState + LowPowerAutoPowerOff; /*!< Selects the auto-off mode: the ADC automatically + powers-off after a conversion and automatically wakes-up + when a new conversion is triggered (with startup time + between trigger and start of sampling). This feature can + be combined with automatic wait mode (parameter + 'LowPowerAutoWait'). This parameter can be set to ENABLE + or DISABLE. Note: If enabled, this feature also turns off + the ADC dedicated 14 MHz RC oscillator (HSI14) */ + FunctionalState + ContinuousConvMode; /*!< Specifies whether the conversion is performed in + single mode (one conversion) or continuous mode for regular + group, after the selected trigger occurred (software start + or external trigger). This parameter can be set to ENABLE or + DISABLE. */ + FunctionalState + DiscontinuousConvMode; /*!< Specifies whether the conversions sequence of + regular group is performed in + Complete-sequence/Discontinuous-sequence (main sequence + subdivided in successive parts). Discontinuous mode is + used only if sequencer is enabled (parameter + 'ScanConvMode'). If sequencer is disabled, this parameter + is discarded. Discontinuous mode can be enabled only if + continuous mode is disabled. If continuous mode is + enabled, this parameter setting is discarded. This + parameter can be set to ENABLE or DISABLE Note: Number of + discontinuous ranks increment is fixed to one-by-one. */ + uint32_t ExternalTrigConv; /*!< Selects the external event used to trigger the + conversion start of regular group. If set to + ADC_SOFTWARE_START, external triggers are disabled. + This parameter can be a value of @ref + ADC_External_trigger_source_Regular */ + uint32_t + ExternalTrigConvEdge; /*!< Selects the external trigger edge of regular group. + If trigger is set to ADC_SOFTWARE_START, this + parameter is discarded. This parameter can be a value + of @ref ADC_External_trigger_edge_Regular */ + FunctionalState + DMAContinuousRequests; /*!< Specifies whether the DMA requests are performed + in one shot mode (DMA transfer stop when number of + conversions is reached) or in Continuous mode (DMA + transfer unlimited, whatever number of conversions). + Note: In continuous mode, DMA must be configured in + circular mode. Otherwise an overrun will be triggered + when DMA buffer maximum pointer is reached. This + parameter can be set to ENABLE or DISABLE. */ + uint32_t Overrun; /*!< Select the behaviour in case of overrun: data preserved or + overwritten This parameter has an effect on regular group + only, including in DMA mode. This parameter can be a value of + @ref ADC_Overrun */ + uint32_t + SamplingTimeCommon; /*!< Sampling time value to be set for the selected + channel. Unit: ADC clock cycles Conversion time is the + addition of sampling time and processing time (12.5 ADC + clock cycles at ADC resolution 12 bits, 10.5 cycles at + 10 bits, 8.5 cycles at 8 bits, 6.5 cycles at 6 bits). + Note: On STM32F0 devices, the sampling time setting + is common to all channels. On some other STM32 devices, + this parameter in channel wise and is located into ADC + channel initialization structure. This parameter can be + a value of @ref ADC_sampling_times Note: In case of + usage of internal measurement channels + (VrefInt/Vbat/TempSensor), sampling time constraints + must be respected (sampling time can be adjusted in + function of ADC clock frequency and sampling time + setting) Refer to device datasheet for timings values, + parameters TS_vrefint, TS_vbat, TS_temp (values rough + order: 5us to 17us). */ + } ADC_InitTypeDef; + + /** + * @brief Structure definition of ADC channel for regular group + * @note The setting of these parameters with function HAL_ADC_ConfigChannel() is + * conditioned to ADC state. ADC state can be either: + * - For all parameters: ADC disabled or enabled without conversion on going + * on regular group. If ADC is not in the appropriate state to modify some parameters, + * these parameters setting is bypassed without error reporting (as it can be the + * expected behaviour in case of intended action to update another parameter (which + * fulfills the ADC state condition) on the fly). + */ + typedef struct + { + uint32_t Channel; /*!< Specifies the channel to configure into ADC regular group. + This parameter can be a value of @ref ADC_channels + Note: Depending on devices, some channels may not be + available on package pins. Refer to device datasheet for + channels availability. */ + uint32_t Rank; /*!< Add or remove the channel from ADC regular group sequencer. + On STM32F0 devices, number of ranks in the sequence is + defined by number of channels enabled, rank of each channel is + defined by channel number (channel 0 fixed on rank 0, channel 1 + fixed on rank1, ...).. Despite the channel rank is fixed, + this parameter allow an additional possibility: to remove the + selected rank (selected channel) from sequencer. This + parameter can be a value of @ref ADC_rank */ + uint32_t + SamplingTime; /*!< Sampling time value to be set for the selected channel. + Unit: ADC clock cycles + Conversion time is the addition of sampling time and + processing time (12.5 ADC clock cycles at ADC resolution 12 + bits, 10.5 cycles at 10 bits, 8.5 cycles at 8 bits, 6.5 + cycles at 6 bits). This parameter can be a value of @ref + ADC_sampling_times Caution: this setting impacts the entire + regular group. Therefore, call of HAL_ADC_ConfigChannel() to + configure a channel can impact the configuration of other + channels previously set. Caution: Obsolete parameter. Use + parameter "SamplingTimeCommon" in ADC initialization + structure. If parameter "SamplingTimeCommon" is set to a + valid sampling time, parameter "SamplingTime" is discarded. + Note: In case of usage of internal measurement channels + (VrefInt/Vbat/TempSensor), sampling time constraints must be + respected (sampling time can be adjusted in function of ADC + clock frequency and sampling time setting) Refer to device + datasheet for timings values, parameters TS_vrefint, TS_vbat, + TS_temp (values rough order: 5us to 17us). */ + } ADC_ChannelConfTypeDef; + + /** + * @brief Structure definition of ADC analog watchdog + * @note The setting of these parameters with function HAL_ADC_AnalogWDGConfig() is + * conditioned to ADC state. ADC state can be either: ADC disabled or ADC enabled + * without conversion on going on regular group. + */ + typedef struct + { + uint32_t WatchdogMode; /*!< Configures the ADC analog watchdog mode: + single/all/none channels. This parameter can be a value + of @ref ADC_analog_watchdog_mode. */ + uint32_t + Channel; /*!< Selects which ADC channel to monitor by analog watchdog. + This parameter has an effect only if parameter 'WatchdogMode' is + configured on single channel. Only 1 channel can be monitored. + This parameter can be a value of @ref ADC_channels. */ + FunctionalState + ITMode; /*!< Specifies whether the analog watchdog is configured in interrupt + or polling mode. This parameter can be set to ENABLE or DISABLE */ + uint32_t HighThreshold; /*!< Configures the ADC analog watchdog High threshold + value. Depending of ADC resolution selected (12, 10, 8 + or 6 bits), this parameter must be a number between + Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or + 0x3F respectively. */ + uint32_t + LowThreshold; /*!< Configures the ADC analog watchdog High threshold value. + Depending of ADC resolution selected (12, 10, 8 or 6 bits), + this parameter must be a number between Min_Data = 0x000 and + Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */ + } ADC_AnalogWDGConfTypeDef; + +/** + * @brief HAL ADC state machine: ADC states definition (bitfields) + * @note ADC state machine is managed by bitfields, state must be compared + * with bit by bit. + * For example: + * " if (HAL_IS_BIT_SET(HAL_ADC_GetState(hadc1), HAL_ADC_STATE_REG_BUSY)) " + * " if (HAL_IS_BIT_SET(HAL_ADC_GetState(hadc1), HAL_ADC_STATE_AWD1) ) " + */ +/* States of ADC global scope */ +#define HAL_ADC_STATE_RESET (0x00000000U) /*!< ADC not yet initialized or disabled */ +#define HAL_ADC_STATE_READY (0x00000001U) /*!< ADC peripheral ready for use */ +#define HAL_ADC_STATE_BUSY_INTERNAL \ + (0x00000002U) /*!< ADC is busy to internal process (initialization, calibration) */ +#define HAL_ADC_STATE_TIMEOUT (0x00000004U) /*!< TimeOut occurrence */ + +/* States of ADC errors */ +#define HAL_ADC_STATE_ERROR_INTERNAL (0x00000010U) /*!< Internal error occurrence */ +#define HAL_ADC_STATE_ERROR_CONFIG (0x00000020U) /*!< Configuration error occurrence */ +#define HAL_ADC_STATE_ERROR_DMA (0x00000040U) /*!< DMA error occurrence */ + +/* States of ADC group regular */ +#define HAL_ADC_STATE_REG_BUSY \ + (0x00000100U) /*!< A conversion on group regular is ongoing or can occur (either by \ + continuous mode, external trigger, low power auto power-on, \ + multimode ADC master control) */ +#define HAL_ADC_STATE_REG_EOC \ + (0x00000200U) /*!< Conversion data available on group regular */ +#define HAL_ADC_STATE_REG_OVR (0x00000400U) /*!< Overrun occurrence */ +#define HAL_ADC_STATE_REG_EOSMP \ + (0x00000800U) /*!< Not available on STM32F0 device: End Of Sampling flag raised */ + +/* States of ADC group injected */ +#define HAL_ADC_STATE_INJ_BUSY \ + (0x00001000U) /*!< Not available on STM32F0 device: A conversion on group injected \ + is ongoing or can occur (either by auto-injection mode, external \ + trigger, low power auto power-on, multimode ADC master control) */ +#define HAL_ADC_STATE_INJ_EOC \ + (0x00002000U) /*!< Not available on STM32F0 device: Conversion data available on \ + group injected */ +#define HAL_ADC_STATE_INJ_JQOVF \ + (0x00004000U) /*!< Not available on STM32F0 device: Not available on STM32F0 device: \ + Injected queue overflow occurrence */ + +/* States of ADC analog watchdogs */ +#define HAL_ADC_STATE_AWD1 \ + (0x00010000U) /*!< Out-of-window occurrence of analog watchdog 1 */ +#define HAL_ADC_STATE_AWD2 \ + (0x00020000U) /*!< Not available on STM32F0 device: Out-of-window occurrence of \ + analog watchdog 2 */ +#define HAL_ADC_STATE_AWD3 \ + (0x00040000U) /*!< Not available on STM32F0 device: Out-of-window occurrence of \ + analog watchdog 3 */ + +/* States of ADC multi-mode */ +#define HAL_ADC_STATE_MULTIMODE_SLAVE \ + (0x00100000U) /*!< Not available on STM32F0 device: ADC in multimode slave state, \ + controlled by another ADC master ( */ + + + /** + * @brief ADC handle Structure definition + */ + typedef struct __ADC_HandleTypeDef + { + ADC_TypeDef* Instance; /*!< Register base address */ + + ADC_InitTypeDef Init; /*!< ADC required parameters */ + + DMA_HandleTypeDef* DMA_Handle; /*!< Pointer DMA Handler */ + + HAL_LockTypeDef Lock; /*!< ADC locking object */ + + __IO uint32_t State; /*!< ADC communication state (bitmap of ADC states) */ + + __IO uint32_t ErrorCode; /*!< ADC Error code */ + + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + void (*ConvCpltCallback)( + struct __ADC_HandleTypeDef* hadc); /*!< ADC conversion complete callback */ + void (*ConvHalfCpltCallback)( + struct __ADC_HandleTypeDef* + hadc); /*!< ADC conversion DMA half-transfer callback */ + void (*LevelOutOfWindowCallback)( + struct __ADC_HandleTypeDef* hadc); /*!< ADC analog watchdog 1 callback */ + void (*ErrorCallback)( + struct __ADC_HandleTypeDef* hadc); /*!< ADC error callback */ + void (*MspInitCallback)( + struct __ADC_HandleTypeDef* hadc); /*!< ADC Msp Init callback */ + void (*MspDeInitCallback)( + struct __ADC_HandleTypeDef* hadc); /*!< ADC Msp DeInit callback */ +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + } ADC_HandleTypeDef; + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + /** + * @brief HAL ADC Callback ID enumeration definition + */ + typedef enum + { + HAL_ADC_CONVERSION_COMPLETE_CB_ID = + 0x00U, /*!< ADC conversion complete callback ID */ + HAL_ADC_CONVERSION_HALF_CB_ID = + 0x01U, /*!< ADC conversion DMA half-transfer callback ID */ + HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID = + 0x02U, /*!< ADC analog watchdog 1 callback ID */ + HAL_ADC_ERROR_CB_ID = 0x03U, /*!< ADC error callback ID */ + HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID = + 0x04U, /*!< ADC group injected conversion complete callback ID */ + HAL_ADC_MSPINIT_CB_ID = 0x09U, /*!< ADC Msp Init callback ID */ + HAL_ADC_MSPDEINIT_CB_ID = 0x0AU /*!< ADC Msp DeInit callback ID */ + } HAL_ADC_CallbackIDTypeDef; + + /** + * @brief HAL ADC Callback pointer definition + */ + typedef void (*pADC_CallbackTypeDef)( + ADC_HandleTypeDef* hadc); /*!< pointer to a ADC callback function */ + +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + +/** + * @} + */ + + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADC_Error_Code ADC Error Code + * @{ + */ +#define HAL_ADC_ERROR_NONE \ + (0x00U) /*!< No error */ +#define HAL_ADC_ERROR_INTERNAL \ + (0x01U) /*!< ADC IP internal error: if problem of clocking, \ + enable/disable, erroneous state */ +#define HAL_ADC_ERROR_OVR \ + (0x02U) /*!< Overrun error */ +#define HAL_ADC_ERROR_DMA \ + (0x04U) /*!< DMA transfer error */ + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +#define HAL_ADC_ERROR_INVALID_CALLBACK (0x10U) /*!< Invalid Callback error */ +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup ADC_ClockPrescaler ADC ClockPrescaler + * @{ + */ +#define ADC_CLOCK_ASYNC_DIV1 \ + (0x00000000U) /*!< ADC asynchronous clock derived from ADC dedicated HSI */ + +#define ADC_CLOCK_SYNC_PCLK_DIV2 \ + ((uint32_t)ADC_CFGR2_CKMODE_0) /*!< ADC synchronous clock derived from AHB clock \ + divided by a prescaler of 2 */ +#define ADC_CLOCK_SYNC_PCLK_DIV4 \ + ((uint32_t)ADC_CFGR2_CKMODE_1) /*!< ADC synchronous clock derived from AHB clock \ + divided by a prescaler of 4 */ + +/** + * @} + */ + +/** @defgroup ADC_Resolution ADC Resolution + * @{ + */ +#define ADC_RESOLUTION_12B (0x00000000U) /*!< ADC 12-bit resolution */ +#define ADC_RESOLUTION_10B ((uint32_t)ADC_CFGR1_RES_0) /*!< ADC 10-bit resolution */ +#define ADC_RESOLUTION_8B ((uint32_t)ADC_CFGR1_RES_1) /*!< ADC 8-bit resolution */ +#define ADC_RESOLUTION_6B ((uint32_t)ADC_CFGR1_RES) /*!< ADC 6-bit resolution */ +/** + * @} + */ + +/** @defgroup ADC_Data_align ADC Data_align + * @{ + */ +#define ADC_DATAALIGN_RIGHT (0x00000000U) +#define ADC_DATAALIGN_LEFT ((uint32_t)ADC_CFGR1_ALIGN) +/** + * @} + */ + +/** @defgroup ADC_Scan_mode ADC Scan mode + * @{ + */ +/* Note: Scan mode values must be compatible with other STM32 devices having */ +/* a configurable sequencer. */ +/* Scan direction setting values are defined by taking in account */ +/* already defined values for other STM32 devices: */ +/* ADC_SCAN_DISABLE (0x00000000U) */ +/* ADC_SCAN_ENABLE (0x00000001U) */ +/* Scan direction forward is considered as default setting equivalent */ +/* to scan enable. */ +/* Scan direction backward is considered as additional setting. */ +/* In case of migration from another STM32 device, the user will be */ +/* warned of change of setting choices with assert check. */ +#define ADC_SCAN_DIRECTION_FORWARD \ + (0x00000001U) /*!< Scan direction forward: from channel 0 to channel 18 */ +#define ADC_SCAN_DIRECTION_BACKWARD \ + (0x00000002U) /*!< Scan direction backward: from channel 18 to channel 0 */ + +#define ADC_SCAN_ENABLE \ + ADC_SCAN_DIRECTION_FORWARD /* For compatibility with other STM32 devices */ + +/** + * @} + */ + +/** @defgroup ADC_External_trigger_edge_Regular ADC External trigger edge Regular + * @{ + */ +#define ADC_EXTERNALTRIGCONVEDGE_NONE (0x00000000U) +#define ADC_EXTERNALTRIGCONVEDGE_RISING ((uint32_t)ADC_CFGR1_EXTEN_0) +#define ADC_EXTERNALTRIGCONVEDGE_FALLING ((uint32_t)ADC_CFGR1_EXTEN_1) +#define ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING ((uint32_t)ADC_CFGR1_EXTEN) +/** + * @} + */ + +/** @defgroup ADC_EOCSelection ADC EOCSelection + * @{ + */ +#define ADC_EOC_SINGLE_CONV ((uint32_t)ADC_ISR_EOC) +#define ADC_EOC_SEQ_CONV ((uint32_t)ADC_ISR_EOS) +/** + * @} + */ + +/** @defgroup ADC_Overrun ADC Overrun + * @{ + */ +#define ADC_OVR_DATA_OVERWRITTEN (0x00000000U) +#define ADC_OVR_DATA_PRESERVED (0x00000001U) +/** + * @} + */ + +/** @defgroup ADC_rank ADC rank + * @{ + */ +#define ADC_RANK_CHANNEL_NUMBER \ + (0x00001000U) /*!< Enable the rank of the selected channels. Number of ranks in the \ + sequence is defined by number of channels enabled, rank of each \ + channel is defined by channel number (channel 0 fixed on rank 0, \ + channel 1 fixed on rank1, ...) */ +#define ADC_RANK_NONE \ + (0x00001001U) /*!< Disable the selected rank (selected channel) from sequencer */ +/** + * @} + */ + +/** @defgroup ADC_sampling_times ADC sampling times + * @{ + */ +/* Note: Parameter "ADC_SAMPLETIME_1CYCLE_5" defined with a dummy bit */ +/* to distinguish this parameter versus reset value 0x00000000, */ +/* in the context of management of parameters "SamplingTimeCommon" */ +/* and "SamplingTime" (obsolete)). */ +#define ADC_SAMPLETIME_1CYCLE_5 (0x10000000U) /*!< Sampling time 1.5 ADC clock cycle */ +#define ADC_SAMPLETIME_7CYCLES_5 \ + ((uint32_t)ADC_SMPR_SMP_0) /*!< Sampling time 7.5 ADC clock cycles */ +#define ADC_SAMPLETIME_13CYCLES_5 \ + ((uint32_t)ADC_SMPR_SMP_1) /*!< Sampling time 13.5 ADC clock cycles */ +#define ADC_SAMPLETIME_28CYCLES_5 \ + ((uint32_t)(ADC_SMPR_SMP_1 | \ + ADC_SMPR_SMP_0)) /*!< Sampling time 28.5 ADC clock cycles */ +#define ADC_SAMPLETIME_41CYCLES_5 \ + ((uint32_t)ADC_SMPR_SMP_2) /*!< Sampling time 41.5 ADC clock cycles */ +#define ADC_SAMPLETIME_55CYCLES_5 \ + ((uint32_t)(ADC_SMPR_SMP_2 | \ + ADC_SMPR_SMP_0)) /*!< Sampling time 55.5 ADC clock cycles */ +#define ADC_SAMPLETIME_71CYCLES_5 \ + ((uint32_t)(ADC_SMPR_SMP_2 | \ + ADC_SMPR_SMP_1)) /*!< Sampling time 71.5 ADC clock cycles */ +#define ADC_SAMPLETIME_239CYCLES_5 \ + ((uint32_t)ADC_SMPR_SMP) /*!< Sampling time 239.5 ADC clock cycles */ +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_mode ADC analog watchdog mode + * @{ + */ +#define ADC_ANALOGWATCHDOG_NONE (0x00000000U) +#define ADC_ANALOGWATCHDOG_SINGLE_REG ((uint32_t)(ADC_CFGR1_AWDSGL | ADC_CFGR1_AWDEN)) +#define ADC_ANALOGWATCHDOG_ALL_REG ((uint32_t)ADC_CFGR1_AWDEN) +/** + * @} + */ + +/** @defgroup ADC_Event_type ADC Event type + * @{ + */ +#define ADC_AWD_EVENT ((uint32_t)ADC_FLAG_AWD) /*!< ADC Analog watchdog 1 event */ +#define ADC_OVR_EVENT ((uint32_t)ADC_FLAG_OVR) /*!< ADC overrun event */ +/** + * @} + */ + +/** @defgroup ADC_interrupts_definition ADC interrupts definition + * @{ + */ +#define ADC_IT_AWD ADC_IER_AWDIE /*!< ADC Analog watchdog interrupt source */ +#define ADC_IT_OVR ADC_IER_OVRIE /*!< ADC overrun interrupt source */ +#define ADC_IT_EOS \ + ADC_IER_EOSEQIE /*!< ADC End of Regular sequence of Conversions interrupt source */ +#define ADC_IT_EOC ADC_IER_EOCIE /*!< ADC End of Regular Conversion interrupt source */ +#define ADC_IT_EOSMP ADC_IER_EOSMPIE /*!< ADC End of Sampling interrupt source */ +#define ADC_IT_RDY ADC_IER_ADRDYIE /*!< ADC Ready interrupt source */ +/** + * @} + */ + +/** @defgroup ADC_flags_definition ADC flags definition + * @{ + */ +#define ADC_FLAG_AWD ADC_ISR_AWD /*!< ADC Analog watchdog flag */ +#define ADC_FLAG_OVR ADC_ISR_OVR /*!< ADC overrun flag */ +#define ADC_FLAG_EOS \ + ADC_ISR_EOSEQ /*!< ADC End of Regular sequence of Conversions flag \ + */ +#define ADC_FLAG_EOC ADC_ISR_EOC /*!< ADC End of Regular Conversion flag */ +#define ADC_FLAG_EOSMP ADC_ISR_EOSMP /*!< ADC End of Sampling flag */ +#define ADC_FLAG_RDY ADC_ISR_ADRDY /*!< ADC Ready flag */ +/** + * @} + */ + +/** + * @} + */ + + +/* Private constants ---------------------------------------------------------*/ + +/** @addtogroup ADC_Private_Constants ADC Private Constants + * @{ + */ + +/** @defgroup ADC_Internal_HAL_driver_Ext_trig_src_Regular ADC Internal HAL driver Ext + * trig src Regular + * @{ + */ + +/* List of external triggers of regular group for ADC1: */ +/* (used internally by HAL driver. To not use into HAL structure parameters) */ +#define ADC1_2_EXTERNALTRIG_T1_TRGO (0x00000000U) +#define ADC1_2_EXTERNALTRIG_T1_CC4 ((uint32_t)ADC_CFGR1_EXTSEL_0) +#define ADC1_2_EXTERNALTRIG_T2_TRGO ((uint32_t)ADC_CFGR1_EXTSEL_1) +#define ADC1_2_EXTERNALTRIG_T3_TRGO ((uint32_t)(ADC_CFGR1_EXTSEL_1 | ADC_CFGR1_EXTSEL_0)) +#define ADC1_2_EXTERNALTRIG_T15_TRGO ((uint32_t)ADC_CFGR1_EXTSEL_2) +/** + * @} + */ + +/* Combination of all post-conversion flags bits: EOC/EOS, OVR, AWD */ +#define ADC_FLAG_POSTCONV_ALL (ADC_FLAG_AWD | ADC_FLAG_OVR | ADC_FLAG_EOS | ADC_FLAG_EOC) + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Macros ADC Exported Macros + * @{ + */ +/* Macro for internal HAL driver usage, and possibly can be used into code of */ +/* final user. */ + +/** + * @brief Enable the ADC peripheral + * @param __HANDLE__ ADC handle + * @retval None + */ +#define __HAL_ADC_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= ADC_CR_ADEN) + +/** + * @brief Disable the ADC peripheral + * @param __HANDLE__ ADC handle + * @retval None + */ +#define __HAL_ADC_DISABLE(__HANDLE__) \ + do \ + { \ + (__HANDLE__)->Instance->CR |= ADC_CR_ADDIS; \ + __HAL_ADC_CLEAR_FLAG((__HANDLE__), (ADC_FLAG_EOSMP | ADC_FLAG_RDY)); \ + } while (0) + +/** + * @brief Enable the ADC end of conversion interrupt. + * @param __HANDLE__ ADC handle + * @param __INTERRUPT__ ADC Interrupt + * This parameter can be any combination of the following values: + * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source + * @arg ADC_IT_EOS: ADC End of Regular sequence of Conversions interrupt source + * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source + * @arg ADC_IT_OVR: ADC overrun interrupt source + * @arg ADC_IT_EOSMP: ADC End of Sampling interrupt source + * @arg ADC_IT_RDY: ADC Ready interrupt source + * @retval None + */ +#define __HAL_ADC_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__)) + +/** + * @brief Disable the ADC end of conversion interrupt. + * @param __HANDLE__ ADC handle + * @param __INTERRUPT__ ADC Interrupt + * This parameter can be any combination of the following values: + * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source + * @arg ADC_IT_EOS: ADC End of Regular sequence of Conversions interrupt source + * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source + * @arg ADC_IT_OVR: ADC overrun interrupt source + * @arg ADC_IT_EOSMP: ADC End of Sampling interrupt source + * @arg ADC_IT_RDY: ADC Ready interrupt source + * @retval None + */ +#define __HAL_ADC_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__)) + +/** @brief Checks if the specified ADC interrupt source is enabled or disabled. + * @param __HANDLE__ ADC handle + * @param __INTERRUPT__ ADC interrupt source to check + * This parameter can be any combination of the following values: + * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source + * @arg ADC_IT_EOS: ADC End of Regular sequence of Conversions interrupt source + * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source + * @arg ADC_IT_OVR: ADC overrun interrupt source + * @arg ADC_IT_EOSMP: ADC End of Sampling interrupt source + * @arg ADC_IT_RDY: ADC Ready interrupt source + * @retval State ofinterruption (SET or RESET) + */ +#define __HAL_ADC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->IER & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Get the selected ADC's flag status. + * @param __HANDLE__ ADC handle + * @param __FLAG__ ADC flag + * This parameter can be any combination of the following values: + * @arg ADC_FLAG_EOC: ADC End of Regular conversion flag + * @arg ADC_FLAG_EOS: ADC End of Regular sequence of Conversions flag + * @arg ADC_FLAG_AWD: ADC Analog watchdog flag + * @arg ADC_FLAG_OVR: ADC overrun flag + * @arg ADC_FLAG_EOSMP: ADC End of Sampling flag + * @arg ADC_FLAG_RDY: ADC Ready flag + * @retval None + */ +#define __HAL_ADC_GET_FLAG(__HANDLE__, __FLAG__) \ + ((((__HANDLE__)->Instance->ISR) & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the ADC's pending flags + * @param __HANDLE__ ADC handle + * @param __FLAG__ ADC flag + * This parameter can be any combination of the following values: + * @arg ADC_FLAG_EOC: ADC End of Regular conversion flag + * @arg ADC_FLAG_EOS: ADC End of Regular sequence of Conversions flag + * @arg ADC_FLAG_AWD: ADC Analog watchdog flag + * @arg ADC_FLAG_OVR: ADC overrun flag + * @arg ADC_FLAG_EOSMP: ADC End of Sampling flag + * @arg ADC_FLAG_RDY: ADC Ready flag + * @retval None + */ +/* Note: bit cleared bit by writing 1 (writing 0 has no effect on any bit of register ISR) + */ +#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + (((__HANDLE__)->Instance->ISR) = (__FLAG__)) + +/** @brief Reset ADC handle state + * @param __HANDLE__ ADC handle + * @retval None + */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) \ + do \ + { \ + (__HANDLE__)->State = HAL_ADC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while (0) +#else +#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) \ + ((__HANDLE__)->State = HAL_ADC_STATE_RESET) +#endif + +/** + * @} + */ + + +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup ADC_Private_Macros ADC Private Macros + * @{ + */ +/* Macro reserved for internal HAL driver usage, not intended to be used in */ +/* code of final user. */ + + +/** + * @brief Verification of hardware constraints before ADC can be enabled + * @param __HANDLE__ ADC handle + * @retval SET (ADC can be enabled) or RESET (ADC cannot be enabled) + */ +#define ADC_ENABLING_CONDITIONS(__HANDLE__) \ + (((((__HANDLE__)->Instance->CR) & (ADC_CR_ADCAL | ADC_CR_ADSTP | ADC_CR_ADSTART | \ + ADC_CR_ADDIS | ADC_CR_ADEN)) == RESET) \ + ? SET \ + : RESET) + +/** + * @brief Verification of hardware constraints before ADC can be disabled + * @param __HANDLE__ ADC handle + * @retval SET (ADC can be disabled) or RESET (ADC cannot be disabled) + */ +#define ADC_DISABLING_CONDITIONS(__HANDLE__) \ + (((((__HANDLE__)->Instance->CR) & (ADC_CR_ADSTART | ADC_CR_ADEN)) == ADC_CR_ADEN) \ + ? SET \ + : RESET) + +/** + * @brief Verification of ADC state: enabled or disabled + * @param __HANDLE__ ADC handle + * @retval SET (ADC enabled) or RESET (ADC disabled) + */ +/* Note: If low power mode AutoPowerOff is enabled, power-on/off phases are */ +/* performed automatically by hardware and flag ADC_FLAG_RDY is not */ +/* set. */ +#define ADC_IS_ENABLE(__HANDLE__) \ + ((((((__HANDLE__)->Instance->CR) & (ADC_CR_ADEN | ADC_CR_ADDIS)) == ADC_CR_ADEN) && \ + (((((__HANDLE__)->Instance->ISR) & ADC_FLAG_RDY) == ADC_FLAG_RDY) || \ + ((((__HANDLE__)->Instance->CFGR1) & ADC_CFGR1_AUTOFF) == ADC_CFGR1_AUTOFF))) \ + ? SET \ + : RESET) + +/** + * @brief Test if conversion trigger of regular group is software start + * or external trigger. + * @param __HANDLE__ ADC handle + * @retval SET (software start) or RESET (external trigger) + */ +#define ADC_IS_SOFTWARE_START_REGULAR(__HANDLE__) \ + (((__HANDLE__)->Instance->CFGR1 & ADC_CFGR1_EXTEN) == RESET) + +/** + * @brief Check if no conversion on going on regular group + * @param __HANDLE__ ADC handle + * @retval SET (conversion is on going) or RESET (no conversion is on going) + */ +#define ADC_IS_CONVERSION_ONGOING_REGULAR(__HANDLE__) \ + (((((__HANDLE__)->Instance->CR) & ADC_CR_ADSTART) == RESET) ? RESET : SET) + +/** + * @brief Returns resolution bits in CFGR1 register: RES[1:0]. + * Returned value is among parameters to @ref ADC_Resolution. + * @param __HANDLE__ ADC handle + * @retval None + */ +#define ADC_GET_RESOLUTION(__HANDLE__) (((__HANDLE__)->Instance->CFGR1) & ADC_CFGR1_RES) + +/** + * @brief Returns ADC sample time bits in SMPR register: SMP[2:0]. + * Returned value is among parameters to @ref ADC_Resolution. + * @param __HANDLE__ ADC handle + * @retval None + */ +#define ADC_GET_SAMPLINGTIME(__HANDLE__) (((__HANDLE__)->Instance->SMPR) & ADC_SMPR_SMP) + +/** + * @brief Simultaneously clears and sets specific bits of the handle State + * @note: ADC_STATE_CLR_SET() macro is merely aliased to generic macro MODIFY_REG(), + * the first parameter is the ADC handle State, the second parameter is the + * bit field to clear, the third and last parameter is the bit field to set. + * @retval None + */ +#define ADC_STATE_CLR_SET MODIFY_REG + +/** + * @brief Clear ADC error code (set it to error code: "no error") + * @param __HANDLE__ ADC handle + * @retval None + */ +#define ADC_CLEAR_ERRORCODE(__HANDLE__) ((__HANDLE__)->ErrorCode = HAL_ADC_ERROR_NONE) + + +/** + * @brief Configure the channel number into channel selection register + * @param _CHANNEL_ ADC Channel + * @retval None + */ +/* This function converts ADC channels from numbers (see defgroup ADC_channels) + to bitfields, to get the equivalence of CMSIS channels: + ADC_CHANNEL_0 ((uint32_t) ADC_CHSELR_CHSEL0) + ADC_CHANNEL_1 ((uint32_t) ADC_CHSELR_CHSEL1) + ADC_CHANNEL_2 ((uint32_t) ADC_CHSELR_CHSEL2) + ADC_CHANNEL_3 ((uint32_t) ADC_CHSELR_CHSEL3) + ADC_CHANNEL_4 ((uint32_t) ADC_CHSELR_CHSEL4) + ADC_CHANNEL_5 ((uint32_t) ADC_CHSELR_CHSEL5) + ADC_CHANNEL_6 ((uint32_t) ADC_CHSELR_CHSEL6) + ADC_CHANNEL_7 ((uint32_t) ADC_CHSELR_CHSEL7) + ADC_CHANNEL_8 ((uint32_t) ADC_CHSELR_CHSEL8) + ADC_CHANNEL_9 ((uint32_t) ADC_CHSELR_CHSEL9) + ADC_CHANNEL_10 ((uint32_t) ADC_CHSELR_CHSEL10) + ADC_CHANNEL_11 ((uint32_t) ADC_CHSELR_CHSEL11) + ADC_CHANNEL_12 ((uint32_t) ADC_CHSELR_CHSEL12) + ADC_CHANNEL_13 ((uint32_t) ADC_CHSELR_CHSEL13) + ADC_CHANNEL_14 ((uint32_t) ADC_CHSELR_CHSEL14) + ADC_CHANNEL_15 ((uint32_t) ADC_CHSELR_CHSEL15) + ADC_CHANNEL_16 ((uint32_t) ADC_CHSELR_CHSEL16) + ADC_CHANNEL_17 ((uint32_t) ADC_CHSELR_CHSEL17) + ADC_CHANNEL_18 ((uint32_t) ADC_CHSELR_CHSEL18) +*/ +#define ADC_CHSELR_CHANNEL(_CHANNEL_) (1U << (_CHANNEL_)) + +/** + * @brief Set the ADC's sample time + * @param _SAMPLETIME_ Sample time parameter. + * @retval None + */ +/* Note: ADC sampling time set using mask ADC_SMPR_SMP due to parameter */ +/* "ADC_SAMPLETIME_1CYCLE_5" defined with a dummy bit (bit used to */ +/* distinguish this parameter versus reset value 0x00000000, */ +/* in the context of management of parameters "SamplingTimeCommon" */ +/* and "SamplingTime" (obsolete)). */ +#define ADC_SMPR_SET(_SAMPLETIME_) ((_SAMPLETIME_) & (ADC_SMPR_SMP)) + +/** + * @brief Set the Analog Watchdog 1 channel. + * @param _CHANNEL_ channel to be monitored by Analog Watchdog 1. + * @retval None + */ +#define ADC_CFGR_AWDCH(_CHANNEL_) ((_CHANNEL_) << 26U) + +/** + * @brief Enable ADC discontinuous conversion mode for regular group + * @param _REG_DISCONTINUOUS_MODE_ Regular discontinuous mode. + * @retval None + */ +#define ADC_CFGR1_REG_DISCCONTINUOUS(_REG_DISCONTINUOUS_MODE_) \ + ((_REG_DISCONTINUOUS_MODE_) << 16U) + +/** + * @brief Enable the ADC auto off mode. + * @param _AUTOOFF_ Auto off bit enable or disable. + * @retval None + */ +#define ADC_CFGR1_AUTOOFF(_AUTOOFF_) ((_AUTOOFF_) << 15U) + +/** + * @brief Enable the ADC auto delay mode. + * @param _AUTOWAIT_ Auto delay bit enable or disable. + * @retval None + */ +#define ADC_CFGR1_AUTOWAIT(_AUTOWAIT_) ((_AUTOWAIT_) << 14U) + +/** + * @brief Enable ADC continuous conversion mode. + * @param _CONTINUOUS_MODE_ Continuous mode. + * @retval None + */ +#define ADC_CFGR1_CONTINUOUS(_CONTINUOUS_MODE_) ((_CONTINUOUS_MODE_) << 13U) + +/** + * @brief Enable ADC overrun mode. + * @param _OVERRUN_MODE_ Overrun mode. + * @retval Overrun bit setting to be programmed into CFGR register + */ +/* Note: Bit ADC_CFGR1_OVRMOD not used directly in constant */ +/* "ADC_OVR_DATA_OVERWRITTEN" to have this case defined to 0x00, to set it */ +/* as the default case to be compliant with other STM32 devices. */ +#define ADC_CFGR1_OVERRUN(_OVERRUN_MODE_) \ + (((_OVERRUN_MODE_) != (ADC_OVR_DATA_PRESERVED)) ? (ADC_CFGR1_OVRMOD) : (0x00000000)) + +/** + * @brief Enable ADC scan mode to convert multiple ranks with sequencer. + * @param _SCAN_MODE_ Scan conversion mode. + * @retval None + */ +/* Note: Scan mode set using this macro (instead of parameter direct set) */ +/* due to different modes on other STM32 devices: to avoid any */ +/* unwanted setting, the exact parameter corresponding to the device */ +/* must be passed to this macro. */ +#define ADC_SCANDIR(_SCAN_MODE_) \ + (((_SCAN_MODE_) == (ADC_SCAN_DIRECTION_BACKWARD)) ? (ADC_CFGR1_SCANDIR) \ + : (0x00000000)) + +/** + * @brief Enable the ADC DMA continuous request. + * @param _DMACONTREQ_MODE_ DMA continuous request mode. + * @retval None + */ +#define ADC_CFGR1_DMACONTREQ(_DMACONTREQ_MODE_) ((_DMACONTREQ_MODE_) << 1U) + +/** + * @brief Configure the analog watchdog high threshold into register TR. + * @param _Threshold_ Threshold value + * @retval None + */ +#define ADC_TRX_HIGHTHRESHOLD(_Threshold_) ((_Threshold_) << 16U) + +/** + * @brief Shift the AWD threshold in function of the selected ADC resolution. + * Thresholds have to be left-aligned on bit 11, the LSB (right bits) are set to 0. + * If resolution 12 bits, no shift. + * If resolution 10 bits, shift of 2 ranks on the left. + * If resolution 8 bits, shift of 4 ranks on the left. + * If resolution 6 bits, shift of 6 ranks on the left. + * therefore, shift = (12 - resolution) = 12 - (12- (((RES[1:0]) >> 3)*2)) + * @param __HANDLE__ ADC handle + * @param _Threshold_ Value to be shifted + * @retval None + */ +#define ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(__HANDLE__, _Threshold_) \ + ((_Threshold_) << ((((__HANDLE__)->Instance->CFGR1 & ADC_CFGR1_RES) >> 3U) * 2)) + + +#define IS_ADC_CLOCKPRESCALER(ADC_CLOCK) \ + (((ADC_CLOCK) == ADC_CLOCK_ASYNC_DIV1) || \ + ((ADC_CLOCK) == ADC_CLOCK_SYNC_PCLK_DIV2) || \ + ((ADC_CLOCK) == ADC_CLOCK_SYNC_PCLK_DIV4)) + +#define IS_ADC_RESOLUTION(RESOLUTION) \ + (((RESOLUTION) == ADC_RESOLUTION_12B) || ((RESOLUTION) == ADC_RESOLUTION_10B) || \ + ((RESOLUTION) == ADC_RESOLUTION_8B) || ((RESOLUTION) == ADC_RESOLUTION_6B)) + +#define IS_ADC_DATA_ALIGN(ALIGN) \ + (((ALIGN) == ADC_DATAALIGN_RIGHT) || ((ALIGN) == ADC_DATAALIGN_LEFT)) + +#define IS_ADC_SCAN_MODE(SCAN_MODE) \ + (((SCAN_MODE) == ADC_SCAN_DIRECTION_FORWARD) || \ + ((SCAN_MODE) == ADC_SCAN_DIRECTION_BACKWARD)) + +#define IS_ADC_EXTTRIG_EDGE(EDGE) \ + (((EDGE) == ADC_EXTERNALTRIGCONVEDGE_NONE) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISING) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_FALLING) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING)) + +#define IS_ADC_EOC_SELECTION(EOC_SELECTION) \ + (((EOC_SELECTION) == ADC_EOC_SINGLE_CONV) || ((EOC_SELECTION) == ADC_EOC_SEQ_CONV)) + +#define IS_ADC_OVERRUN(OVR) \ + (((OVR) == ADC_OVR_DATA_PRESERVED) || ((OVR) == ADC_OVR_DATA_OVERWRITTEN)) + +#define IS_ADC_RANK(WATCHDOG) \ + (((WATCHDOG) == ADC_RANK_CHANNEL_NUMBER) || ((WATCHDOG) == ADC_RANK_NONE)) + +#define IS_ADC_SAMPLE_TIME(TIME) \ + (((TIME) == ADC_SAMPLETIME_1CYCLE_5) || ((TIME) == ADC_SAMPLETIME_7CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_13CYCLES_5) || ((TIME) == ADC_SAMPLETIME_28CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_41CYCLES_5) || ((TIME) == ADC_SAMPLETIME_55CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_71CYCLES_5) || ((TIME) == ADC_SAMPLETIME_239CYCLES_5)) + +#define IS_ADC_ANALOG_WATCHDOG_MODE(WATCHDOG) \ + (((WATCHDOG) == ADC_ANALOGWATCHDOG_NONE) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REG) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REG)) + +#define IS_ADC_EVENT_TYPE(EVENT) \ + (((EVENT) == ADC_AWD_EVENT) || ((EVENT) == ADC_OVR_EVENT)) + +/** @defgroup ADC_range_verification ADC range verification + * in function of ADC resolution selected (12, 10, 8 or 6 bits) + * @{ + */ +#define IS_ADC_RANGE(RESOLUTION, ADC_VALUE) \ + ((((RESOLUTION) == ADC_RESOLUTION_12B) && ((ADC_VALUE) <= (0x0FFFU))) || \ + (((RESOLUTION) == ADC_RESOLUTION_10B) && ((ADC_VALUE) <= (0x03FFU))) || \ + (((RESOLUTION) == ADC_RESOLUTION_8B) && ((ADC_VALUE) <= (0x00FFU))) || \ + (((RESOLUTION) == ADC_RESOLUTION_6B) && ((ADC_VALUE) <= (0x003FU)))) +/** + * @} + */ + +/** @defgroup ADC_regular_rank_verification ADC regular rank verification + * @{ + */ +#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= (1U)) && ((RANK) <= (16U))) +/** + * @} + */ + +/** + * @} + */ + +/* Include ADC HAL Extension module */ +#include "stm32f0xx_hal_adc_ex.h" + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup ADC_Exported_Functions + * @{ + */ + + /** @addtogroup ADC_Exported_Functions_Group1 + * @{ + */ + + + /* Initialization and de-initialization functions **********************************/ + HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc); + HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc); + void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc); + void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc); + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + /* Callbacks Register/UnRegister functions ***********************************/ + HAL_StatusTypeDef HAL_ADC_RegisterCallback(ADC_HandleTypeDef* hadc, + HAL_ADC_CallbackIDTypeDef CallbackID, + pADC_CallbackTypeDef pCallback); + HAL_StatusTypeDef HAL_ADC_UnRegisterCallback(ADC_HandleTypeDef* hadc, + HAL_ADC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /** + * @} + */ + + /* IO operation functions *****************************************************/ + + /** @addtogroup ADC_Exported_Functions_Group2 + * @{ + */ + + + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); + HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc); + HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, + uint32_t Timeout); + HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, + uint32_t Timeout); + + /* Non-blocking mode: Interruption */ + HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc); + HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc); + + /* Non-blocking mode: DMA */ + HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, + uint32_t Length); + HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc); + + /* ADC retrieve conversion value intended to be used with polling or interruption */ + uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc); + + /* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption and DMA) */ + void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc); + void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc); + void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc); + void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc); + void HAL_ADC_ErrorCallback(ADC_HandleTypeDef* hadc); + /** + * @} + */ + + + /* Peripheral Control functions ***********************************************/ + /** @addtogroup ADC_Exported_Functions_Group3 + * @{ + */ + HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, + ADC_ChannelConfTypeDef* sConfig); + HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, + ADC_AnalogWDGConfTypeDef* AnalogWDGConfig); + /** + * @} + */ + + + /* Peripheral State functions *************************************************/ + /** @addtogroup ADC_Exported_Functions_Group4 + * @{ + */ + uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc); + uint32_t HAL_ADC_GetError(ADC_HandleTypeDef* hadc); + /** + * @} + */ + + + /** + * @} + */ + + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32F0xx_HAL_ADC_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_adc_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_adc_ex.h new file mode 100644 index 0000000000..fd8d1b59f3 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_adc_ex.h @@ -0,0 +1,268 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_adc_ex.h + * @author MCD Application Team + * @brief Header file of ADC HAL Extension module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_ADC_EX_H +#define __STM32F0xx_HAL_ADC_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup ADCEx + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /* Exported constants --------------------------------------------------------*/ + + /** @defgroup ADC_Exported_Constants ADC Exported Constants + * @{ + */ + +#if !defined(STM32F030x6) && !defined(STM32F030x8) && !defined(STM32F070x6) && \ + !defined(STM32F070xB) && !defined(STM32F030xC) +#define ADC_CCR_ALL (ADC_CCR_VBATEN | ADC_CCR_TSEN | ADC_CCR_VREFEN) +#else +#define ADC_CCR_ALL (ADC_CCR_TSEN | ADC_CCR_VREFEN) +#endif + +/** @defgroup ADC_External_trigger_source_Regular ADC External trigger source Regular + * @{ + */ +/* List of external triggers with generic trigger name, sorted by trigger */ +/* name: */ + +/* External triggers of regular group for ADC1 */ +#define ADC_EXTERNALTRIGCONV_T1_TRGO ADC1_2_EXTERNALTRIG_T1_TRGO +#define ADC_EXTERNALTRIGCONV_T1_CC4 ADC1_2_EXTERNALTRIG_T1_CC4 +#define ADC_EXTERNALTRIGCONV_T3_TRGO ADC1_2_EXTERNALTRIG_T3_TRGO +#define ADC_SOFTWARE_START (ADC_CFGR1_EXTSEL + 1U) + +#if !defined(STM32F030x6) && !defined(STM32F030x8) && !defined(STM32F070x6) && \ + !defined(STM32F070xB) && !defined(STM32F030xC) +#define ADC_EXTERNALTRIGCONV_T2_TRGO ADC1_2_EXTERNALTRIG_T2_TRGO +#endif + +#if !defined(STM32F030x6) && !defined(STM32F070x6) && !defined(STM32F042x6) +#define ADC_EXTERNALTRIGCONV_T15_TRGO ADC1_2_EXTERNALTRIG_T15_TRGO +#endif + +/** + * @} + */ + + +/** @defgroup ADC_channels ADC channels + * @{ + */ +/* Note: Depending on devices, some channels may not be available on package */ +/* pins. Refer to device datasheet for channels availability. */ +/* Note: Channels are used by bitfields for setting of channel selection */ +/* (register ADC_CHSELR) and used by number for setting of analog */ +/* watchdog channel (bits AWDCH in register ADC_CFGR1). */ +/* Channels are defined with decimal numbers and converted them to */ +/* bitfields when needed. */ +#define ADC_CHANNEL_0 (0x00000000U) +#define ADC_CHANNEL_1 (0x00000001U) +#define ADC_CHANNEL_2 (0x00000002U) +#define ADC_CHANNEL_3 (0x00000003U) +#define ADC_CHANNEL_4 (0x00000004U) +#define ADC_CHANNEL_5 (0x00000005U) +#define ADC_CHANNEL_6 (0x00000006U) +#define ADC_CHANNEL_7 (0x00000007U) +#define ADC_CHANNEL_8 (0x00000008U) +#define ADC_CHANNEL_9 (0x00000009U) +#define ADC_CHANNEL_10 (0x0000000AU) +#define ADC_CHANNEL_11 (0x0000000BU) +#define ADC_CHANNEL_12 (0x0000000CU) +#define ADC_CHANNEL_13 (0x0000000DU) +#define ADC_CHANNEL_14 (0x0000000EU) +#define ADC_CHANNEL_15 (0x0000000FU) +#define ADC_CHANNEL_16 (0x00000010U) +#define ADC_CHANNEL_17 (0x00000011U) + +#define ADC_CHANNEL_TEMPSENSOR ADC_CHANNEL_16 +#define ADC_CHANNEL_VREFINT ADC_CHANNEL_17 + +#if !defined(STM32F030x6) && !defined(STM32F030x8) && !defined(STM32F070x6) && \ + !defined(STM32F070xB) && !defined(STM32F030xC) +#define ADC_CHANNEL_18 (0x00000012U) +#define ADC_CHANNEL_VBAT ADC_CHANNEL_18 +#endif + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + + +/* Private macros ------------------------------------------------------------*/ + +/** @defgroup ADCEx_Private_Macros ADCEx Private Macros + * @{ + */ +/* Macro reserved for internal HAL driver usage, not intended to be used in */ +/* code of final user. */ + +/** + * @brief Test if the selected ADC channel is an internal channel + * VrefInt/TempSensor/Vbat + * Note: On STM32F0, availability of internal channel Vbat depends on + * devices lines. + * @param __CHANNEL__ ADC channel + * @retval None + */ +#if !defined(STM32F030x6) && !defined(STM32F030x8) && !defined(STM32F070x6) && \ + !defined(STM32F070xB) && !defined(STM32F030xC) +#define ADC_IS_CHANNEL_INTERNAL(__CHANNEL__) \ + (((__CHANNEL__) == ADC_CHANNEL_TEMPSENSOR) || \ + ((__CHANNEL__) == ADC_CHANNEL_VREFINT) || ((__CHANNEL__) == ADC_CHANNEL_VBAT)) +#else +#define ADC_IS_CHANNEL_INTERNAL(__CHANNEL__) \ + (((__CHANNEL__) == ADC_CHANNEL_TEMPSENSOR) || ((__CHANNEL__) == ADC_CHANNEL_VREFINT)) +#endif + +/** + * @brief Select the internal measurement path to be enabled/disabled + * corresponding to the selected ADC internal channel + * VrefInt/TempSensor/Vbat. + * Note: On STM32F0, availability of internal channel Vbat depends on + * devices lines. + * @param __CHANNEL__ ADC channel + * @retval Bit of register ADC_CCR + */ +#if !defined(STM32F030x6) && !defined(STM32F030x8) && !defined(STM32F070x6) && \ + !defined(STM32F070xB) && !defined(STM32F030xC) +#define ADC_CHANNEL_INTERNAL_PATH(__CHANNEL__) \ + (((__CHANNEL__) == ADC_CHANNEL_TEMPSENSOR) \ + ? (ADC_CCR_TSEN) \ + : (((__CHANNEL__) == ADC_CHANNEL_VREFINT) ? (ADC_CCR_VREFEN) \ + : (ADC_CCR_VBATEN))) +#else +#define ADC_CHANNEL_INTERNAL_PATH(__CHANNEL__) \ + (((__CHANNEL__) == ADC_CHANNEL_TEMPSENSOR) ? (ADC_CCR_TSEN) : (ADC_CCR_VREFEN)) +#endif + + +#if defined(STM32F030x6) || defined(STM32F070x6) +#define IS_ADC_EXTTRIG(REGTRIG) \ + (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || ((REGTRIG) == ADC_SOFTWARE_START)) +#elif defined(STM32F042x6) +#define IS_ADC_EXTTRIG(REGTRIG) \ + (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || ((REGTRIG) == ADC_SOFTWARE_START)) + +#elif defined(STM32F030xC) || defined(STM32F070xB) || defined(STM32F030x8) +#define IS_ADC_EXTTRIG(REGTRIG) \ + (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T15_TRGO) || ((REGTRIG) == ADC_SOFTWARE_START)) +#else +#define IS_ADC_EXTTRIG(REGTRIG) \ + (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T15_TRGO) || ((REGTRIG) == ADC_SOFTWARE_START)) +#endif + +#if !defined(STM32F030x6) && !defined(STM32F030x8) && !defined(STM32F070x6) && \ + !defined(STM32F070xB) && !defined(STM32F030xC) +#define IS_ADC_CHANNEL(CHANNEL) \ + (((CHANNEL) == ADC_CHANNEL_0) || ((CHANNEL) == ADC_CHANNEL_1) || \ + ((CHANNEL) == ADC_CHANNEL_2) || ((CHANNEL) == ADC_CHANNEL_3) || \ + ((CHANNEL) == ADC_CHANNEL_4) || ((CHANNEL) == ADC_CHANNEL_5) || \ + ((CHANNEL) == ADC_CHANNEL_6) || ((CHANNEL) == ADC_CHANNEL_7) || \ + ((CHANNEL) == ADC_CHANNEL_8) || ((CHANNEL) == ADC_CHANNEL_9) || \ + ((CHANNEL) == ADC_CHANNEL_10) || ((CHANNEL) == ADC_CHANNEL_11) || \ + ((CHANNEL) == ADC_CHANNEL_12) || ((CHANNEL) == ADC_CHANNEL_13) || \ + ((CHANNEL) == ADC_CHANNEL_14) || ((CHANNEL) == ADC_CHANNEL_15) || \ + ((CHANNEL) == ADC_CHANNEL_TEMPSENSOR) || ((CHANNEL) == ADC_CHANNEL_VREFINT) || \ + ((CHANNEL) == ADC_CHANNEL_VBAT)) +#else +#define IS_ADC_CHANNEL(CHANNEL) \ + (((CHANNEL) == ADC_CHANNEL_0) || ((CHANNEL) == ADC_CHANNEL_1) || \ + ((CHANNEL) == ADC_CHANNEL_2) || ((CHANNEL) == ADC_CHANNEL_3) || \ + ((CHANNEL) == ADC_CHANNEL_4) || ((CHANNEL) == ADC_CHANNEL_5) || \ + ((CHANNEL) == ADC_CHANNEL_6) || ((CHANNEL) == ADC_CHANNEL_7) || \ + ((CHANNEL) == ADC_CHANNEL_8) || ((CHANNEL) == ADC_CHANNEL_9) || \ + ((CHANNEL) == ADC_CHANNEL_10) || ((CHANNEL) == ADC_CHANNEL_11) || \ + ((CHANNEL) == ADC_CHANNEL_12) || ((CHANNEL) == ADC_CHANNEL_13) || \ + ((CHANNEL) == ADC_CHANNEL_14) || ((CHANNEL) == ADC_CHANNEL_15) || \ + ((CHANNEL) == ADC_CHANNEL_TEMPSENSOR) || ((CHANNEL) == ADC_CHANNEL_VREFINT)) +#endif + + /** + * @} + */ + + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup ADCEx_Exported_Functions + * @{ + */ + + /* IO operation functions *****************************************************/ + /** @addtogroup ADCEx_Exported_Functions_Group1 + * @{ + */ + + /* ADC calibration */ + HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc); + /** + * @} + */ + + + /** + * @} + */ + + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_ADC_EX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_conf.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_conf.h new file mode 100644 index 0000000000..c5c317bb10 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_conf.h @@ -0,0 +1,331 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_CONF_H +#define __STM32F0xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED + /*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_CEC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/* USER CODE BEGIN SPI_ENABLE */ +#define HAL_SPI_MODULE_ENABLED +/* USER CODE END SPI_ENABLE */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your + * application. This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + * Timeout value + */ +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined(HSI_VALUE) +#define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + * Timeout value + */ +#if !defined(HSI_STARTUP_TIMEOUT) +#define HSI_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSI start up */ +#endif /* HSI_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator for ADC (HSI14) value. + */ +#if !defined(HSI14_VALUE) +#define HSI14_VALUE \ + ((uint32_t)14000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. \ + The real value may vary depending on the variations \ + in voltage and temperature. */ +#endif /* HSI14_VALUE */ + +/** + * @brief Internal High Speed oscillator for USB (HSI48) value. + */ +#if !defined(HSI48_VALUE) +#define HSI48_VALUE \ + ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz. \ + The real value may vary depending on the variations \ + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined(LSI_VALUE) +#define LSI_VALUE ((uint32_t)40000) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \ + The real value may vary depending on the variations \ + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSI) value. + */ +#if !defined(LSE_VALUE) +#define LSE_VALUE \ + ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +/** + * @brief Time out for LSE start up value in ms. + */ +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY \ + ((uint32_t)2) /*!< tick interrupt priority (lowest by default) */ + /* Warning: Must be set to higher priority for HAL_Delay() */ + /* and HAL_GetTick() usage under interrupt context */ +#define USE_RTOS 0 +#define PREFETCH_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 0 +#define DATA_CACHE_ENABLE 0 +#define USE_SPI_CRC 0U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS \ + 0U /* SMARTCARD register callback disabled \ + */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ + + /* ########################## Assert Selection ############################## */ + /** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ + /* #define USE_FULL_ASSERT 1U */ + + /* Includes ------------------------------------------------------------------*/ + /** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32f0xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32f0xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32f0xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32f0xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32f0xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32f0xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED +#include "stm32f0xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED +#include "stm32f0xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32f0xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32f0xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32f0xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32f0xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32f0xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32f0xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32f0xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32f0xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32f0xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32f0xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32f0xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32f0xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32f0xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32f0xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32f0xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED +#include "stm32f0xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32f0xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32f0xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32f0xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT + /** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) \ + ((expr) ? (void)0U : assert_failed((uint8_t*)__FILE__, __LINE__)) + /* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_CONF_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_cortex.c b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_cortex.c new file mode 100644 index 0000000000..04fcbab4f7 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_cortex.c @@ -0,0 +1,353 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_cortex.c + * @author MCD Application Team + * @brief CORTEX HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the CORTEX: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + * @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + + [..] + *** How to configure Interrupts using CORTEX HAL driver *** + =========================================================== + [..] + This section provides functions allowing to configure the NVIC interrupts (IRQ). + The Cortex-M0 exceptions are managed by CMSIS functions. + (#) Enable and Configure the priority of the selected IRQ Channels. + The priority can be 0..3. + + -@- Lower priority values gives higher priority. + -@- Priority Order: + (#@) Lowest priority. + (#@) Lowest hardware priority (IRQn position). + + (#) Configure the priority of the selected IRQ Channels using + HAL_NVIC_SetPriority() + + (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ() + + -@- Negative value of IRQn_Type are not allowed. + + + [..] + *** How to configure Systick using CORTEX HAL driver *** + ======================================================== + [..] + Setup SysTick Timer for time base. + + (+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which + is a CMSIS function that: + (++) Configures the SysTick Reload register with value passed as function + parameter. + (++) Configures the SysTick IRQ priority to the lowest value (0x03). + (++) Resets the SysTick Counter register. + (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK). + (++) Enables the SysTick Interrupt. + (++) Starts the SysTick Counter. + + (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the + HAL_SYSTICK_Config() function call. The HAL_SYSTICK_CLKSourceConfig() macro is + defined inside the stm32f0xx_hal_cortex.h file. + + (+) You can change the SysTick IRQ priority by calling the + HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() + function call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is + a CMSIS function. + + (+) To adjust the SysTick time base, use the following formula: + + Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s) + (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function + (++) Reload Value should not exceed 0xFFFFFF + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup CORTEX CORTEX + * @brief CORTEX CORTEX HAL module driver + * @{ + */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions + * @{ + */ + + +/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization +functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions allowing to configure +Interrupts Systick functionalities + +@endverbatim + * @{ + */ + +/** + * @brief Sets the priority of an interrupt. + * @param IRQn External interrupt number . + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to stm32f0xx.h + * file) + * @param PreemptPriority The preemption priority for the IRQn channel. + * This parameter can be a value between 0 and 3. + * A lower priority value indicates a higher priority + * @param SubPriority the subpriority level for the IRQ channel. + * with stm32f0xx devices, this parameter is a dummy value and it is ignored, + * because no subpriority supported in Cortex M0 based products. + * @retval None + */ +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority)); + NVIC_SetPriority(IRQn, PreemptPriority); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(SubPriority); +} + +/** + * @brief Enables a device specific interrupt in the NVIC interrupt controller. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the + * appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Enable interrupt */ + NVIC_EnableIRQ(IRQn); +} + +/** + * @brief Disables a device specific interrupt in the NVIC interrupt controller. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the + * appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Disable interrupt */ + NVIC_DisableIRQ(IRQn); +} + +/** + * @brief Initiates a system reset request to reset the MCU. + * @retval None + */ +void HAL_NVIC_SystemReset(void) +{ + /* System Reset */ + NVIC_SystemReset(); +} + +/** + * @brief Initializes the System Timer and its interrupt, and starts the System Tick + * Timer. Counter is in free running mode to generate periodic interrupts. + * @param TicksNumb Specifies the ticks Number of ticks between two interrupts. + * @retval status: - 0 Function succeeded. + * - 1 Function failed. + */ +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) +{ + return SysTick_Config(TicksNumb); +} +/** + * @} + */ + +/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions + * @brief Cortex control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the CORTEX + (NVIC, SYSTICK) functionalities. + + +@endverbatim + * @{ + */ + + +/** + * @brief Gets the priority of an interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the + * appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +uint32_t HAL_NVIC_GetPriority(IRQn_Type IRQn) +{ + /* Get priority for Cortex-M system or device specific interrupts */ + return NVIC_GetPriority(IRQn); +} + +/** + * @brief Sets Pending bit of an external interrupt. + * @param IRQn External interrupt number + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the + * appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Set interrupt pending */ + NVIC_SetPendingIRQ(IRQn); +} + +/** + * @brief Gets Pending Interrupt (reads the pending register in the NVIC + * and returns the pending bit for the specified interrupt). + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the + * appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Return 1 if pending else 0 */ + return NVIC_GetPendingIRQ(IRQn); +} + +/** + * @brief Clears the pending bit of an external interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the + * appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Clear pending interrupt */ + NVIC_ClearPendingIRQ(IRQn); +} + +/** + * @brief Configures the SysTick clock source. + * @param CLKSource specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as + * SysTick clock source. + * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource)); + if (CLKSource == SYSTICK_CLKSOURCE_HCLK) + { + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + } + else + { + SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK; + } +} + +/** + * @brief This function handles SYSTICK interrupt request. + * @retval None + */ +void HAL_SYSTICK_IRQHandler(void) +{ + HAL_SYSTICK_Callback(); +} + +/** + * @brief SYSTICK callback. + * @retval None + */ +__weak void HAL_SYSTICK_Callback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SYSTICK_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_CORTEX_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_cortex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_cortex.h new file mode 100644 index 0000000000..aac4eda00a --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_cortex.h @@ -0,0 +1,131 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_cortex.h + * @author MCD Application Team + * @brief Header file of CORTEX HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_CORTEX_H +#define __STM32F0xx_HAL_CORTEX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup CORTEX CORTEX + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants + * @{ + */ + +/** @defgroup CORTEX_SysTick_clock_source CORTEX SysTick clock source + * @{ + */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 (0x00000000U) +#define SYSTICK_CLKSOURCE_HCLK (0x00000004U) + + /** + * @} + */ + + /** + * @} + */ + + /* Exported Macros -----------------------------------------------------------*/ + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup CORTEX_Exported_Functions CORTEX Exported Functions + * @{ + */ + /** @addtogroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization + * functions + * @brief Initialization and Configuration functions + * @{ + */ + /* Initialization and de-initialization functions *******************************/ + void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, + uint32_t SubPriority); + void HAL_NVIC_EnableIRQ(IRQn_Type IRQn); + void HAL_NVIC_DisableIRQ(IRQn_Type IRQn); + void HAL_NVIC_SystemReset(void); + uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb); + /** + * @} + */ + + /** @addtogroup CORTEX_Exported_Functions_Group2 Peripheral Control functions + * @brief Cortex control functions + * @{ + */ + + /* Peripheral Control functions *************************************************/ + uint32_t HAL_NVIC_GetPriority(IRQn_Type IRQn); + uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn); + void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn); + void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn); + void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource); + void HAL_SYSTICK_IRQHandler(void); + void HAL_SYSTICK_Callback(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CORTEX_Private_Macros CORTEX Private Macros + * @{ + */ +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x4) + +#define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) >= 0x00) + +#define IS_SYSTICK_CLK_SOURCE(SOURCE) \ + (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8)) + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_CORTEX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_def.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_def.h new file mode 100644 index 0000000000..2b6be90713 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_def.h @@ -0,0 +1,184 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_def.h + * @author MCD Application Team + * @brief This file contains HAL common defines, enumeration, macros and + * structures definitions. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_DEF +#define __STM32F0xx_HAL_DEF + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include + +#include "firmware/motor/stm32f0xx/legacy/stm32_hal_legacy.h" +#include "firmware/motor/stm32f0xx/stm32f0xx.h" + + /* Exported types ------------------------------------------------------------*/ + + /** + * @brief HAL Status structures definition + */ + typedef enum + { + HAL_OK = 0x00U, + HAL_ERROR = 0x01U, + HAL_BUSY = 0x02U, + HAL_TIMEOUT = 0x03U + } HAL_StatusTypeDef; + + /** + * @brief HAL Lock structures definition + */ + typedef enum + { + HAL_UNLOCKED = 0x00U, + HAL_LOCKED = 0x01U + } HAL_LockTypeDef; + + /* Exported macro ------------------------------------------------------------*/ + +#if !defined(UNUSED) +#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */ +#endif /* UNUSED */ + +#define HAL_MAX_DELAY 0xFFFFFFFFU + +#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT)) +#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U) + +#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \ + do \ + { \ + (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \ + (__DMA_HANDLE__).Parent = (__HANDLE__); \ + } while (0U) + +/** @brief Reset the Handle's State field. + * @param __HANDLE__ specifies the Peripheral Handle. + * @note This macro can be used for the following purpose: + * - When the Handle is declared as local variable; before passing it as + * parameter to HAL_PPP_Init() for the first time, it is mandatory to use this macro to + * set to 0 the Handle's "State" field. Otherwise, "State" field may have any random value + * and the first time the function HAL_PPP_Init() is called, the low level hardware + * initialization will be missed (i.e. HAL_PPP_MspInit() will not be executed). + * - When there is a need to reconfigure the low level hardware: instead of + * calling HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then + * HAL_PPP_Init(). In this later function, when the Handle's "State" field is set to 0, it + * will execute the function HAL_PPP_MspInit() which will reconfigure the low level + * hardware. + * @retval None + */ +#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U) + +#if (USE_RTOS == 1U) +/* Reserved for future use */ +#error " USE_RTOS should be 0 in the current HAL release " +#else +#define __HAL_LOCK(__HANDLE__) \ + do \ + { \ + if ((__HANDLE__)->Lock == HAL_LOCKED) \ + { \ + return HAL_BUSY; \ + } \ + else \ + { \ + (__HANDLE__)->Lock = HAL_LOCKED; \ + } \ + } while (0U) + +#define __HAL_UNLOCK(__HANDLE__) \ + do \ + { \ + (__HANDLE__)->Lock = HAL_UNLOCKED; \ + } while (0U) +#endif /* USE_RTOS */ + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif +#ifndef __packed +#define __packed __attribute__((packed)) +#endif +#elif defined(__GNUC__) && !defined(__CC_ARM) /* GNU Compiler */ +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + + +/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma + * data_alignment=4" must be used instead */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__((aligned(4))) +#endif +#elif defined(__GNUC__) && !defined(__CC_ARM) /* GNU Compiler */ +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__((aligned(4))) +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ +#else +#ifndef __ALIGN_END +#define __ALIGN_END +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#if defined(__CC_ARM) /* ARM Compiler V5*/ +#define __ALIGN_BEGIN __align(4) +#elif defined(__ICCARM__) /* IAR Compiler */ +#define __ALIGN_BEGIN +#endif /* __CC_ARM */ +#endif /* __ALIGN_BEGIN */ +#endif /* __GNUC__ */ + +/** + * @brief __NOINLINE definition + */ +#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) || \ + defined(__GNUC__) +/* ARM V4/V5 and V6 & GNU Compiler + ------------------------------- +*/ +#define __NOINLINE __attribute__((noinline)) + +#elif defined(__ICCARM__) +/* ICCARM Compiler + --------------- +*/ +#define __NOINLINE _Pragma("optimize = no_inline") + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ___STM32F0xx_HAL_DEF */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma.c b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma.c new file mode 100644 index 0000000000..c48b36b3f5 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma.c @@ -0,0 +1,917 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_dma.c + * @author MCD Application Team + * @brief DMA HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Direct Memory Access (DMA) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and errors functions + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable and configure the peripheral to be connected to the DMA Channel + (except for internal SRAM / FLASH memories: no initialization is + necessary). Please refer to Reference manual for connection between peripherals + and DMA requests . + + (#) For a given Channel, program the required configuration through the following + parameters: Transfer Direction, Source and Destination data formats, Circular or Normal + mode, Channel Priority level, Source and Destination Increment mode, using + HAL_DMA_Init() function. + + (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in + case of error detection. + + (#) Use HAL_DMA_Abort() function to abort the current transfer + + -@- In Memory-to-Memory transfer mode, Circular mode is not allowed. + *** Polling mode IO operation *** + ================================= + [..] + (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source + address and destination address and the Length of data to be transferred + (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this + case a fixed Timeout can be configured by User depending from his application. + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority() + (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() + (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of + Source address and destination address and the Length of data to be transferred. + In this case the DMA interrupt is configured + (+) Use HAL_DMA_Channel_IRQHandler() called under DMA_IRQHandler() Interrupt + subroutine + (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user + can add his own function by customization of function pointer XferCpltCallback and + XferErrorCallback (i.e a member of DMA handle structure). + + *** DMA HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DMA HAL driver. + + [..] + (@) You can refer to the DMA HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + +/** @defgroup DMA DMA + * @brief DMA HAL module driver + * @{ + */ + +#ifdef HAL_DMA_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup DMA_Private_Functions DMA Private Functions + * @{ + */ +static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, + uint32_t DstAddress, uint32_t DataLength); +static void DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Functions DMA Exported Functions + * @{ + */ + +/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to initialize the DMA Channel source + and destination addresses, incrementation and data sizes, transfer direction, + circular/normal mode selection, memory-to-memory mode selection and Channel priority +value. + [..] + The HAL_DMA_Init() function follows the DMA configuration procedures as described in + reference manual. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the DMA according to the specified + * parameters in the DMA_InitTypeDef and initialize the associated handle. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) +{ + uint32_t tmp = 0U; + + /* Check the DMA handle allocation */ + if (NULL == hdma) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); + assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc)); + assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc)); + assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment)); + assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment)); + assert_param(IS_DMA_MODE(hdma->Init.Mode)); + assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Get the CR register value */ + tmp = hdma->Instance->CCR; + + /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */ + tmp &= ((uint32_t) ~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | DMA_CCR_MINC | + DMA_CCR_PINC | DMA_CCR_CIRC | DMA_CCR_DIR)); + + /* Prepare the DMA Channel configuration */ + tmp |= hdma->Init.Direction | hdma->Init.PeriphInc | hdma->Init.MemInc | + hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment | + hdma->Init.Mode | hdma->Init.Priority; + + /* Write to DMA Channel CR register */ + hdma->Instance->CCR = tmp; + + /* Initialize DmaBaseAddress and ChannelIndex parameters used + by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */ + DMA_CalcBaseAndBitshift(hdma); + + /* Initialise the error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Initialize the DMA state*/ + hdma->State = HAL_DMA_STATE_READY; + + /* Allocate lock resource and initialize it */ + hdma->Lock = HAL_UNLOCKED; + + return HAL_OK; +} + +/** + * @brief DeInitialize the DMA peripheral + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) +{ + /* Check the DMA handle allocation */ + if (NULL == hdma) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + + /* Disable the selected DMA Channelx */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Reset DMA Channel control register */ + hdma->Instance->CCR = 0U; + + /* Reset DMA Channel Number of Data to Transfer register */ + hdma->Instance->CNDTR = 0U; + + /* Reset DMA Channel peripheral address register */ + hdma->Instance->CPAR = 0U; + + /* Reset DMA Channel memory address register */ + hdma->Instance->CMAR = 0U; + + /* Get DMA Base Address */ + DMA_CalcBaseAndBitshift(hdma); + + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex; + + /* Clean callbacks */ + hdma->XferCpltCallback = NULL; + hdma->XferHalfCpltCallback = NULL; + hdma->XferErrorCallback = NULL; + hdma->XferAbortCallback = NULL; + + /* Reset the error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Reset the DMA state */ + hdma->State = HAL_DMA_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions + * @brief I/O operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the source, destination address and data length and Start DMA transfer + (+) Configure the source, destination address and data length and + Start DMA transfer with interrupt + (+) Abort DMA transfer + (+) Poll for transfer complete + (+) Handle DMA interrupt request + +@endverbatim + * @{ + */ + +/** + * @brief Start the DMA Transfer. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @param SrcAddress The source memory Buffer address + * @param DstAddress The destination memory Buffer address + * @param DataLength The length of data to be transferred from source to destination + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, + uint32_t DstAddress, uint32_t DataLength) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Process locked */ + __HAL_LOCK(hdma); + + if (HAL_DMA_STATE_READY == hdma->State) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Disable the peripheral */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Configure the source, destination address and the data length */ + DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); + + /* Enable the Peripheral */ + hdma->Instance->CCR |= DMA_CCR_EN; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Remain BUSY */ + status = HAL_BUSY; + } + + return status; +} + +/** + * @brief Start the DMA Transfer with interrupt enabled. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @param SrcAddress The source memory Buffer address + * @param DstAddress The destination memory Buffer address + * @param DataLength The length of data to be transferred from source to destination + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, + uint32_t DstAddress, uint32_t DataLength) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Process locked */ + __HAL_LOCK(hdma); + + if (HAL_DMA_STATE_READY == hdma->State) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Disable the peripheral */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Configure the source, destination address and the data length */ + DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); + + /* Enable the transfer complete, & transfer error interrupts */ + /* Half transfer interrupt is optional: enable it only if associated callback is + * available */ + if (NULL != hdma->XferHalfCpltCallback) + { + hdma->Instance->CCR |= (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); + } + else + { + hdma->Instance->CCR |= (DMA_IT_TC | DMA_IT_TE); + hdma->Instance->CCR &= ~DMA_IT_HT; + } + + /* Enable the Peripheral */ + hdma->Instance->CCR |= DMA_CCR_EN; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Remain BUSY */ + status = HAL_BUSY; + } + + return status; +} + +/** + * @brief Abort the DMA Transfer. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) +{ + if (hdma->State != HAL_DMA_STATE_BUSY) + { + /* no transfer ongoing */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + else + { + /* Disable DMA IT */ + hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); + + /* Disable the channel */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = (DMA_FLAG_GL1 << hdma->ChannelIndex); + } + /* Change the DMA state*/ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} + +/** + * @brief Abort the DMA Transfer in Interrupt mode. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (HAL_DMA_STATE_BUSY != hdma->State) + { + /* no transfer ongoing */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + status = HAL_ERROR; + } + else + { + /* Disable DMA IT */ + hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); + + /* Disable the channel */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Call User Abort callback */ + if (hdma->XferAbortCallback != NULL) + { + hdma->XferAbortCallback(hdma); + } + } + return status; +} + +/** + * @brief Polling for transfer complete. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @param CompleteLevel Specifies the DMA level complete. + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, + uint32_t Timeout) +{ + uint32_t temp; + uint32_t tickstart = 0U; + + if (HAL_DMA_STATE_BUSY != hdma->State) + { + /* no transfer ongoing */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + __HAL_UNLOCK(hdma); + return HAL_ERROR; + } + + /* Polling mode not supported in circular mode */ + if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC)) + { + hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; + return HAL_ERROR; + } + + /* Get the level transfer complete flag */ + if (HAL_DMA_FULL_TRANSFER == CompleteLevel) + { + /* Transfer Complete flag */ + temp = DMA_FLAG_TC1 << hdma->ChannelIndex; + } + else + { + /* Half Transfer Complete flag */ + temp = DMA_FLAG_HT1 << hdma->ChannelIndex; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while (RESET == (hdma->DmaBaseAddress->ISR & temp)) + { + if (RESET != (hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << hdma->ChannelIndex))) + { + /* When a DMA transfer error occurs */ + /* A hardware clear of its EN bits is performed */ + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex; + + /* Update error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TE; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + { + /* Update error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + } + } + + if (HAL_DMA_FULL_TRANSFER == CompleteLevel) + { + /* Clear the transfer complete flag */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_TC1 << hdma->ChannelIndex; + + /* The selected Channelx EN bit is cleared (DMA is disabled and + all transfers are complete) */ + hdma->State = HAL_DMA_STATE_READY; + } + else + { + /* Clear the half transfer complete flag */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_HT1 << hdma->ChannelIndex; + } + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} + +/** + * @brief Handle DMA interrupt request. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval None + */ +void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) +{ + uint32_t flag_it = hdma->DmaBaseAddress->ISR; + uint32_t source_it = hdma->Instance->CCR; + + /* Half Transfer Complete Interrupt management ******************************/ + if ((RESET != (flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex))) && + (RESET != (source_it & DMA_IT_HT))) + { + /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ + if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) + { + /* Disable the half transfer interrupt */ + hdma->Instance->CCR &= ~DMA_IT_HT; + } + + /* Clear the half transfer complete flag */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_HT1 << hdma->ChannelIndex; + + /* DMA peripheral state is not updated in Half Transfer */ + /* State is updated only in Transfer Complete case */ + + if (hdma->XferHalfCpltCallback != NULL) + { + /* Half transfer callback */ + hdma->XferHalfCpltCallback(hdma); + } + } + + /* Transfer Complete Interrupt management ***********************************/ + else if ((RESET != (flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex))) && + (RESET != (source_it & DMA_IT_TC))) + { + if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) + { + /* Disable the transfer complete & transfer error interrupts */ + /* if the DMA mode is not CIRCULAR */ + hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_TE); + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + } + + /* Clear the transfer complete flag */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_TC1 << hdma->ChannelIndex; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + if (hdma->XferCpltCallback != NULL) + { + /* Transfer complete callback */ + hdma->XferCpltCallback(hdma); + } + } + + /* Transfer Error Interrupt management ***************************************/ + else if ((RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && + (RESET != (source_it & DMA_IT_TE))) + { + /* When a DMA transfer error occurs */ + /* A hardware clear of its EN bits is performed */ + /* Then, disable all DMA interrupts */ + hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); + + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex; + + /* Update error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TE; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + if (hdma->XferErrorCallback != NULL) + { + /* Transfer error callback */ + hdma->XferErrorCallback(hdma); + } + } +} + +/** + * @brief Register callbacks + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA + * Stream. + * @param CallbackID User Callback identifier + * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. + * @param pCallback pointer to private callback function which has pointer to + * a DMA_HandleTypeDef structure as parameter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, + HAL_DMA_CallbackIDTypeDef CallbackID, + void (*pCallback)(DMA_HandleTypeDef *_hdma)) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hdma); + + if (HAL_DMA_STATE_READY == hdma->State) + { + switch (CallbackID) + { + case HAL_DMA_XFER_CPLT_CB_ID: + hdma->XferCpltCallback = pCallback; + break; + + case HAL_DMA_XFER_HALFCPLT_CB_ID: + hdma->XferHalfCpltCallback = pCallback; + break; + + case HAL_DMA_XFER_ERROR_CB_ID: + hdma->XferErrorCallback = pCallback; + break; + + case HAL_DMA_XFER_ABORT_CB_ID: + hdma->XferAbortCallback = pCallback; + break; + + default: + status = HAL_ERROR; + break; + } + } + else + { + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return status; +} + +/** + * @brief UnRegister callbacks + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA + * Stream. + * @param CallbackID User Callback identifier + * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, + HAL_DMA_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hdma); + + if (HAL_DMA_STATE_READY == hdma->State) + { + switch (CallbackID) + { + case HAL_DMA_XFER_CPLT_CB_ID: + hdma->XferCpltCallback = NULL; + break; + + case HAL_DMA_XFER_HALFCPLT_CB_ID: + hdma->XferHalfCpltCallback = NULL; + break; + + case HAL_DMA_XFER_ERROR_CB_ID: + hdma->XferErrorCallback = NULL; + break; + + case HAL_DMA_XFER_ABORT_CB_ID: + hdma->XferAbortCallback = NULL; + break; + + case HAL_DMA_XFER_ALL_CB_ID: + hdma->XferCpltCallback = NULL; + hdma->XferHalfCpltCallback = NULL; + hdma->XferErrorCallback = NULL; + hdma->XferAbortCallback = NULL; + break; + + default: + status = HAL_ERROR; + break; + } + } + else + { + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return status; +} + +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the DMA state + (+) Get error code + +@endverbatim + * @{ + */ + +/** + * @brief Returns the DMA state. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval HAL state + */ +HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma) +{ + return hdma->State; +} + +/** + * @brief Return the DMA error code + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval DMA Error Code + */ +uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma) +{ + return hdma->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DMA_Private_Functions + * @{ + */ + +/** + * @brief Set the DMA Transfer parameters. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @param SrcAddress The source memory Buffer address + * @param DstAddress The destination memory Buffer address + * @param DataLength The length of data to be transferred from source to destination + * @retval HAL status + */ +static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, + uint32_t DstAddress, uint32_t DataLength) +{ + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = (DMA_FLAG_GL1 << hdma->ChannelIndex); + + /* Configure DMA Channel data length */ + hdma->Instance->CNDTR = DataLength; + + /* Memory to Peripheral */ + if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) + { + /* Configure DMA Channel destination address */ + hdma->Instance->CPAR = DstAddress; + + /* Configure DMA Channel source address */ + hdma->Instance->CMAR = SrcAddress; + } + /* Peripheral to Memory */ + else + { + /* Configure DMA Channel source address */ + hdma->Instance->CPAR = SrcAddress; + + /* Configure DMA Channel destination address */ + hdma->Instance->CMAR = DstAddress; + } +} + +/** + * @brief set the DMA base address and channel index depending on DMA instance + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval None + */ +static void DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma) +{ +#if defined(DMA2) + /* calculation of the channel index */ + if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1)) + { + /* DMA1 */ + hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / + ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) + << 2U; + hdma->DmaBaseAddress = DMA1; + } + else + { + /* DMA2 */ + hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / + ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) + << 2U; + hdma->DmaBaseAddress = DMA2; + } +#else + /* calculation of the channel index */ + /* DMA1 */ + hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / + ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) + << 2U; + hdma->DmaBaseAddress = DMA1; +#endif +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma.h new file mode 100644 index 0000000000..a19a7af0ae --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma.h @@ -0,0 +1,633 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_dma.h + * @author MCD Application Team + * @brief Header file of DMA HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_DMA_H +#define __STM32F0xx_HAL_DMA_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup DMA + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** @defgroup DMA_Exported_Types DMA Exported Types + * @{ + */ + + /** + * @brief DMA Configuration Structure definition + */ + typedef struct + { + uint32_t Direction; /*!< Specifies if the data will be transferred from memory to + peripheral, from memory to memory or from peripheral to + memory. This parameter can be a value of @ref + DMA_Data_transfer_direction */ + + uint32_t PeriphInc; /*!< Specifies whether the Peripheral address register should + be incremented or not. This parameter can be a value of + @ref DMA_Peripheral_incremented_mode */ + + uint32_t MemInc; /*!< Specifies whether the memory address register should be + incremented or not. This parameter can be a value of @ref + DMA_Memory_incremented_mode */ + + uint32_t PeriphDataAlignment; /*!< Specifies the Peripheral data width. + This parameter can be a value of @ref + DMA_Peripheral_data_size */ + + uint32_t MemDataAlignment; /*!< Specifies the Memory data width. + This parameter can be a value of @ref + DMA_Memory_data_size */ + + uint32_t Mode; /*!< Specifies the operation mode of the DMAy Channelx. + This parameter can be a value of @ref DMA_mode + @note The circular buffer mode cannot be used if the + memory-to-memory data transfer is configured on the selected + Channel */ + + uint32_t + Priority; /*!< Specifies the software priority for the DMAy Channelx. + This parameter can be a value of @ref DMA_Priority_level */ + } DMA_InitTypeDef; + + /** + * @brief HAL DMA State structures definition + */ + typedef enum + { + HAL_DMA_STATE_RESET = 0x00U, /*!< DMA not yet initialized or disabled */ + HAL_DMA_STATE_READY = 0x01U, /*!< DMA initialized and ready for use */ + HAL_DMA_STATE_BUSY = 0x02U, /*!< DMA process is ongoing */ + HAL_DMA_STATE_TIMEOUT = 0x03U /*!< DMA timeout state */ + } HAL_DMA_StateTypeDef; + + /** + * @brief HAL DMA Error Code structure definition + */ + typedef enum + { + HAL_DMA_FULL_TRANSFER = 0x00U, /*!< Full transfer */ + HAL_DMA_HALF_TRANSFER = 0x01U /*!< Half Transfer */ + } HAL_DMA_LevelCompleteTypeDef; + + /** + * @brief HAL DMA Callback ID structure definition + */ + typedef enum + { + HAL_DMA_XFER_CPLT_CB_ID = 0x00U, /*!< Full transfer */ + HAL_DMA_XFER_HALFCPLT_CB_ID = 0x01U, /*!< Half transfer */ + HAL_DMA_XFER_ERROR_CB_ID = 0x02U, /*!< Error */ + HAL_DMA_XFER_ABORT_CB_ID = 0x03U, /*!< Abort */ + HAL_DMA_XFER_ALL_CB_ID = 0x04U /*!< All */ + + } HAL_DMA_CallbackIDTypeDef; + + /** + * @brief DMA handle Structure definition + */ + typedef struct __DMA_HandleTypeDef + { + DMA_Channel_TypeDef *Instance; /*!< Register base address */ + + DMA_InitTypeDef Init; /*!< DMA communication parameters */ + + HAL_LockTypeDef Lock; /*!< DMA locking object */ + + __IO HAL_DMA_StateTypeDef State; /*!< DMA transfer state */ + + void *Parent; /*!< Parent object state */ + + void (*XferCpltCallback)( + struct __DMA_HandleTypeDef *hdma); /*!< DMA transfer complete callback */ + + void (*XferHalfCpltCallback)( + struct __DMA_HandleTypeDef *hdma); /*!< DMA Half transfer complete callback */ + + void (*XferErrorCallback)( + struct __DMA_HandleTypeDef *hdma); /*!< DMA transfer error callback */ + + void (*XferAbortCallback)( + struct __DMA_HandleTypeDef *hdma); /*!< DMA transfer abort callback */ + + __IO uint32_t ErrorCode; /*!< DMA Error code */ + + DMA_TypeDef *DmaBaseAddress; /*!< DMA Channel Base Address */ + + uint32_t ChannelIndex; /*!< DMA Channel Index */ + } DMA_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Constants DMA Exported Constants + * @{ + */ + +/** @defgroup DMA_Error_Code DMA Error Code + * @{ + */ +#define HAL_DMA_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_DMA_ERROR_TE (0x00000001U) /*!< Transfer error */ +#define HAL_DMA_ERROR_NO_XFER (0x00000004U) /*!< no ongoin transfer */ +#define HAL_DMA_ERROR_TIMEOUT (0x00000020U) /*!< Timeout error */ +#define HAL_DMA_ERROR_NOT_SUPPORTED (0x00000100U) /*!< Not supported mode */ +/** + * @} + */ + +/** @defgroup DMA_Data_transfer_direction DMA Data transfer direction + * @{ + */ +#define DMA_PERIPH_TO_MEMORY (0x00000000U) /*!< Peripheral to memory direction */ +#define DMA_MEMORY_TO_PERIPH \ + ((uint32_t)DMA_CCR_DIR) /*!< Memory to peripheral direction */ +#define DMA_MEMORY_TO_MEMORY \ + ((uint32_t)(DMA_CCR_MEM2MEM)) /*!< Memory to memory direction */ + +/** + * @} + */ + +/** @defgroup DMA_Peripheral_incremented_mode DMA Peripheral incremented mode + * @{ + */ +#define DMA_PINC_ENABLE \ + ((uint32_t)DMA_CCR_PINC) /*!< Peripheral increment mode Enable \ + */ +#define DMA_PINC_DISABLE (0x00000000U) /*!< Peripheral increment mode Disable */ +/** + * @} + */ + +/** @defgroup DMA_Memory_incremented_mode DMA Memory incremented mode + * @{ + */ +#define DMA_MINC_ENABLE ((uint32_t)DMA_CCR_MINC) /*!< Memory increment mode Enable */ +#define DMA_MINC_DISABLE (0x00000000U) /*!< Memory increment mode Disable */ +/** + * @} + */ + +/** @defgroup DMA_Peripheral_data_size DMA Peripheral data size + * @{ + */ +#define DMA_PDATAALIGN_BYTE (0x00000000U) /*!< Peripheral data alignment : Byte */ +#define DMA_PDATAALIGN_HALFWORD \ + ((uint32_t)DMA_CCR_PSIZE_0) /*!< Peripheral data alignment : HalfWord */ +#define DMA_PDATAALIGN_WORD \ + ((uint32_t)DMA_CCR_PSIZE_1) /*!< Peripheral data alignment : Word */ +/** + * @} + */ + +/** @defgroup DMA_Memory_data_size DMA Memory data size + * @{ + */ +#define DMA_MDATAALIGN_BYTE (0x00000000U) /*!< Memory data alignment : Byte */ +#define DMA_MDATAALIGN_HALFWORD \ + ((uint32_t)DMA_CCR_MSIZE_0) /*!< Memory data alignment : HalfWord */ +#define DMA_MDATAALIGN_WORD \ + ((uint32_t)DMA_CCR_MSIZE_1) /*!< Memory data alignment : Word */ +/** + * @} + */ + +/** @defgroup DMA_mode DMA mode + * @{ + */ +#define DMA_NORMAL (0x00000000U) /*!< Normal Mode */ +#define DMA_CIRCULAR ((uint32_t)DMA_CCR_CIRC) /*!< Circular Mode */ +/** + * @} + */ + +/** @defgroup DMA_Priority_level DMA Priority level + * @{ + */ +#define DMA_PRIORITY_LOW (0x00000000U) /*!< Priority level : Low */ +#define DMA_PRIORITY_MEDIUM ((uint32_t)DMA_CCR_PL_0) /*!< Priority level : Medium */ +#define DMA_PRIORITY_HIGH ((uint32_t)DMA_CCR_PL_1) /*!< Priority level : High */ +#define DMA_PRIORITY_VERY_HIGH ((uint32_t)DMA_CCR_PL) /*!< Priority level : Very_High */ +/** + * @} + */ + + +/** @defgroup DMA_interrupt_enable_definitions DMA interrupt enable definitions + * @{ + */ +#define DMA_IT_TC ((uint32_t)DMA_CCR_TCIE) +#define DMA_IT_HT ((uint32_t)DMA_CCR_HTIE) +#define DMA_IT_TE ((uint32_t)DMA_CCR_TEIE) + /** + * @} + */ + + /** @defgroup DMA_flag_definitions DMA flag definitions + * @{ + */ + +#define DMA_FLAG_GL1 (0x00000001U) /*!< Channel 1 global interrupt flag */ +#define DMA_FLAG_TC1 (0x00000002U) /*!< Channel 1 transfer complete flag */ +#define DMA_FLAG_HT1 (0x00000004U) /*!< Channel 1 half transfer flag */ +#define DMA_FLAG_TE1 (0x00000008U) /*!< Channel 1 transfer error flag */ +#define DMA_FLAG_GL2 (0x00000010U) /*!< Channel 2 global interrupt flag */ +#define DMA_FLAG_TC2 (0x00000020U) /*!< Channel 2 transfer complete flag */ +#define DMA_FLAG_HT2 (0x00000040U) /*!< Channel 2 half transfer flag */ +#define DMA_FLAG_TE2 (0x00000080U) /*!< Channel 2 transfer error flag */ +#define DMA_FLAG_GL3 (0x00000100U) /*!< Channel 3 global interrupt flag */ +#define DMA_FLAG_TC3 (0x00000200U) /*!< Channel 3 transfer complete flag */ +#define DMA_FLAG_HT3 (0x00000400U) /*!< Channel 3 half transfer flag */ +#define DMA_FLAG_TE3 (0x00000800U) /*!< Channel 3 transfer error flag */ +#define DMA_FLAG_GL4 (0x00001000U) /*!< Channel 4 global interrupt flag */ +#define DMA_FLAG_TC4 (0x00002000U) /*!< Channel 4 transfer complete flag */ +#define DMA_FLAG_HT4 (0x00004000U) /*!< Channel 4 half transfer flag */ +#define DMA_FLAG_TE4 (0x00008000U) /*!< Channel 4 transfer error flag */ +#define DMA_FLAG_GL5 (0x00010000U) /*!< Channel 5 global interrupt flag */ +#define DMA_FLAG_TC5 (0x00020000U) /*!< Channel 5 transfer complete flag */ +#define DMA_FLAG_HT5 (0x00040000U) /*!< Channel 5 half transfer flag */ +#define DMA_FLAG_TE5 (0x00080000U) /*!< Channel 5 transfer error flag */ +#define DMA_FLAG_GL6 (0x00100000U) /*!< Channel 6 global interrupt flag */ +#define DMA_FLAG_TC6 (0x00200000U) /*!< Channel 6 transfer complete flag */ +#define DMA_FLAG_HT6 (0x00400000U) /*!< Channel 6 half transfer flag */ +#define DMA_FLAG_TE6 (0x00800000U) /*!< Channel 6 transfer error flag */ +#define DMA_FLAG_GL7 (0x01000000U) /*!< Channel 7 global interrupt flag */ +#define DMA_FLAG_TC7 (0x02000000U) /*!< Channel 7 transfer complete flag */ +#define DMA_FLAG_HT7 (0x04000000U) /*!< Channel 7 half transfer flag */ +#define DMA_FLAG_TE7 (0x08000000U) /*!< Channel 7 transfer error flag */ + + /** + * @} + */ + +#if defined(SYSCFG_CFGR1_DMA_RMP) +/** @defgroup HAL_DMA_remapping HAL DMA remapping + * Elements values convention: 0xYYYYYYYY + * - YYYYYYYY : Position in the SYSCFG register CFGR1 + * @{ + */ +#define DMA_REMAP_ADC_DMA_CH2 \ + ((uint32_t) \ + SYSCFG_CFGR1_ADC_DMA_RMP) /*!< ADC DMA remap \ + 0: No remap (ADC DMA requests mapped on DMA channel 1 \ + 1: Remap (ADC DMA requests mapped on DMA channel 2 */ +#define DMA_REMAP_USART1_TX_DMA_CH4 \ + ((uint32_t)SYSCFG_CFGR1_USART1TX_DMA_RMP) /*!< USART1 TX DMA remap \ + 0: No remap (USART1_TX DMA request mapped on DMA \ + channel 2 1: Remap (USART1_TX DMA request mapped \ + on DMA channel 4 */ +#define DMA_REMAP_USART1_RX_DMA_CH5 \ + ((uint32_t)SYSCFG_CFGR1_USART1RX_DMA_RMP) /*!< USART1 RX DMA remap \ + 0: No remap (USART1_RX DMA request mapped on DMA \ + channel 3 1: Remap (USART1_RX DMA request mapped \ + on DMA channel 5 */ +#define DMA_REMAP_TIM16_DMA_CH4 \ + ((uint32_t)SYSCFG_CFGR1_TIM16_DMA_RMP) /*!< TIM16 DMA request remap \ + 0: No remap (TIM16_CH1 and TIM16_UP DMA requests \ + mapped on DMA channel 3) 1: Remap (TIM16_CH1 and \ + TIM16_UP DMA requests mapped on DMA channel 4) */ +#define DMA_REMAP_TIM17_DMA_CH2 \ + ((uint32_t)SYSCFG_CFGR1_TIM17_DMA_RMP) /*!< TIM17 DMA request remap \ + 0: No remap (TIM17_CH1 and TIM17_UP DMA requests \ + mapped on DMA channel 1 1: Remap (TIM17_CH1 and \ + TIM17_UP DMA requests mapped on DMA channel 2) */ +#if defined(STM32F070xB) +#define DMA_REMAP_USART3_DMA_CH32 \ + ((uint32_t) \ + SYSCFG_CFGR1_USART3_DMA_RMP) /*!< USART3 DMA request remapping bit. Available \ + on STM32F070xB devices only. 0: Disabled, need to remap \ + before use 1: Remap (USART3_RX and USART3_TX DMA \ + requests mapped on DMA channel 3 and 2 respectively) */ + +#endif + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) +#define DMA_REMAP_TIM16_DMA_CH6 \ + ((uint32_t) \ + SYSCFG_CFGR1_TIM16_DMA_RMP2) /*!< TIM16 alternate DMA request remapping bit. \ + Available on STM32F07x devices only 0: No alternate \ + remap (TIM16 DMA requestsmapped according to \ + TIM16_DMA_RMP bit) 1: Alternate remap (TIM16_CH1 and \ + TIM16_UP DMA requests mapped on DMA channel 6) */ +#define DMA_REMAP_TIM17_DMA_CH7 \ + ((uint32_t) \ + SYSCFG_CFGR1_TIM17_DMA_RMP2) /*!< TIM17 alternate DMA request remapping bit. \ + Available on STM32F07x devices only 0: No alternate \ + remap (TIM17 DMA requestsmapped according to \ + TIM17_DMA_RMP bit) 1: Alternate remap (TIM17_CH1 and \ + TIM17_UP DMA requests mapped on DMA channel 7) */ +#define DMA_REMAP_SPI2_DMA_CH67 \ + ((uint32_t) \ + SYSCFG_CFGR1_SPI2_DMA_RMP) /*!< SPI2 DMA request remapping bit. Available on \ + STM32F07x devices only. 0: No remap (SPI2_RX and \ + SPI2_TX DMA requests mapped on DMA channel 4 and 5 \ + respectively) 1: Remap (SPI2_RX and SPI2_TX DMA \ + requests mapped on DMA channel 6 and 7 respectively) */ +#define DMA_REMAP_USART2_DMA_CH67 \ + ((uint32_t) \ + SYSCFG_CFGR1_USART2_DMA_RMP) /*!< USART2 DMA request remapping bit. Available \ + on STM32F07x devices only. 0: No remap (USART2_RX and \ + USART2_TX DMA requests mapped on DMA channel 5 and 4 \ + respectively) 1: 1: Remap (USART2_RX and USART2_TX DMA \ + requests mapped on DMA channel 6 and 7 respectively) */ +#define DMA_REMAP_USART3_DMA_CH32 \ + ((uint32_t) \ + SYSCFG_CFGR1_USART3_DMA_RMP) /*!< USART3 DMA request remapping bit. Available \ + on STM32F07x devices only. 0: No remap (USART3_RX and \ + USART3_TX DMA requests mapped on DMA channel 6 and 7 \ + respectively) 1: Remap (USART3_RX and USART3_TX DMA \ + requests mapped on DMA channel 3 and 2 respectively) */ +#define DMA_REMAP_I2C1_DMA_CH76 \ + ((uint32_t) \ + SYSCFG_CFGR1_I2C1_DMA_RMP) /*!< I2C1 DMA request remapping bit. Available on \ + STM32F07x devices only. 0: No remap (I2C1_RX and \ + I2C1_TX DMA requests mapped on DMA channel 3 and 2 \ + respectively) 1: Remap (I2C1_RX and I2C1_TX DMA \ + requests mapped on DMA channel 7 and 6 respectively) */ +#define DMA_REMAP_TIM1_DMA_CH6 \ + ((uint32_t) \ + SYSCFG_CFGR1_TIM1_DMA_RMP) /*!< TIM1 DMA request remapping bit. Available on \ + STM32F07x devices only. 0: No remap (TIM1_CH1, TIM1_CH2 \ + and TIM1_CH3 DMA requests mapped on DMA channel 2, 3 \ + and 4 respectively) 1: Remap (TIM1_CH1, TIM1_CH2 and \ + TIM1_CH3 DMA requests mapped on DMA channel 6 */ +#define DMA_REMAP_TIM2_DMA_CH7 \ + ((uint32_t)SYSCFG_CFGR1_TIM2_DMA_RMP) /*!< TIM2 DMA request remapping bit. Available \ + on STM32F07x devices only. 0: No remap (TIM2_CH2 \ + and TIM2_CH4 DMA requests mapped on DMA channel 3 \ + and 4 respectively) 1: Remap (TIM2_CH2 and \ + TIM2_CH4 DMA requests mapped on DMA channel 7 */ +#define DMA_REMAP_TIM3_DMA_CH6 \ + ((uint32_t)SYSCFG_CFGR1_TIM3_DMA_RMP) /*!< TIM3 DMA request remapping bit. Available \ + on STM32F07x devices only. 0: No remap (TIM3_CH1 \ + and TIM3_TRIG DMA requests mapped on DMA channel \ + 4) 1: Remap (TIM3_CH1 and TIM3_TRIG DMA requests \ + mapped on DMA channel 6) */ +#endif + + /** + * @} + */ + +#endif /* SYSCFG_CFGR1_DMA_RMP */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DMA_Exported_Macros DMA Exported Macros + * @{ + */ + +/** @brief Reset DMA handle state + * @param __HANDLE__ DMA handle. + * @retval None + */ +#define __HAL_DMA_RESET_HANDLE_STATE(__HANDLE__) \ + ((__HANDLE__)->State = HAL_DMA_STATE_RESET) + +/** + * @brief Enable the specified DMA Channel. + * @param __HANDLE__ DMA handle + * @retval None + */ +#define __HAL_DMA_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CCR |= DMA_CCR_EN) + +/** + * @brief Disable the specified DMA Channel. + * @param __HANDLE__ DMA handle + * @retval None + */ +#define __HAL_DMA_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CCR &= ~DMA_CCR_EN) + + +/* Interrupt & Flag management */ + +/** + * @brief Enables the specified DMA Channel interrupts. + * @param __HANDLE__ DMA handle + * @param __INTERRUPT__ specifies the DMA interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer complete interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @retval None + */ +#define __HAL_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->CCR |= (__INTERRUPT__)) + +/** + * @brief Disables the specified DMA Channel interrupts. + * @param __HANDLE__ DMA handle + * @param __INTERRUPT__ specifies the DMA interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer complete interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @retval None + */ +#define __HAL_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->CCR &= ~(__INTERRUPT__)) + +/** + * @brief Checks whether the specified DMA Channel interrupt is enabled or disabled. + * @param __HANDLE__ DMA handle + * @param __INTERRUPT__ specifies the DMA interrupt source to check. + * This parameter can be one of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer complete interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @retval The state of DMA_IT (SET or RESET). + */ +#define __HAL_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CCR & (__INTERRUPT__))) + +/** + * @brief Returns the number of remaining data units in the current DMAy Channelx + * transfer. + * @param __HANDLE__ DMA handle + * + * @retval The number of remaining data units in the current DMA Channel transfer. + */ +#define __HAL_DMA_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNDTR) + +#if defined(SYSCFG_CFGR1_DMA_RMP) +/** @brief DMA remapping enable/disable macros + * @param __DMA_REMAP__ This parameter can be a value of @ref HAL_DMA_remapping + */ +#define __HAL_DMA_REMAP_CHANNEL_ENABLE(__DMA_REMAP__) \ + do \ + { \ + assert_param(IS_DMA_REMAP((__DMA_REMAP__))); \ + SYSCFG->CFGR1 |= (__DMA_REMAP__); \ + } while (0) +#define __HAL_DMA_REMAP_CHANNEL_DISABLE(__DMA_REMAP__) \ + do \ + { \ + assert_param(IS_DMA_REMAP((__DMA_REMAP__))); \ + SYSCFG->CFGR1 &= ~(__DMA_REMAP__); \ + } while (0) +#endif /* SYSCFG_CFGR1_DMA_RMP */ + +/** + * @} + */ + +/* Include DMA HAL Extension module */ +#include "stm32f0xx_hal_dma_ex.h" + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup DMA_Exported_Functions + * @{ + */ + + /** @addtogroup DMA_Exported_Functions_Group1 + * @{ + */ + /* Initialization and de-initialization functions *****************************/ + HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma); + HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma); + /** + * @} + */ + + /** @addtogroup DMA_Exported_Functions_Group2 + * @{ + */ + /* Input and Output operation functions + * *****************************************************/ + HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, + uint32_t DstAddress, uint32_t DataLength); + HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, + uint32_t DstAddress, uint32_t DataLength); + HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma); + HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma); + HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, + uint32_t CompleteLevel, uint32_t Timeout); + void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma); + HAL_StatusTypeDef HAL_DMA_RegisterCallback( + DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, + void (*pCallback)(DMA_HandleTypeDef *_hdma)); + HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, + HAL_DMA_CallbackIDTypeDef CallbackID); + + /** + * @} + */ + + /** @addtogroup DMA_Exported_Functions_Group3 + * @{ + */ + /* Peripheral State and Error functions ***************************************/ + HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma); + uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DMA_Private_Macros + * @{ + */ +#define IS_DMA_DIRECTION(DIRECTION) \ + (((DIRECTION) == DMA_PERIPH_TO_MEMORY) || ((DIRECTION) == DMA_MEMORY_TO_PERIPH) || \ + ((DIRECTION) == DMA_MEMORY_TO_MEMORY)) +#define IS_DMA_PERIPHERAL_INC_STATE(STATE) \ + (((STATE) == DMA_PINC_ENABLE) || ((STATE) == DMA_PINC_DISABLE)) + +#define IS_DMA_MEMORY_INC_STATE(STATE) \ + (((STATE) == DMA_MINC_ENABLE) || ((STATE) == DMA_MINC_DISABLE)) + +#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) \ + (((SIZE) == DMA_PDATAALIGN_BYTE) || ((SIZE) == DMA_PDATAALIGN_HALFWORD) || \ + ((SIZE) == DMA_PDATAALIGN_WORD)) + +#define IS_DMA_MEMORY_DATA_SIZE(SIZE) \ + (((SIZE) == DMA_MDATAALIGN_BYTE) || ((SIZE) == DMA_MDATAALIGN_HALFWORD) || \ + ((SIZE) == DMA_MDATAALIGN_WORD)) + +#define IS_DMA_MODE(MODE) (((MODE) == DMA_NORMAL) || ((MODE) == DMA_CIRCULAR)) +#define IS_DMA_PRIORITY(PRIORITY) \ + (((PRIORITY) == DMA_PRIORITY_LOW) || ((PRIORITY) == DMA_PRIORITY_MEDIUM) || \ + ((PRIORITY) == DMA_PRIORITY_HIGH) || ((PRIORITY) == DMA_PRIORITY_VERY_HIGH)) +#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1U) && ((SIZE) < 0x10000U)) + +#if defined(SYSCFG_CFGR1_DMA_RMP) + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) +#define IS_DMA_REMAP(RMP) \ + (((RMP) == DMA_REMAP_ADC_DMA_CH2) || ((RMP) == DMA_REMAP_USART1_TX_DMA_CH4) || \ + ((RMP) == DMA_REMAP_USART1_RX_DMA_CH5) || ((RMP) == DMA_REMAP_TIM16_DMA_CH4) || \ + ((RMP) == DMA_REMAP_TIM17_DMA_CH2) || ((RMP) == DMA_REMAP_TIM16_DMA_CH6) || \ + ((RMP) == DMA_REMAP_TIM17_DMA_CH7) || ((RMP) == DMA_REMAP_SPI2_DMA_CH67) || \ + ((RMP) == DMA_REMAP_USART2_DMA_CH67) || ((RMP) == DMA_REMAP_USART3_DMA_CH32) || \ + ((RMP) == DMA_REMAP_I2C1_DMA_CH76) || ((RMP) == DMA_REMAP_TIM1_DMA_CH6) || \ + ((RMP) == DMA_REMAP_TIM2_DMA_CH7) || ((RMP) == DMA_REMAP_TIM3_DMA_CH6)) +#elif defined(STM32F070xB) +#define IS_DMA_REMAP(RMP) \ + (((RMP) == DMA_REMAP_USART3_DMA_CH32) || ((RMP) == DMA_REMAP_ADC_DMA_CH2) || \ + ((RMP) == DMA_REMAP_USART1_TX_DMA_CH4) || ((RMP) == DMA_REMAP_USART1_RX_DMA_CH5) || \ + ((RMP) == DMA_REMAP_TIM16_DMA_CH4) || ((RMP) == DMA_REMAP_TIM17_DMA_CH2)) +#else +#define IS_DMA_REMAP(RMP) \ + (((RMP) == DMA_REMAP_ADC_DMA_CH2) || ((RMP) == DMA_REMAP_USART1_TX_DMA_CH4) || \ + ((RMP) == DMA_REMAP_USART1_RX_DMA_CH5) || ((RMP) == DMA_REMAP_TIM16_DMA_CH4) || \ + ((RMP) == DMA_REMAP_TIM17_DMA_CH2)) +#endif + +#endif /* SYSCFG_CFGR1_DMA_RMP */ + + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_DMA_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma_ex.h new file mode 100644 index 0000000000..3f1d5b209a --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_dma_ex.h @@ -0,0 +1,1042 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_dma_ex.h + * @author MCD Application Team + * @brief Header file of DMA HAL Extension module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_DMA_EX_H +#define __STM32F0xx_HAL_DMA_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup DMAEx DMAEx + * @brief DMA HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) +/** @defgroup DMAEx_Exported_Constants DMAEx Exported Constants + * @{ + */ +#define DMA1_CHANNEL1_RMP \ + 0x00000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA1_CHANNEL2_RMP \ + 0x10000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA1_CHANNEL3_RMP \ + 0x20000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA1_CHANNEL4_RMP \ + 0x30000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA1_CHANNEL5_RMP \ + 0x40000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#if !defined(STM32F030xC) +#define DMA1_CHANNEL6_RMP \ + 0x50000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA1_CHANNEL7_RMP \ + 0x60000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA2_CHANNEL1_RMP \ + 0x00000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA2_CHANNEL2_RMP \ + 0x10000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA2_CHANNEL3_RMP \ + 0x20000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA2_CHANNEL4_RMP \ + 0x30000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#define DMA2_CHANNEL5_RMP \ + 0x40000000 /*!< Internal define for remapping on STM32F09x/30xC */ +#endif /* !defined(STM32F030xC) */ + +/****************** DMA1 remap bit field definition********************/ +/* DMA1 - Channel 1 */ +#define HAL_DMA1_CH1_DEFAULT \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH1_ADC \ + (uint32_t)(DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_ADC) /*!< Remap ADC on DMA1 Channel \ + 1*/ +#define HAL_DMA1_CH1_TIM17_CH1 \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_TIM17_CH1) /*!< Remap TIM17 channel 1 on DMA1 channel 1 */ +#define HAL_DMA1_CH1_TIM17_UP \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_TIM17_UP) /*!< Remap TIM17 up on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART1_RX \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_USART1_RX) /*!< Remap USART1 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART2_RX \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_USART2_RX) /*!< Remap USART2 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART3_RX \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_USART3_RX) /*!< Remap USART3 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART4_RX \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_USART4_RX) /*!< Remap USART4 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART5_RX \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_USART5_RX) /*!< Remap USART5 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART6_RX \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_USART6_RX) /*!< Remap USART6 Rx on DMA1 channel 1 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH1_USART7_RX \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_USART7_RX) /*!< Remap USART7 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART8_RX \ + (uint32_t)(DMA1_CHANNEL1_RMP | \ + DMA1_CSELR_CH1_USART8_RX) /*!< Remap USART8 Rx on DMA1 channel 1 */ +#endif /* !defined(STM32F030xC) */ + +/* DMA1 - Channel 2 */ +#define HAL_DMA1_CH2_DEFAULT \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH2_ADC \ + (uint32_t)(DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_ADC) /*!< Remap ADC on DMA1 channel 2 \ + */ +#define HAL_DMA1_CH2_I2C1_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_I2C1_TX) /*!< Remap I2C1 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_SPI1_RX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_SPI1_RX) /*!< Remap SPI1 Rx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_TIM1_CH1 \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_TIM1_CH1) /*!< Remap TIM1 channel 1 on DMA1 channel 2 */ +#define HAL_DMA1_CH2_TIM17_CH1 \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_TIM17_CH1) /*!< Remap TIM17 channel 1 on DMA1 channel 2 */ +#define HAL_DMA1_CH2_TIM17_UP \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_TIM17_UP) /*!< Remap TIM17 up on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART1_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_USART1_TX) /*!< Remap USART1 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART2_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_USART2_TX) /*!< Remap USART2 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART3_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_USART3_TX) /*!< Remap USART3 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART4_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_USART4_TX) /*!< Remap USART4 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART5_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_USART5_TX) /*!< Remap USART5 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART6_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_USART6_TX) /*!< Remap USART6 Tx on DMA1 channel 2 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH2_USART7_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_USART7_TX) /*!< Remap USART7 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART8_TX \ + (uint32_t)(DMA1_CHANNEL2_RMP | \ + DMA1_CSELR_CH2_USART8_TX) /*!< Remap USART8 Tx on DMA1 channel 2 */ +#endif /* !defined(STM32F030xC) */ + +/* DMA1 - Channel 3 */ +#define HAL_DMA1_CH3_DEFAULT \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH3_TIM6_UP \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_TIM6_UP) /*!< Remap TIM6 up on DMA1 channel 3 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH3_DAC_CH1 \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_DAC_CH1) /*!< Remap DAC Channel 1on DMA1 channel 3 */ +#endif /* !defined(STM32F030xC) */ +#define HAL_DMA1_CH3_I2C1_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_I2C1_RX) /*!< Remap I2C1 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_SPI1_TX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_SPI1_TX) /*!< Remap SPI1 Tx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_TIM1_CH2 \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_TIM1_CH2) /*!< Remap TIM1 channel 2 on DMA1 channel 3 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH3_TIM2_CH2 \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_TIM2_CH2) /*!< Remap TIM2 channel 2 on DMA1 channel 3 */ +#endif /* !defined(STM32F030xC) */ +#define HAL_DMA1_CH3_TIM16_CH1 \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_TIM16_CH1) /*!< Remap TIM16 channel 1 on DMA1 channel 3 */ +#define HAL_DMA1_CH3_TIM16_UP \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_TIM16_UP) /*!< Remap TIM16 up on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART1_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_USART1_RX) /*!< Remap USART1 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART2_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_USART2_RX) /*!< Remap USART2 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART3_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_USART3_RX) /*!< Remap USART3 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART4_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_USART4_RX) /*!< Remap USART4 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART5_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_USART5_RX) /*!< Remap USART5 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART6_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_USART6_RX) /*!< Remap USART6 Rx on DMA1 channel 3 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH3_USART7_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_USART7_RX) /*!< Remap USART7 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART8_RX \ + (uint32_t)(DMA1_CHANNEL3_RMP | \ + DMA1_CSELR_CH3_USART8_RX) /*!< Remap USART8 Rx on DMA1 channel 3 */ +#endif /* !defined(STM32F030xC) */ + +/* DMA1 - Channel 4 */ +#define HAL_DMA1_CH4_DEFAULT \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH4_TIM7_UP \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_TIM7_UP) /*!< Remap TIM7 up on DMA1 channel 4 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH4_DAC_CH2 \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_DAC_CH2) /*!< Remap DAC Channel 2 on DMA1 channel 4 */ +#endif /* !defined(STM32F030xC) */ +#define HAL_DMA1_CH4_I2C2_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_I2C2_TX) /*!< Remap I2C2 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_SPI2_RX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_SPI2_RX) /*!< Remap SPI2 Rx on DMA1 channel 4 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH4_TIM2_CH4 \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_TIM2_CH4) /*!< Remap TIM2 channel 4 on DMA1 channel 4 */ +#endif /* !defined(STM32F030xC) */ +#define HAL_DMA1_CH4_TIM3_CH1 \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_TIM3_CH1) /*!< Remap TIM3 channel 1 on DMA1 channel 4 */ +#define HAL_DMA1_CH4_TIM3_TRIG \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_TIM3_TRIG) /*!< Remap TIM3 Trig on DMA1 channel 4 */ +#define HAL_DMA1_CH4_TIM16_CH1 \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_TIM16_CH1) /*!< Remap TIM16 channel 1 on DMA1 channel 4 */ +#define HAL_DMA1_CH4_TIM16_UP \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_TIM16_UP) /*!< Remap TIM16 up on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART1_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_USART1_TX) /*!< Remap USART1 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART2_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_USART2_TX) /*!< Remap USART2 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART3_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_USART3_TX) /*!< Remap USART3 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART4_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_USART4_TX) /*!< Remap USART4 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART5_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_USART5_TX) /*!< Remap USART5 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART6_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_USART6_TX) /*!< Remap USART6 Tx on DMA1 channel 4 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH4_USART7_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_USART7_TX) /*!< Remap USART7 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART8_TX \ + (uint32_t)(DMA1_CHANNEL4_RMP | \ + DMA1_CSELR_CH4_USART8_TX) /*!< Remap USART8 Tx on DMA1 channel 4 */ +#endif /* !defined(STM32F030xC) */ + +/* DMA1 - Channel 5 */ +#define HAL_DMA1_CH5_DEFAULT \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH5_I2C2_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_I2C2_RX) /*!< Remap I2C2 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_SPI2_TX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_SPI2_TX) /*!< Remap SPI1 Tx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_TIM1_CH3 \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_TIM1_CH3) /*!< Remap TIM1 channel 3 on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART1_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_USART1_RX) /*!< Remap USART1 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART2_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_USART2_RX) /*!< Remap USART2 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART3_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_USART3_RX) /*!< Remap USART3 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART4_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_USART4_RX) /*!< Remap USART4 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART5_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_USART5_RX) /*!< Remap USART5 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART6_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_USART6_RX) /*!< Remap USART6 Rx on DMA1 channel 5 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH5_USART7_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_USART7_RX) /*!< Remap USART7 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART8_RX \ + (uint32_t)(DMA1_CHANNEL5_RMP | \ + DMA1_CSELR_CH5_USART8_RX) /*!< Remap USART8 Rx on DMA1 channel 5 */ +#endif /* !defined(STM32F030xC) */ + +#if !defined(STM32F030xC) +/* DMA1 - Channel 6 */ +#define HAL_DMA1_CH6_DEFAULT \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH6_I2C1_TX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_I2C1_TX) /*!< Remap I2C1 Tx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_SPI2_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_SPI2_RX) /*!< Remap SPI2 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM1_CH1 \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_TIM1_CH1) /*!< Remap TIM1 channel 1 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM1_CH2 \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_TIM1_CH2) /*!< Remap TIM1 channel 2 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM1_CH3 \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_TIM1_CH3) /*!< Remap TIM1 channel 3 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM3_CH1 \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_TIM3_CH1) /*!< Remap TIM3 channel 1 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM3_TRIG \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_TIM3_TRIG) /*!< Remap TIM3 Trig on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM16_CH1 \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_TIM16_CH1) /*!< Remap TIM16 channel 1 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM16_UP \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_TIM16_UP) /*!< Remap TIM16 up on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART1_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_USART1_RX) /*!< Remap USART1 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART2_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_USART2_RX) /*!< Remap USART2 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART3_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_USART3_RX) /*!< Remap USART3 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART4_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_USART4_RX) /*!< Remap USART4 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART5_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_USART5_RX) /*!< Remap USART5 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART6_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_USART6_RX) /*!< Remap USART6 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART7_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_USART7_RX) /*!< Remap USART7 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART8_RX \ + (uint32_t)(DMA1_CHANNEL6_RMP | \ + DMA1_CSELR_CH6_USART8_RX) /*!< Remap USART8 Rx on DMA1 channel 6 */ +/* DMA1 - Channel 7 */ +#define HAL_DMA1_CH7_DEFAULT \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH7_I2C1_RX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_I2C1_RX) /*!< Remap I2C1 Rx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_SPI2_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_SPI2_TX) /*!< Remap SPI2 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_TIM2_CH2 \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_TIM2_CH2) /*!< Remap TIM2 channel 2 on DMA1 channel 7 */ +#define HAL_DMA1_CH7_TIM2_CH4 \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_TIM2_CH4) /*!< Remap TIM2 channel 4 on DMA1 channel 7 */ +#define HAL_DMA1_CH7_TIM17_CH1 \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_TIM17_CH1) /*!< Remap TIM17 channel 1 on DMA1 channel 7 */ +#define HAL_DMA1_CH7_TIM17_UP \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_TIM17_UP) /*!< Remap TIM17 up on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART1_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_USART1_TX) /*!< Remap USART1 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART2_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_USART2_TX) /*!< Remap USART2 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART3_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_USART3_TX) /*!< Remap USART3 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART4_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_USART4_TX) /*!< Remap USART4 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART5_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_USART5_TX) /*!< Remap USART5 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART6_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_USART6_TX) /*!< Remap USART6 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART7_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_USART7_TX) /*!< Remap USART7 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART8_TX \ + (uint32_t)(DMA1_CHANNEL7_RMP | \ + DMA1_CSELR_CH7_USART8_TX) /*!< Remap USART8 Tx on DMA1 channel 7 */ + +/****************** DMA2 remap bit field definition********************/ +/* DMA2 - Channel 1 */ +#define HAL_DMA2_CH1_DEFAULT \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH1_I2C2_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_I2C2_TX) /*!< Remap I2C2 TX on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART1_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_USART1_TX) /*!< Remap USART1 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART2_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_USART2_TX) /*!< Remap USART2 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART3_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_USART3_TX) /*!< Remap USART3 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART4_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_USART4_TX) /*!< Remap USART4 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART5_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_USART5_TX) /*!< Remap USART5 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART6_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_USART6_TX) /*!< Remap USART6 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART7_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_USART7_TX) /*!< Remap USART7 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART8_TX \ + (uint32_t)(DMA2_CHANNEL1_RMP | \ + DMA2_CSELR_CH1_USART8_TX) /*!< Remap USART8 Tx on DMA2 channel 1 */ +/* DMA2 - Channel 2 */ +#define HAL_DMA2_CH2_DEFAULT \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH2_I2C2_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_I2C2_RX) /*!< Remap I2C2 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART1_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_USART1_RX) /*!< Remap USART1 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART2_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_USART2_RX) /*!< Remap USART2 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART3_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_USART3_RX) /*!< Remap USART3 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART4_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_USART4_RX) /*!< Remap USART4 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART5_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_USART5_RX) /*!< Remap USART5 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART6_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_USART6_RX) /*!< Remap USART6 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART7_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_USART7_RX) /*!< Remap USART7 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART8_RX \ + (uint32_t)(DMA2_CHANNEL2_RMP | \ + DMA2_CSELR_CH2_USART8_RX) /*!< Remap USART8 Rx on DMA2 channel 2 */ +/* DMA2 - Channel 3 */ +#define HAL_DMA2_CH3_DEFAULT \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH3_TIM6_UP \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_TIM6_UP) /*!< Remap TIM6 up on DMA2 channel 3 */ +#define HAL_DMA2_CH3_DAC_CH1 \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_DAC_CH1) /*!< Remap DAC channel 1 on DMA2 channel 3 */ +#define HAL_DMA2_CH3_SPI1_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_SPI1_RX) /*!< Remap SPI1 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART1_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_USART1_RX) /*!< Remap USART1 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART2_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_USART2_RX) /*!< Remap USART2 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART3_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_USART3_RX) /*!< Remap USART3 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART4_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_USART4_RX) /*!< Remap USART4 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART5_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_USART5_RX) /*!< Remap USART5 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART6_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_USART6_RX) /*!< Remap USART6 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART7_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_USART7_RX) /*!< Remap USART7 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART8_RX \ + (uint32_t)(DMA2_CHANNEL3_RMP | \ + DMA2_CSELR_CH3_USART8_RX) /*!< Remap USART8 Rx on DMA2 channel 3 */ +/* DMA2 - Channel 4 */ +#define HAL_DMA2_CH4_DEFAULT \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH4_TIM7_UP \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_TIM7_UP) /*!< Remap TIM7 up on DMA2 channel 4 */ +#define HAL_DMA2_CH4_DAC_CH2 \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_DAC_CH2) /*!< Remap DAC channel 2 on DMA2 channel 4 */ +#define HAL_DMA2_CH4_SPI1_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_SPI1_TX) /*!< Remap SPI1 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART1_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_USART1_TX) /*!< Remap USART1 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART2_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_USART2_TX) /*!< Remap USART2 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART3_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_USART3_TX) /*!< Remap USART3 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART4_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_USART4_TX) /*!< Remap USART4 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART5_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_USART5_TX) /*!< Remap USART5 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART6_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_USART6_TX) /*!< Remap USART6 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART7_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_USART7_TX) /*!< Remap USART7 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART8_TX \ + (uint32_t)(DMA2_CHANNEL4_RMP | \ + DMA2_CSELR_CH4_USART8_TX) /*!< Remap USART8 Tx on DMA2 channel 4 */ +/* DMA2 - Channel 5 */ +#define HAL_DMA2_CH5_DEFAULT \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH5_ADC \ + (uint32_t)(DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_ADC) /*!< Remap ADC on DMA2 channel 5 \ + */ +#define HAL_DMA2_CH5_USART1_TX \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_CH5_USART1_TX) /*!< Remap USART1 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART2_TX \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_CH5_USART2_TX) /*!< Remap USART2 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART3_TX \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_CH5_USART3_TX) /*!< Remap USART3 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART4_TX \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_CH5_USART4_TX) /*!< Remap USART4 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART5_TX \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_CH5_USART5_TX) /*!< Remap USART5 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART6_TX \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_CH5_USART6_TX) /*!< Remap USART6 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART7_TX \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_CH5_USART7_TX) /*!< Remap USART7 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART8_TX \ + (uint32_t)(DMA2_CHANNEL5_RMP | \ + DMA2_CSELR_CH5_USART8_TX) /*!< Remap USART8 Tx on DMA2 channel 5 */ +#endif /* !defined(STM32F030xC) */ + +#if defined(STM32F091xC) || defined(STM32F098xx) +#define IS_HAL_DMA1_REMAP(REQUEST) \ + (((REQUEST) == HAL_DMA1_CH1_DEFAULT) || ((REQUEST) == HAL_DMA1_CH1_ADC) || \ + ((REQUEST) == HAL_DMA1_CH1_TIM17_CH1) || ((REQUEST) == HAL_DMA1_CH1_TIM17_UP) || \ + ((REQUEST) == HAL_DMA1_CH1_USART1_RX) || ((REQUEST) == HAL_DMA1_CH1_USART2_RX) || \ + ((REQUEST) == HAL_DMA1_CH1_USART3_RX) || ((REQUEST) == HAL_DMA1_CH1_USART4_RX) || \ + ((REQUEST) == HAL_DMA1_CH1_USART5_RX) || ((REQUEST) == HAL_DMA1_CH1_USART6_RX) || \ + ((REQUEST) == HAL_DMA1_CH1_USART7_RX) || ((REQUEST) == HAL_DMA1_CH1_USART8_RX) || \ + ((REQUEST) == HAL_DMA1_CH2_DEFAULT) || ((REQUEST) == HAL_DMA1_CH2_ADC) || \ + ((REQUEST) == HAL_DMA1_CH2_I2C1_TX) || ((REQUEST) == HAL_DMA1_CH2_SPI1_RX) || \ + ((REQUEST) == HAL_DMA1_CH2_TIM1_CH1) || ((REQUEST) == HAL_DMA1_CH2_I2C1_TX) || \ + ((REQUEST) == HAL_DMA1_CH2_TIM17_CH1) || ((REQUEST) == HAL_DMA1_CH2_TIM17_UP) || \ + ((REQUEST) == HAL_DMA1_CH2_USART1_TX) || ((REQUEST) == HAL_DMA1_CH2_USART2_TX) || \ + ((REQUEST) == HAL_DMA1_CH2_USART3_TX) || ((REQUEST) == HAL_DMA1_CH2_USART4_TX) || \ + ((REQUEST) == HAL_DMA1_CH2_USART5_TX) || ((REQUEST) == HAL_DMA1_CH2_USART6_TX) || \ + ((REQUEST) == HAL_DMA1_CH2_USART7_TX) || ((REQUEST) == HAL_DMA1_CH2_USART8_TX) || \ + ((REQUEST) == HAL_DMA1_CH3_DEFAULT) || ((REQUEST) == HAL_DMA1_CH3_TIM6_UP) || \ + ((REQUEST) == HAL_DMA1_CH3_DAC_CH1) || ((REQUEST) == HAL_DMA1_CH3_I2C1_RX) || \ + ((REQUEST) == HAL_DMA1_CH3_SPI1_TX) || ((REQUEST) == HAL_DMA1_CH3_TIM1_CH2) || \ + ((REQUEST) == HAL_DMA1_CH3_TIM2_CH2) || ((REQUEST) == HAL_DMA1_CH3_TIM16_CH1) || \ + ((REQUEST) == HAL_DMA1_CH3_TIM16_UP) || ((REQUEST) == HAL_DMA1_CH3_USART1_RX) || \ + ((REQUEST) == HAL_DMA1_CH3_USART2_RX) || ((REQUEST) == HAL_DMA1_CH3_USART3_RX) || \ + ((REQUEST) == HAL_DMA1_CH3_USART4_RX) || ((REQUEST) == HAL_DMA1_CH3_USART5_RX) || \ + ((REQUEST) == HAL_DMA1_CH3_USART6_RX) || ((REQUEST) == HAL_DMA1_CH3_USART7_RX) || \ + ((REQUEST) == HAL_DMA1_CH3_USART8_RX) || ((REQUEST) == HAL_DMA1_CH4_DEFAULT) || \ + ((REQUEST) == HAL_DMA1_CH4_TIM7_UP) || ((REQUEST) == HAL_DMA1_CH4_DAC_CH2) || \ + ((REQUEST) == HAL_DMA1_CH4_I2C2_TX) || ((REQUEST) == HAL_DMA1_CH4_SPI2_RX) || \ + ((REQUEST) == HAL_DMA1_CH4_TIM2_CH4) || ((REQUEST) == HAL_DMA1_CH4_TIM3_CH1) || \ + ((REQUEST) == HAL_DMA1_CH4_TIM3_TRIG) || ((REQUEST) == HAL_DMA1_CH4_TIM16_CH1) || \ + ((REQUEST) == HAL_DMA1_CH4_TIM16_UP) || ((REQUEST) == HAL_DMA1_CH4_USART1_TX) || \ + ((REQUEST) == HAL_DMA1_CH4_USART2_TX) || ((REQUEST) == HAL_DMA1_CH4_USART3_TX) || \ + ((REQUEST) == HAL_DMA1_CH4_USART4_TX) || ((REQUEST) == HAL_DMA1_CH4_USART5_TX) || \ + ((REQUEST) == HAL_DMA1_CH4_USART6_TX) || ((REQUEST) == HAL_DMA1_CH4_USART7_TX) || \ + ((REQUEST) == HAL_DMA1_CH4_USART8_TX) || ((REQUEST) == HAL_DMA1_CH5_DEFAULT) || \ + ((REQUEST) == HAL_DMA1_CH5_I2C2_RX) || ((REQUEST) == HAL_DMA1_CH5_SPI2_TX) || \ + ((REQUEST) == HAL_DMA1_CH5_TIM1_CH3) || ((REQUEST) == HAL_DMA1_CH5_USART1_RX) || \ + ((REQUEST) == HAL_DMA1_CH5_USART2_RX) || ((REQUEST) == HAL_DMA1_CH5_USART3_RX) || \ + ((REQUEST) == HAL_DMA1_CH5_USART4_RX) || ((REQUEST) == HAL_DMA1_CH5_USART5_RX) || \ + ((REQUEST) == HAL_DMA1_CH5_USART6_RX) || ((REQUEST) == HAL_DMA1_CH5_USART7_RX) || \ + ((REQUEST) == HAL_DMA1_CH5_USART8_RX) || ((REQUEST) == HAL_DMA1_CH6_DEFAULT) || \ + ((REQUEST) == HAL_DMA1_CH6_I2C1_TX) || ((REQUEST) == HAL_DMA1_CH6_SPI2_RX) || \ + ((REQUEST) == HAL_DMA1_CH6_TIM1_CH1) || ((REQUEST) == HAL_DMA1_CH6_TIM1_CH2) || \ + ((REQUEST) == HAL_DMA1_CH6_TIM1_CH3) || ((REQUEST) == HAL_DMA1_CH6_TIM3_CH1) || \ + ((REQUEST) == HAL_DMA1_CH6_TIM3_TRIG) || ((REQUEST) == HAL_DMA1_CH6_TIM16_CH1) || \ + ((REQUEST) == HAL_DMA1_CH6_TIM16_UP) || ((REQUEST) == HAL_DMA1_CH6_USART1_RX) || \ + ((REQUEST) == HAL_DMA1_CH6_USART2_RX) || ((REQUEST) == HAL_DMA1_CH6_USART3_RX) || \ + ((REQUEST) == HAL_DMA1_CH6_USART4_RX) || ((REQUEST) == HAL_DMA1_CH6_USART5_RX) || \ + ((REQUEST) == HAL_DMA1_CH6_USART6_RX) || ((REQUEST) == HAL_DMA1_CH6_USART7_RX) || \ + ((REQUEST) == HAL_DMA1_CH6_USART8_RX) || ((REQUEST) == HAL_DMA1_CH7_DEFAULT) || \ + ((REQUEST) == HAL_DMA1_CH7_I2C1_RX) || ((REQUEST) == HAL_DMA1_CH7_SPI2_TX) || \ + ((REQUEST) == HAL_DMA1_CH7_TIM2_CH2) || ((REQUEST) == HAL_DMA1_CH7_TIM2_CH4) || \ + ((REQUEST) == HAL_DMA1_CH7_TIM17_CH1) || ((REQUEST) == HAL_DMA1_CH7_TIM17_UP) || \ + ((REQUEST) == HAL_DMA1_CH7_USART1_TX) || ((REQUEST) == HAL_DMA1_CH7_USART2_TX) || \ + ((REQUEST) == HAL_DMA1_CH7_USART3_TX) || ((REQUEST) == HAL_DMA1_CH7_USART4_TX) || \ + ((REQUEST) == HAL_DMA1_CH7_USART5_TX) || ((REQUEST) == HAL_DMA1_CH7_USART6_TX) || \ + ((REQUEST) == HAL_DMA1_CH7_USART7_TX) || ((REQUEST) == HAL_DMA1_CH7_USART8_TX)) + +#define IS_HAL_DMA2_REMAP(REQUEST) \ + (((REQUEST) == HAL_DMA2_CH1_DEFAULT) || ((REQUEST) == HAL_DMA2_CH1_I2C2_TX) || \ + ((REQUEST) == HAL_DMA2_CH1_USART1_TX) || ((REQUEST) == HAL_DMA2_CH1_USART2_TX) || \ + ((REQUEST) == HAL_DMA2_CH1_USART3_TX) || ((REQUEST) == HAL_DMA2_CH1_USART4_TX) || \ + ((REQUEST) == HAL_DMA2_CH1_USART5_TX) || ((REQUEST) == HAL_DMA2_CH1_USART6_TX) || \ + ((REQUEST) == HAL_DMA2_CH1_USART7_TX) || ((REQUEST) == HAL_DMA2_CH1_USART8_TX) || \ + ((REQUEST) == HAL_DMA2_CH2_DEFAULT) || ((REQUEST) == HAL_DMA2_CH2_I2C2_RX) || \ + ((REQUEST) == HAL_DMA2_CH2_USART1_RX) || ((REQUEST) == HAL_DMA2_CH2_USART2_RX) || \ + ((REQUEST) == HAL_DMA2_CH2_USART3_RX) || ((REQUEST) == HAL_DMA2_CH2_USART4_RX) || \ + ((REQUEST) == HAL_DMA2_CH2_USART5_RX) || ((REQUEST) == HAL_DMA2_CH2_USART6_RX) || \ + ((REQUEST) == HAL_DMA2_CH2_USART7_RX) || ((REQUEST) == HAL_DMA2_CH2_USART8_RX) || \ + ((REQUEST) == HAL_DMA2_CH3_DEFAULT) || ((REQUEST) == HAL_DMA2_CH3_TIM6_UP) || \ + ((REQUEST) == HAL_DMA2_CH3_DAC_CH1) || ((REQUEST) == HAL_DMA2_CH3_SPI1_RX) || \ + ((REQUEST) == HAL_DMA2_CH3_USART1_RX) || ((REQUEST) == HAL_DMA2_CH3_USART2_RX) || \ + ((REQUEST) == HAL_DMA2_CH3_USART3_RX) || ((REQUEST) == HAL_DMA2_CH3_USART4_RX) || \ + ((REQUEST) == HAL_DMA2_CH3_USART5_RX) || ((REQUEST) == HAL_DMA2_CH3_USART6_RX) || \ + ((REQUEST) == HAL_DMA2_CH3_USART7_RX) || ((REQUEST) == HAL_DMA2_CH3_USART8_RX) || \ + ((REQUEST) == HAL_DMA2_CH4_DEFAULT) || ((REQUEST) == HAL_DMA2_CH4_TIM7_UP) || \ + ((REQUEST) == HAL_DMA2_CH4_DAC_CH2) || ((REQUEST) == HAL_DMA2_CH4_SPI1_TX) || \ + ((REQUEST) == HAL_DMA2_CH4_USART1_TX) || ((REQUEST) == HAL_DMA2_CH4_USART2_TX) || \ + ((REQUEST) == HAL_DMA2_CH4_USART3_TX) || ((REQUEST) == HAL_DMA2_CH4_USART4_TX) || \ + ((REQUEST) == HAL_DMA2_CH4_USART5_TX) || ((REQUEST) == HAL_DMA2_CH4_USART6_TX) || \ + ((REQUEST) == HAL_DMA2_CH4_USART7_TX) || ((REQUEST) == HAL_DMA2_CH4_USART8_TX) || \ + ((REQUEST) == HAL_DMA2_CH5_DEFAULT) || ((REQUEST) == HAL_DMA2_CH5_ADC) || \ + ((REQUEST) == HAL_DMA2_CH5_USART1_TX) || ((REQUEST) == HAL_DMA2_CH5_USART2_TX) || \ + ((REQUEST) == HAL_DMA2_CH5_USART3_TX) || ((REQUEST) == HAL_DMA2_CH5_USART4_TX) || \ + ((REQUEST) == HAL_DMA2_CH5_USART5_TX) || ((REQUEST) == HAL_DMA2_CH5_USART6_TX) || \ + ((REQUEST) == HAL_DMA2_CH5_USART7_TX) || ((REQUEST) == HAL_DMA2_CH5_USART8_TX)) +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030xC) +#define IS_HAL_DMA1_REMAP(REQUEST) \ + (((REQUEST) == HAL_DMA1_CH1_DEFAULT) || ((REQUEST) == HAL_DMA1_CH1_ADC) || \ + ((REQUEST) == HAL_DMA1_CH1_TIM17_CH1) || ((REQUEST) == HAL_DMA1_CH1_TIM17_UP) || \ + ((REQUEST) == HAL_DMA1_CH1_USART1_RX) || ((REQUEST) == HAL_DMA1_CH1_USART2_RX) || \ + ((REQUEST) == HAL_DMA1_CH1_USART3_RX) || ((REQUEST) == HAL_DMA1_CH1_USART4_RX) || \ + ((REQUEST) == HAL_DMA1_CH1_USART5_RX) || ((REQUEST) == HAL_DMA1_CH1_USART6_RX) || \ + ((REQUEST) == HAL_DMA1_CH2_DEFAULT) || ((REQUEST) == HAL_DMA1_CH2_ADC) || \ + ((REQUEST) == HAL_DMA1_CH2_I2C1_TX) || ((REQUEST) == HAL_DMA1_CH2_SPI1_RX) || \ + ((REQUEST) == HAL_DMA1_CH2_TIM1_CH1) || ((REQUEST) == HAL_DMA1_CH2_I2C1_TX) || \ + ((REQUEST) == HAL_DMA1_CH2_TIM17_CH1) || ((REQUEST) == HAL_DMA1_CH2_TIM17_UP) || \ + ((REQUEST) == HAL_DMA1_CH2_USART1_TX) || ((REQUEST) == HAL_DMA1_CH2_USART2_TX) || \ + ((REQUEST) == HAL_DMA1_CH2_USART3_TX) || ((REQUEST) == HAL_DMA1_CH2_USART4_TX) || \ + ((REQUEST) == HAL_DMA1_CH2_USART5_TX) || ((REQUEST) == HAL_DMA1_CH2_USART6_TX) || \ + ((REQUEST) == HAL_DMA1_CH3_DEFAULT) || ((REQUEST) == HAL_DMA1_CH3_TIM6_UP) || \ + ((REQUEST) == HAL_DMA1_CH3_I2C1_RX) || ((REQUEST) == HAL_DMA1_CH3_SPI1_TX) || \ + ((REQUEST) == HAL_DMA1_CH3_TIM1_CH2) || ((REQUEST) == HAL_DMA1_CH3_TIM16_CH1) || \ + ((REQUEST) == HAL_DMA1_CH3_TIM16_UP) || ((REQUEST) == HAL_DMA1_CH3_USART1_RX) || \ + ((REQUEST) == HAL_DMA1_CH3_USART2_RX) || ((REQUEST) == HAL_DMA1_CH3_USART3_RX) || \ + ((REQUEST) == HAL_DMA1_CH3_USART4_RX) || ((REQUEST) == HAL_DMA1_CH3_USART5_RX) || \ + ((REQUEST) == HAL_DMA1_CH3_USART6_RX) || ((REQUEST) == HAL_DMA1_CH4_DEFAULT) || \ + ((REQUEST) == HAL_DMA1_CH4_TIM7_UP) || ((REQUEST) == HAL_DMA1_CH4_I2C2_TX) || \ + ((REQUEST) == HAL_DMA1_CH4_SPI2_RX) || ((REQUEST) == HAL_DMA1_CH4_TIM3_CH1) || \ + ((REQUEST) == HAL_DMA1_CH4_TIM3_TRIG) || ((REQUEST) == HAL_DMA1_CH4_TIM16_CH1) || \ + ((REQUEST) == HAL_DMA1_CH4_TIM16_UP) || ((REQUEST) == HAL_DMA1_CH4_USART1_TX) || \ + ((REQUEST) == HAL_DMA1_CH4_USART2_TX) || ((REQUEST) == HAL_DMA1_CH4_USART3_TX) || \ + ((REQUEST) == HAL_DMA1_CH4_USART4_TX) || ((REQUEST) == HAL_DMA1_CH4_USART5_TX) || \ + ((REQUEST) == HAL_DMA1_CH4_USART6_TX) || ((REQUEST) == HAL_DMA1_CH5_DEFAULT) || \ + ((REQUEST) == HAL_DMA1_CH5_I2C2_RX) || ((REQUEST) == HAL_DMA1_CH5_SPI2_TX) || \ + ((REQUEST) == HAL_DMA1_CH5_TIM1_CH3) || ((REQUEST) == HAL_DMA1_CH5_USART1_RX) || \ + ((REQUEST) == HAL_DMA1_CH5_USART2_RX) || ((REQUEST) == HAL_DMA1_CH5_USART3_RX) || \ + ((REQUEST) == HAL_DMA1_CH5_USART4_RX) || ((REQUEST) == HAL_DMA1_CH5_USART5_RX) || \ + ((REQUEST) == HAL_DMA1_CH5_USART6_RX)) +#endif /* STM32F030xC */ + +/** + * @} + */ +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + + /* Exported macros -----------------------------------------------------------*/ + + /** @defgroup DMAEx_Exported_Macros DMAEx Exported Macros + * @{ + */ + /* Interrupt & Flag management */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) +/** + * @brief Returns the current DMA Channel transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer complete flag index. + */ +#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_TC1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_TC2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_TC3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_TC4 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5)) ? DMA_FLAG_TC5 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6)) ? DMA_FLAG_TC6 \ + : DMA_FLAG_TC7) + +/** + * @brief Returns the current DMA Channel half transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified half transfer complete flag index. + */ +#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_HT1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_HT2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_HT3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_HT4 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5)) ? DMA_FLAG_HT5 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6)) ? DMA_FLAG_HT6 \ + : DMA_FLAG_HT7) + +/** + * @brief Returns the current DMA Channel transfer error flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_TE1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_TE2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_TE3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_TE4 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5)) ? DMA_FLAG_TE5 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6)) ? DMA_FLAG_TE6 \ + : DMA_FLAG_TE7) + +/** + * @brief Return the current DMA Channel Global interrupt flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_GL1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_GL2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_GL3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_GL4 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5)) ? DMA_FLAG_GL5 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6)) ? DMA_FLAG_GL6 \ + : DMA_FLAG_GL7) + + /** + * @brief Get the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 1_7 to select the DMA Channel flag. + * @retval The state of FLAG (SET or RESET). + */ + +#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) (DMA1->ISR & (__FLAG__)) + +/** + * @brief Clears the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 1_7 to select the DMA Channel flag. + * @retval None + */ +#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) (DMA1->IFCR = (__FLAG__)) + +#elif defined(STM32F091xC) || defined(STM32F098xx) +/** + * @brief Returns the current DMA Channel transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer complete flag index. + */ +#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_TC1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_TC2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_TC3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_TC4 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5)) ? DMA_FLAG_TC5 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6)) ? DMA_FLAG_TC6 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7)) ? DMA_FLAG_TC7 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1)) ? DMA_FLAG_TC1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2)) ? DMA_FLAG_TC2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3)) ? DMA_FLAG_TC3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4)) ? DMA_FLAG_TC4 \ + : DMA_FLAG_TC5) + +/** + * @brief Returns the current DMA Channel half transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified half transfer complete flag index. + */ +#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_HT1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_HT2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_HT3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_HT4 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5)) ? DMA_FLAG_HT5 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6)) ? DMA_FLAG_HT6 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7)) ? DMA_FLAG_HT7 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1)) ? DMA_FLAG_HT1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2)) ? DMA_FLAG_HT2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3)) ? DMA_FLAG_HT3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4)) ? DMA_FLAG_HT4 \ + : DMA_FLAG_HT5) + +/** + * @brief Returns the current DMA Channel transfer error flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_TE1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_TE2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_TE3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_TE4 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5)) ? DMA_FLAG_TE5 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6)) ? DMA_FLAG_TE6 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7)) ? DMA_FLAG_TE7 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1)) ? DMA_FLAG_TE1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2)) ? DMA_FLAG_TE2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3)) ? DMA_FLAG_TE3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4)) ? DMA_FLAG_TE4 \ + : DMA_FLAG_TE5) + +/** + * @brief Return the current DMA Channel Global interrupt flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_GL1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_GL2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_GL3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_GL4 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5)) ? DMA_FLAG_GL5 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6)) ? DMA_FLAG_GL6 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7)) ? DMA_FLAG_GL7 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1)) ? DMA_FLAG_GL1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2)) ? DMA_FLAG_GL2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3)) ? DMA_FLAG_GL3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4)) ? DMA_FLAG_GL4 \ + : DMA_FLAG_GL5) + +/** + * @brief Get the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 0_4, 1_5, 2_6 or 3_7 to select the DMA Channel flag. + * @retval The state of FLAG (SET or RESET). + */ + +#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) \ + (((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Channel7) \ + ? (DMA2->ISR & (__FLAG__)) \ + : (DMA1->ISR & (__FLAG__))) + +/** + * @brief Clears the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 0_4, 1_5, 2_6 or 3_7 to select the DMA Channel flag. + * @retval None + */ +#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + (((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Channel7) \ + ? (DMA2->IFCR = (__FLAG__)) \ + : (DMA1->IFCR = (__FLAG__))) + +#else /* STM32F030x8_STM32F030xC_STM32F031x6_STM32F038xx_STM32F051x8_STM32F058xx_STM32F070x6_STM32F070xB \ + Product devices */ +/** + * @brief Returns the current DMA Channel transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer complete flag index. + */ +#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_TC1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_TC2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_TC3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_TC4 \ + : DMA_FLAG_TC5) + +/** + * @brief Returns the current DMA Channel half transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified half transfer complete flag index. + */ +#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_HT1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_HT2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_HT3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_HT4 \ + : DMA_FLAG_HT5) + +/** + * @brief Returns the current DMA Channel transfer error flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_TE1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_TE2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_TE3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_TE4 \ + : DMA_FLAG_TE5) + +/** + * @brief Return the current DMA Channel Global interrupt flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__) \ + (((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1)) ? DMA_FLAG_GL1 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2)) ? DMA_FLAG_GL2 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3)) ? DMA_FLAG_GL3 \ + : ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4)) ? DMA_FLAG_GL4 \ + : DMA_FLAG_GL5) + +/** + * @brief Get the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 1_5 to select the DMA Channel flag. + * @retval The state of FLAG (SET or RESET). + */ + +#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) (DMA1->ISR & (__FLAG__)) + +/** + * @brief Clears the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 1_5 to select the DMA Channel flag. + * @retval None + */ +#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) (DMA1->IFCR = (__FLAG__)) + +#endif + + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) +#define __HAL_DMA1_REMAP(__REQUEST__) \ + do \ + { \ + assert_param(IS_HAL_DMA1_REMAP(__REQUEST__)); \ + DMA1->CSELR &= ~(0x0FU << (uint32_t)(((__REQUEST__) >> 28U) * 4U)); \ + DMA1->CSELR |= (uint32_t)((__REQUEST__)&0x0FFFFFFFU); \ + } while (0) + +#if defined(STM32F091xC) || defined(STM32F098xx) +#define __HAL_DMA2_REMAP(__REQUEST__) \ + do \ + { \ + assert_param(IS_HAL_DMA2_REMAP(__REQUEST__)); \ + DMA2->CSELR &= ~(0x0FU << (uint32_t)(((__REQUEST__) >> 28U) * 4U)); \ + DMA2->CSELR |= (uint32_t)((__REQUEST__)&0x0FFFFFFFU); \ + } while (0) +#endif /* STM32F091xC || STM32F098xx */ + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_DMA_EX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_exti.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_exti.h new file mode 100644 index 0000000000..f1b540f905 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_exti.h @@ -0,0 +1,401 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_exti.h + * @author MCD Application Team + * @brief Header file of EXTI HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_EXTI_H +#define STM32F0xx_HAL_EXTI_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @defgroup EXTI EXTI + * @brief EXTI HAL module driver + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** @defgroup EXTI_Exported_Types EXTI Exported Types + * @{ + */ + + /** + * @brief HAL EXTI common Callback ID enumeration definition + */ + typedef enum + { + HAL_EXTI_COMMON_CB_ID = 0x00U + } EXTI_CallbackIDTypeDef; + + /** + * @brief EXTI Handle structure definition + */ + typedef struct + { + uint32_t Line; /*!< Exti line number */ + void (*PendingCallback)(void); /*!< Exti pending callback */ + } EXTI_HandleTypeDef; + + /** + * @brief EXTI Configuration structure definition + */ + typedef struct + { + uint32_t Line; /*!< The Exti line to be configured. This parameter + can be a value of @ref EXTI_Line */ + uint32_t Mode; /*!< The Exit Mode to be configured for a core. + This parameter can be a combination of @ref EXTI_Mode */ + uint32_t Trigger; /*!< The Exti Trigger to be configured. This parameter + can be a value of @ref EXTI_Trigger */ + uint32_t GPIOSel; /*!< The Exti GPIO multiplexer selection to be configured. + This parameter is only possible for line 0 to 15. It + can be a value of @ref EXTI_GPIOSel */ + } EXTI_ConfigTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup EXTI_Exported_Constants EXTI Exported Constants + * @{ + */ + +/** @defgroup EXTI_Line EXTI Line + * @{ + */ +#define EXTI_LINE_0 (EXTI_GPIO | 0x00u) /*!< External interrupt line 0 */ +#define EXTI_LINE_1 (EXTI_GPIO | 0x01u) /*!< External interrupt line 1 */ +#define EXTI_LINE_2 (EXTI_GPIO | 0x02u) /*!< External interrupt line 2 */ +#define EXTI_LINE_3 (EXTI_GPIO | 0x03u) /*!< External interrupt line 3 */ +#define EXTI_LINE_4 (EXTI_GPIO | 0x04u) /*!< External interrupt line 4 */ +#define EXTI_LINE_5 (EXTI_GPIO | 0x05u) /*!< External interrupt line 5 */ +#define EXTI_LINE_6 (EXTI_GPIO | 0x06u) /*!< External interrupt line 6 */ +#define EXTI_LINE_7 (EXTI_GPIO | 0x07u) /*!< External interrupt line 7 */ +#define EXTI_LINE_8 (EXTI_GPIO | 0x08u) /*!< External interrupt line 8 */ +#define EXTI_LINE_9 (EXTI_GPIO | 0x09u) /*!< External interrupt line 9 */ +#define EXTI_LINE_10 (EXTI_GPIO | 0x0Au) /*!< External interrupt line 10 */ +#define EXTI_LINE_11 (EXTI_GPIO | 0x0Bu) /*!< External interrupt line 11 */ +#define EXTI_LINE_12 (EXTI_GPIO | 0x0Cu) /*!< External interrupt line 12 */ +#define EXTI_LINE_13 (EXTI_GPIO | 0x0Du) /*!< External interrupt line 13 */ +#define EXTI_LINE_14 (EXTI_GPIO | 0x0Eu) /*!< External interrupt line 14 */ +#define EXTI_LINE_15 (EXTI_GPIO | 0x0Fu) /*!< External interrupt line 15 */ + +#if defined(EXTI_IMR_MR16) +#define EXTI_LINE_16 \ + (EXTI_CONFIG | 0x10u) /*!< External interrupt line 16 Connected to the PVD Output */ +#else +#define EXTI_LINE_16 (EXTI_RESERVED | 0x10u) +#endif /* EXTI_IMR_MR16 */ + +#define EXTI_LINE_17 \ + (EXTI_CONFIG | \ + 0x11u) /*!< External interrupt line 17 Connected to the RTC Alarm event */ + +#if defined(EXTI_IMR_MR18) +#define EXTI_LINE_18 \ + (EXTI_CONFIG | 0x12u) /*!< External interrupt line 18 Connected to the USB OTG FS \ + Wakeup from suspend event */ +#else +#define EXTI_LINE_18 (EXTI_RESERVED | 0x12u) +#endif /* EXTI_IMR_MR18 */ + +#define EXTI_LINE_19 \ + (EXTI_CONFIG | \ + 0x13u) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */ + +#if defined(EXTI_IMR_MR20) +#define EXTI_LINE_20 \ + (EXTI_CONFIG | 0x14u) /*!< External interrupt line 20 Connected to the USB OTG HS \ + (configured in FS) Wakeup event */ +#else +#define EXTI_LINE_20 (EXTI_RESERVED | 0x14u) +#endif /* EXTI_IMR_MR20 */ + +#if defined(EXTI_IMR_MR21) +#define EXTI_LINE_21 \ + (EXTI_CONFIG | \ + 0x15u) /*!< External interrupt line 21 Connected to the Comparator 1 output */ +#else +#define EXTI_LINE_21 (EXTI_RESERVED | 0x15u) +#endif /* EXTI_IMR_MR21 */ + +#if defined(EXTI_IMR_MR22) +#define EXTI_LINE_22 \ + (EXTI_CONFIG | \ + 0x16u) /*!< External interrupt line 22 Connected to the Comparator 2 output */ +#else +#define EXTI_LINE_22 (EXTI_RESERVED | 0x16u) +#endif /* EXTI_IMR_MR22 */ + +#if defined(EXTI_IMR_MR23) +#define EXTI_LINE_23 \ + (EXTI_DIRECT | 0x17u) /*!< External interrupt line 23 Connected to the internal I2C1 \ + wakeup event */ +#else +#define EXTI_LINE_23 (EXTI_RESERVED | 0x17u) +#endif /* EXTI_IMR_MR23 */ + +#define EXTI_LINE_24 (EXTI_RESERVED | 0x18u) + +#if defined(EXTI_IMR_MR25) +#define EXTI_LINE_25 \ + (EXTI_CONFIG | 0x19u) /*!< External interrupt line 25 Connected to the internal \ + USART1 wakeup event */ +#else +#define EXTI_LINE_25 (EXTI_RESERVED | 0x19u) +#endif /* EXTI_IMR_MR25 */ + +#if defined(EXTI_IMR_MR26) +#define EXTI_LINE_26 \ + (EXTI_CONFIG | 0x1Au) /*!< External interrupt line 26 Connected to the internal \ + USART2 wakeup event */ +#else +#define EXTI_LINE_26 (EXTI_RESERVED | 0x1Au) +#endif /* EXTI_IMR_MR26 */ + +#if defined(EXTI_IMR_MR27) +#define EXTI_LINE_27 \ + (EXTI_CONFIG | 0x1Bu) /*!< External interrupt line 27 Connected to the internal CEC \ + wakeup event */ +#else +#define EXTI_LINE_27 (EXTI_RESERVED | 0x1Bu) +#endif /* EXTI_IMR_MR27 */ + +#if defined(EXTI_IMR_MR28) +#define EXTI_LINE_28 \ + (EXTI_CONFIG | 0x1Cu) /*!< External interrupt line 28 Connected to the internal \ + USART3 wakeup event */ +#else +#define EXTI_LINE_28 (EXTI_RESERVED | 0x1Cu) +#endif /* EXTI_IMR_MR28 */ + +#define EXTI_LINE_29 (EXTI_RESERVED | 0x1Du) +#define EXTI_LINE_30 (EXTI_RESERVED | 0x1Eu) + +#if defined(EXTI_IMR_MR31) +#define EXTI_LINE_31 \ + (EXTI_CONFIG | 0x1Fu) /*!< External interrupt line 31 Connected to the VDDIO2 supply \ + comparator output */ +#else +#define EXTI_LINE_31 (EXTI_RESERVED | 0x1Fu) +#endif /* EXTI_IMR_MR31 */ + +/** + * @} + */ + +/** @defgroup EXTI_Mode EXTI Mode + * @{ + */ +#define EXTI_MODE_NONE 0x00000000u +#define EXTI_MODE_INTERRUPT 0x00000001u +#define EXTI_MODE_EVENT 0x00000002u +/** + * @} + */ + +/** @defgroup EXTI_Trigger EXTI Trigger + * @{ + */ +#define EXTI_TRIGGER_NONE 0x00000000u +#define EXTI_TRIGGER_RISING 0x00000001u +#define EXTI_TRIGGER_FALLING 0x00000002u +#define EXTI_TRIGGER_RISING_FALLING (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING) +/** + * @} + */ + +/** @defgroup EXTI_GPIOSel EXTI GPIOSel + * @brief + * @{ + */ +#define EXTI_GPIOA 0x00000000u +#define EXTI_GPIOB 0x00000001u +#define EXTI_GPIOC 0x00000002u +#if defined(GPIOD) +#define EXTI_GPIOD 0x00000003u +#endif /* GPIOD */ +#if defined(GPIOE) +#define EXTI_GPIOE 0x00000004u +#endif /* GPIOE */ +#define EXTI_GPIOF 0x00000005u +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EXTI_Exported_Macros EXTI Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Private constants --------------------------------------------------------*/ +/** @defgroup EXTI_Private_Constants EXTI Private Constants + * @{ + */ +/** + * @brief EXTI Line property definition + */ +#define EXTI_PROPERTY_SHIFT 24u +#define EXTI_DIRECT (0x01uL << EXTI_PROPERTY_SHIFT) +#define EXTI_CONFIG (0x02uL << EXTI_PROPERTY_SHIFT) +#define EXTI_GPIO ((0x04uL << EXTI_PROPERTY_SHIFT) | EXTI_CONFIG) +#define EXTI_RESERVED (0x08uL << EXTI_PROPERTY_SHIFT) +#define EXTI_PROPERTY_MASK (EXTI_DIRECT | EXTI_CONFIG | EXTI_GPIO) + +/** + * @brief EXTI bit usage + */ +#define EXTI_PIN_MASK 0x0000001Fu + +/** + * @brief EXTI Mask for interrupt & event mode + */ +#define EXTI_MODE_MASK (EXTI_MODE_EVENT | EXTI_MODE_INTERRUPT) + +/** + * @brief EXTI Mask for trigger possibilities + */ +#define EXTI_TRIGGER_MASK (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING) + +/** + * @brief EXTI Line number + */ +#define EXTI_LINE_NB 32uL + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup EXTI_Private_Macros EXTI Private Macros + * @{ + */ +#define IS_EXTI_LINE(__EXTI_LINE__) \ + ((((__EXTI_LINE__) & ~(EXTI_PROPERTY_MASK | EXTI_PIN_MASK)) == 0x00u) && \ + ((((__EXTI_LINE__)&EXTI_PROPERTY_MASK) == EXTI_DIRECT) || \ + (((__EXTI_LINE__)&EXTI_PROPERTY_MASK) == EXTI_CONFIG) || \ + (((__EXTI_LINE__)&EXTI_PROPERTY_MASK) == EXTI_GPIO)) && \ + (((__EXTI_LINE__)&EXTI_PIN_MASK) < EXTI_LINE_NB)) + +#define IS_EXTI_MODE(__EXTI_LINE__) \ + ((((__EXTI_LINE__)&EXTI_MODE_MASK) != 0x00u) && \ + (((__EXTI_LINE__) & ~EXTI_MODE_MASK) == 0x00u)) + +#define IS_EXTI_TRIGGER(__EXTI_LINE__) (((__EXTI_LINE__) & ~EXTI_TRIGGER_MASK) == 0x00u) + +#define IS_EXTI_PENDING_EDGE(__EXTI_LINE__) \ + ((__EXTI_LINE__) == EXTI_TRIGGER_RISING_FALLING) + +#define IS_EXTI_CONFIG_LINE(__EXTI_LINE__) (((__EXTI_LINE__)&EXTI_CONFIG) != 0x00u) + +#if defined(GPIOE) +#define IS_EXTI_GPIO_PORT(__PORT__) \ + (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || \ + ((__PORT__) == EXTI_GPIOC) || ((__PORT__) == EXTI_GPIOD) || \ + ((__PORT__) == EXTI_GPIOE) || ((__PORT__) == EXTI_GPIOF)) +#elif defined(GPIOD) +#define IS_EXTI_GPIO_PORT(__PORT__) \ + (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || \ + ((__PORT__) == EXTI_GPIOC) || ((__PORT__) == EXTI_GPIOD) || \ + ((__PORT__) == EXTI_GPIOF)) +#else +#define IS_EXTI_GPIO_PORT(__PORT__) \ + (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || \ + ((__PORT__) == EXTI_GPIOC) || ((__PORT__) == EXTI_GPIOF)) +#endif /* GPIOE */ + +#define IS_EXTI_GPIO_PIN(__PIN__) ((__PIN__) < 16u) + + /** + * @} + */ + + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup EXTI_Exported_Functions EXTI Exported Functions + * @brief EXTI Exported Functions + * @{ + */ + + /** @defgroup EXTI_Exported_Functions_Group1 Configuration functions + * @brief Configuration functions + * @{ + */ + /* Configuration functions ****************************************************/ + HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, + EXTI_ConfigTypeDef *pExtiConfig); + HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, + EXTI_ConfigTypeDef *pExtiConfig); + HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti); + HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, + EXTI_CallbackIDTypeDef CallbackID, + void (*pPendingCbfn)(void)); + HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine); + /** + * @} + */ + + /** @defgroup EXTI_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * @{ + */ + /* IO operation functions *****************************************************/ + void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti); + uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge); + void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge); + void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_EXTI_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_flash.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_flash.h new file mode 100644 index 0000000000..1587dbeda7 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_flash.h @@ -0,0 +1,362 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_flash.h + * @author MCD Application Team + * @brief Header file of Flash HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_FLASH_H +#define __STM32F0xx_HAL_FLASH_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/** @addtogroup FLASH_Private_Constants + * @{ + */ +#define FLASH_TIMEOUT_VALUE (50000U) /* 50 s */ + /** + * @} + */ + + /** @addtogroup FLASH_Private_Macros + * @{ + */ + +#define IS_FLASH_TYPEPROGRAM(VALUE) \ + (((VALUE) == FLASH_TYPEPROGRAM_HALFWORD) || ((VALUE) == FLASH_TYPEPROGRAM_WORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_DOUBLEWORD)) + +#define IS_FLASH_LATENCY(__LATENCY__) \ + (((__LATENCY__) == FLASH_LATENCY_0) || ((__LATENCY__) == FLASH_LATENCY_1)) + + /** + * @} + */ + + /* Exported types ------------------------------------------------------------*/ + /** @defgroup FLASH_Exported_Types FLASH Exported Types + * @{ + */ + + /** + * @brief FLASH Procedure structure definition + */ + typedef enum + { + FLASH_PROC_NONE = 0U, + FLASH_PROC_PAGEERASE = 1U, + FLASH_PROC_MASSERASE = 2U, + FLASH_PROC_PROGRAMHALFWORD = 3U, + FLASH_PROC_PROGRAMWORD = 4U, + FLASH_PROC_PROGRAMDOUBLEWORD = 5U + } FLASH_ProcedureTypeDef; + + /** + * @brief FLASH handle Structure definition + */ + typedef struct + { + __IO FLASH_ProcedureTypeDef + ProcedureOnGoing; /*!< Internal variable to indicate which procedure is + ongoing or not in IT context */ + + __IO uint32_t DataRemaining; /*!< Internal variable to save the remaining pages to + erase or half-word to program in IT context */ + + __IO uint32_t Address; /*!< Internal variable to save address selected for program + or erase */ + + __IO uint64_t Data; /*!< Internal variable to save data to be programmed */ + + HAL_LockTypeDef Lock; /*!< FLASH locking object */ + + __IO uint32_t + ErrorCode; /*!< FLASH error code + This parameter can be a value of @ref FLASH_Error_Codes */ + } FLASH_ProcessTypeDef; + + /** + * @} + */ + + /* Exported constants --------------------------------------------------------*/ + /** @defgroup FLASH_Exported_Constants FLASH Exported Constants + * @{ + */ + + /** @defgroup FLASH_Error_Codes FLASH Error Codes + * @{ + */ + +#define HAL_FLASH_ERROR_NONE 0x00U /*!< No error */ +#define HAL_FLASH_ERROR_PROG 0x01U /*!< Programming error */ +#define HAL_FLASH_ERROR_WRP 0x02U /*!< Write protection error */ + +/** + * @} + */ + +/** @defgroup FLASH_Type_Program FLASH Type Program + * @{ + */ +#define FLASH_TYPEPROGRAM_HALFWORD \ + (0x01U) /*!ACR = (FLASH->ACR & (~FLASH_ACR_LATENCY)) | (__LATENCY__)) + + +/** + * @brief Get the FLASH Latency. + * @retval FLASH Latency + * The value of this parameter depend on device used within the same series + */ +#define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)) + +/** + * @} + */ + +/** @defgroup FLASH_Prefetch FLASH Prefetch + * @brief macros to handle FLASH Prefetch buffer + * @{ + */ +/** + * @brief Enable the FLASH prefetch buffer. + * @retval None + */ +#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTBE) + +/** + * @brief Disable the FLASH prefetch buffer. + * @retval None + */ +#define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() (FLASH->ACR &= (~FLASH_ACR_PRFTBE)) + +/** + * @} + */ + +/** @defgroup FLASH_Interrupt FLASH Interrupts + * @brief macros to handle FLASH interrupts + * @{ + */ + +/** + * @brief Enable the specified FLASH interrupt. + * @param __INTERRUPT__ FLASH interrupt + * This parameter can be any combination of the following values: + * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt + * @arg @ref FLASH_IT_ERR Error Interrupt + * @retval none + */ +#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) SET_BIT((FLASH->CR), (__INTERRUPT__)) + +/** + * @brief Disable the specified FLASH interrupt. + * @param __INTERRUPT__ FLASH interrupt + * This parameter can be any combination of the following values: + * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt + * @arg @ref FLASH_IT_ERR Error Interrupt + * @retval none + */ +#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) \ + CLEAR_BIT((FLASH->CR), (uint32_t)(__INTERRUPT__)) + +/** + * @brief Get the specified FLASH flag status. + * @param __FLAG__ specifies the FLASH flag to check. + * This parameter can be one of the following values: + * @arg @ref FLASH_FLAG_BSY FLASH Busy flag + * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag + * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag + * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define __HAL_FLASH_GET_FLAG(__FLAG__) (((FLASH->SR) & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the specified FLASH flag. + * @param __FLAG__ specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag + * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag + * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag + * @retval none + */ +#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) ((FLASH->SR) = (__FLAG__)) + +/** + * @} + */ + +/** + * @} + */ + +/* Include FLASH HAL Extended module */ +#include "stm32f0xx_hal_flash_ex.h" + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup FLASH_Exported_Functions + * @{ + */ + + /** @addtogroup FLASH_Exported_Functions_Group1 + * @{ + */ + /* IO operation functions *****************************************************/ + HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, + uint64_t Data); + HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, + uint64_t Data); + + /* FLASH IRQ handler function */ + void HAL_FLASH_IRQHandler(void); + /* Callbacks in non blocking modes */ + void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue); + void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue); + + /** + * @} + */ + + /** @addtogroup FLASH_Exported_Functions_Group2 + * @{ + */ + /* Peripheral Control functions ***********************************************/ + HAL_StatusTypeDef HAL_FLASH_Unlock(void); + HAL_StatusTypeDef HAL_FLASH_Lock(void); + HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void); + HAL_StatusTypeDef HAL_FLASH_OB_Lock(void); + HAL_StatusTypeDef HAL_FLASH_OB_Launch(void); + + /** + * @} + */ + + /** @addtogroup FLASH_Exported_Functions_Group3 + * @{ + */ + /* Peripheral State and Error functions ***************************************/ + uint32_t HAL_FLASH_GetError(void); + + /** + * @} + */ + + /** + * @} + */ + + /* Private function -------------------------------------------------*/ + /** @addtogroup FLASH_Private_Functions + * @{ + */ + HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_FLASH_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_flash_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_flash_ex.h new file mode 100644 index 0000000000..e7da927bc1 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_flash_ex.h @@ -0,0 +1,488 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_flash_ex.h + * @author MCD Application Team + * @brief Header file of Flash HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_FLASH_EX_H +#define __STM32F0xx_HAL_FLASH_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASHEx + * @{ + */ + +/** @addtogroup FLASHEx_Private_Macros + * @{ + */ +#define IS_FLASH_TYPEERASE(VALUE) \ + (((VALUE) == FLASH_TYPEERASE_PAGES) || ((VALUE) == FLASH_TYPEERASE_MASSERASE)) + +#define IS_OPTIONBYTE(VALUE) \ + ((VALUE) <= (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_DATA)) + +#define IS_WRPSTATE(VALUE) \ + (((VALUE) == OB_WRPSTATE_DISABLE) || ((VALUE) == OB_WRPSTATE_ENABLE)) + +#define IS_OB_DATA_ADDRESS(ADDRESS) \ + (((ADDRESS) == OB_DATA_ADDRESS_DATA0) || ((ADDRESS) == OB_DATA_ADDRESS_DATA1)) + +#define IS_OB_RDP_LEVEL(LEVEL) \ + (((LEVEL) == OB_RDP_LEVEL_0) || ((LEVEL) == OB_RDP_LEVEL_1)) /*|| \ + ((LEVEL) == OB_RDP_LEVEL_2))*/ + +#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW)) + +#define IS_OB_STOP_SOURCE(SOURCE) \ + (((SOURCE) == OB_STOP_NO_RST) || ((SOURCE) == OB_STOP_RST)) + +#define IS_OB_STDBY_SOURCE(SOURCE) \ + (((SOURCE) == OB_STDBY_NO_RST) || ((SOURCE) == OB_STDBY_RST)) + +#define IS_OB_BOOT1(BOOT1) (((BOOT1) == OB_BOOT1_RESET) || ((BOOT1) == OB_BOOT1_SET)) + +#define IS_OB_VDDA_ANALOG(ANALOG) \ + (((ANALOG) == OB_VDDA_ANALOG_ON) || ((ANALOG) == OB_VDDA_ANALOG_OFF)) + +#define IS_OB_SRAM_PARITY(PARITY) \ + (((PARITY) == OB_SRAM_PARITY_SET) || ((PARITY) == OB_SRAM_PARITY_RESET)) + +#if defined(FLASH_OBR_BOOT_SEL) +#define IS_OB_BOOT_SEL(BOOT_SEL) \ + (((BOOT_SEL) == OB_BOOT_SEL_RESET) || ((BOOT_SEL) == OB_BOOT_SEL_SET)) +#define IS_OB_BOOT0(BOOT0) (((BOOT0) == OB_BOOT0_RESET) || ((BOOT0) == OB_BOOT0_SET)) +#endif /* FLASH_OBR_BOOT_SEL */ + + +#define IS_OB_WRP(PAGE) (((PAGE) != 0x0000000U)) + +#define IS_FLASH_NB_PAGES(ADDRESS, NBPAGES) \ + ((ADDRESS) + ((NBPAGES)*FLASH_PAGE_SIZE) - 1 <= FLASH_BANK1_END) + +#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) \ + (((ADDRESS) >= FLASH_BASE) && ((ADDRESS) <= FLASH_BANK1_END)) + + /** + * @} + */ + + /* Exported types ------------------------------------------------------------*/ + /** @defgroup FLASHEx_Exported_Types FLASHEx Exported Types + * @{ + */ + /** + * @brief FLASH Erase structure definition + */ + typedef struct + { + uint32_t + TypeErase; /*!< TypeErase: Mass erase or page erase. + This parameter can be a value of @ref FLASHEx_Type_Erase */ + + uint32_t + PageAddress; /*!< PageAdress: Initial FLASH page address to erase when mass + erase is disabled This parameter must be a number between + Min_Data = FLASH_BASE and Max_Data = FLASH_BANK1_END */ + + uint32_t NbPages; /*!< NbPages: Number of pagess to be erased. + This parameter must be a value between Min_Data = 1 and + Max_Data = (max number of pages - value of initial page)*/ + + } FLASH_EraseInitTypeDef; + + /** + * @brief FLASH Options bytes program structure definition + */ + typedef struct + { + uint32_t OptionType; /*!< OptionType: Option byte to be configured. + This parameter can be a value of @ref FLASHEx_OB_Type */ + + uint32_t + WRPState; /*!< WRPState: Write protection activation or deactivation. + This parameter can be a value of @ref FLASHEx_OB_WRP_State */ + + uint32_t WRPPage; /*!< WRPPage: specifies the page(s) to be write protected + This parameter can be a value of @ref + FLASHEx_OB_Write_Protection */ + + uint8_t RDPLevel; /*!< RDPLevel: Set the read protection level.. + This parameter can be a value of @ref + FLASHEx_OB_Read_Protection */ + + uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte: + IWDG / STOP / STDBY / BOOT1 / VDDA_ANALOG / SRAM_PARITY + This parameter can be a combination of @ref + FLASHEx_OB_IWatchdog, @ref FLASHEx_OB_nRST_STOP, + @ref FLASHEx_OB_nRST_STDBY, @ref FLASHEx_OB_BOOT1, @ref + FLASHEx_OB_VDDA_Analog_Monitoring and + @ref FLASHEx_OB_RAM_Parity_Check_Enable */ + + uint32_t DATAAddress; /*!< DATAAddress: Address of the option byte DATA to be + programmed This parameter can be a value of @ref + FLASHEx_OB_Data_Address */ + + uint8_t DATAData; /*!< DATAData: Data to be stored in the option byte DATA + This parameter must be a number between Min_Data = 0x00 and + Max_Data = 0xFF */ + } FLASH_OBProgramInitTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Constants FLASHEx Exported Constants + * @{ + */ + +/** @defgroup FLASHEx_Page_Size FLASHEx Page Size + * @{ + */ +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || \ + defined(STM32F038xx) || defined(STM32F051x8) || defined(STM32F042x6) || \ + defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6) +#define FLASH_PAGE_SIZE 0x400U +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || \ + STM32F048xx || STM32F058xx || STM32F070x6 */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) +#define FLASH_PAGE_SIZE 0x800U +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || \ + STM32F030xC */ +/** + * @} + */ + +/** @defgroup FLASHEx_Type_Erase FLASH Type Erase + * @{ + */ +#define FLASH_TYPEERASE_PAGES (0x00U) /*!Pin)); + assert_param(IS_GPIO_MODE(GPIO_Init->Mode)); + + /* Configure the port pins */ + while (((GPIO_Init->Pin) >> position) != 0x00u) + { + /* Get current io position */ + iocurrent = (GPIO_Init->Pin) & (1uL << position); + + if (iocurrent != 0x00u) + { + /*--------------------- GPIO Mode Configuration ------------------------*/ + /* In case of Output or Alternate function mode selection */ + if (((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || + ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)) + { + /* Check the Speed parameter */ + assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); + /* Configure the IO Speed */ + temp = GPIOx->OSPEEDR; + temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2u)); + temp |= (GPIO_Init->Speed << (position * 2u)); + GPIOx->OSPEEDR = temp; + + /* Configure the IO Output Type */ + temp = GPIOx->OTYPER; + temp &= ~(GPIO_OTYPER_OT_0 << position); + temp |= + (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position); + GPIOx->OTYPER = temp; + } + + if ((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG) + { + /* Check the Pull parameter */ + assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = GPIOx->PUPDR; + temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2u)); + temp |= ((GPIO_Init->Pull) << (position * 2u)); + GPIOx->PUPDR = temp; + } + + /* In case of Alternate function mode selection */ + if ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF) + { + /* Check the Alternate function parameters */ + assert_param(IS_GPIO_AF_INSTANCE(GPIOx)); + assert_param(IS_GPIO_AF(GPIO_Init->Alternate)); + + /* Configure Alternate function mapped with the current IO */ + temp = GPIOx->AFR[position >> 3u]; + temp &= ~(0xFu << ((position & 0x07u) * 4u)); + temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u)); + GPIOx->AFR[position >> 3u] = temp; + } + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = GPIOx->MODER; + temp &= ~(GPIO_MODER_MODER0 << (position * 2u)); + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u)); + GPIOx->MODER = temp; + + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if ((GPIO_Init->Mode & EXTI_MODE) != 0x00u) + { + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + temp = SYSCFG->EXTICR[position >> 2u]; + temp &= ~(0x0FuL << (4u * (position & 0x03u))); + temp |= (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u))); + SYSCFG->EXTICR[position >> 2u] = temp; + + /* Clear Rising Falling edge configuration */ + temp = EXTI->RTSR; + temp &= ~(iocurrent); + if ((GPIO_Init->Mode & TRIGGER_RISING) != 0x00u) + { + temp |= iocurrent; + } + EXTI->RTSR = temp; + + temp = EXTI->FTSR; + temp &= ~(iocurrent); + if ((GPIO_Init->Mode & TRIGGER_FALLING) != 0x00u) + { + temp |= iocurrent; + } + EXTI->FTSR = temp; + + /* Clear EXTI line configuration */ + temp = EXTI->EMR; + temp &= ~(iocurrent); + if ((GPIO_Init->Mode & EXTI_EVT) != 0x00u) + { + temp |= iocurrent; + } + EXTI->EMR = temp; + + temp = EXTI->IMR; + temp &= ~(iocurrent); + if ((GPIO_Init->Mode & EXTI_IT) != 0x00u) + { + temp |= iocurrent; + } + EXTI->IMR = temp; + } + } + + position++; + } +} + +/** + * @brief De-initialize the GPIOx peripheral registers to their default reset values. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_DeInit(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin) +{ + uint32_t position = 0x00u; + uint32_t iocurrent; + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Configure the port pins */ + while ((GPIO_Pin >> position) != 0x00u) + { + /* Get current io position */ + iocurrent = (GPIO_Pin) & (1uL << position); + + if (iocurrent != 0x00u) + { + /*------------------------- EXTI Mode Configuration --------------------*/ + /* Clear the External Interrupt or Event for the current IO */ + + tmp = SYSCFG->EXTICR[position >> 2u]; + tmp &= (0x0FuL << (4u * (position & 0x03u))); + if (tmp == (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u)))) + { + /* Clear EXTI line configuration */ + EXTI->IMR &= ~((uint32_t)iocurrent); + EXTI->EMR &= ~((uint32_t)iocurrent); + + /* Clear Rising Falling edge configuration */ + EXTI->FTSR &= ~((uint32_t)iocurrent); + EXTI->RTSR &= ~((uint32_t)iocurrent); + + /* Configure the External Interrupt or event for the current IO */ + tmp = 0x0FuL << (4u * (position & 0x03u)); + SYSCFG->EXTICR[position >> 2u] &= ~tmp; + } + + /*------------------------- GPIO Mode Configuration --------------------*/ + /* Configure IO Direction in Input Floating Mode */ + GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (position * 2u)); + + /* Configure the default Alternate Function in current IO */ + GPIOx->AFR[position >> 3u] &= ~(0xFu << ((uint32_t)(position & 0x07u) * 4u)); + + /* Deactivate the Pull-up and Pull-down resistor for the current IO */ + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << (position * 2u)); + + /* Configure the default value IO Output Type */ + GPIOx->OTYPER &= ~(GPIO_OTYPER_OT_0 << position); + + /* Configure the default value for IO Speed */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2u)); + } + + position++; + } +} + +/** + * @} + */ + +/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions + * @brief GPIO Read, Write, Toggle, Lock and EXTI management functions. + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Read the specified input port pin. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the port bit to read. + * This parameter can be GPIO_PIN_x where x can be (0..15). + * @retval The input port pin value. + */ +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + GPIO_PinState bitstatus; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET) + { + bitstatus = GPIO_PIN_SET; + } + else + { + bitstatus = GPIO_PIN_RESET; + } + return bitstatus; +} + +/** + * @brief Set or clear the selected data port bit. + * @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic + * read/modify accesses. In this way, there is no risk of an IRQ occurring between the + * read and the modify access. + * + * @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @param PinState specifies the value to be written to the selected bit. + * This parameter can be one of the GPIO_PinState enum values: + * @arg GPIO_PIN_RESET: to clear the port pin + * @arg GPIO_PIN_SET: to set the port pin + * @retval None + */ +void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_PIN_ACTION(PinState)); + + if (PinState != GPIO_PIN_RESET) + { + GPIOx->BSRR = (uint32_t)GPIO_Pin; + } + else + { + GPIOx->BRR = (uint32_t)GPIO_Pin; + } +} + +/** + * @brief Toggle the specified GPIO pin. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the pin to be toggled. + * @retval None + */ +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + uint32_t odr; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* get current Output Data Register value */ + odr = GPIOx->ODR; + + /* Set selected pins that were at low level, and reset ones that were high */ + GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin); +} + +/** + * @brief Locks GPIO Pins configuration registers. + * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, + * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. + * @note The configuration of the locked GPIO pins can no longer be modified + * until the next reset. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the port bits to be locked. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + __IO uint32_t tmp = GPIO_LCKR_LCKK; + + /* Check the parameters */ + assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Apply lock key write sequence */ + SET_BIT(tmp, GPIO_Pin); + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Read LCKK register. This read is mandatory to complete key lock sequence */ + tmp = GPIOx->LCKR; + + /* read again in order to confirm lock is active */ + if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00u) + { + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Handle EXTI interrupt request. + * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line. + * @retval None + */ +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) +{ + /* EXTI line interrupt detected */ + if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u) + { + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); + HAL_GPIO_EXTI_Callback(GPIO_Pin); + } +} + +/** + * @brief EXTI line detection callback. + * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line. + * @retval None + */ +__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(GPIO_Pin); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_GPIO_EXTI_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* HAL_GPIO_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_gpio.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_gpio.h new file mode 100644 index 0000000000..a91f192a50 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_gpio.h @@ -0,0 +1,340 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_gpio.h + * @author MCD Application Team + * @brief Header file of GPIO HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_GPIO_H +#define __STM32F0xx_HAL_GPIO_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup GPIO + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** @defgroup GPIO_Exported_Types GPIO Exported Types + * @{ + */ + /** + * @brief GPIO Init structure definition + */ + typedef struct + { + uint32_t Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_mode */ + + uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected + pins. This parameter can be a value of @ref GPIO_pull */ + + uint32_t Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIO_speed */ + + uint32_t Alternate; /*!< Peripheral to be connected to the selected pins + This parameter can be a value of @ref + GPIOEx_Alternate_function_selection */ + } GPIO_InitTypeDef; + + /** + * @brief GPIO Bit SET and Bit RESET enumeration + */ + typedef enum + { + GPIO_PIN_RESET = 0U, + GPIO_PIN_SET + } GPIO_PinState; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Constants GPIO Exported Constants + * @{ + */ +/** @defgroup GPIO_pins GPIO pins + * @{ + */ +#define GPIO_PIN_0 ((uint16_t)0x0001U) /* Pin 0 selected */ +#define GPIO_PIN_1 ((uint16_t)0x0002U) /* Pin 1 selected */ +#define GPIO_PIN_2 ((uint16_t)0x0004U) /* Pin 2 selected */ +#define GPIO_PIN_3 ((uint16_t)0x0008U) /* Pin 3 selected */ +#define GPIO_PIN_4 ((uint16_t)0x0010U) /* Pin 4 selected */ +#define GPIO_PIN_5 ((uint16_t)0x0020U) /* Pin 5 selected */ +#define GPIO_PIN_6 ((uint16_t)0x0040U) /* Pin 6 selected */ +#define GPIO_PIN_7 ((uint16_t)0x0080U) /* Pin 7 selected */ +#define GPIO_PIN_8 ((uint16_t)0x0100U) /* Pin 8 selected */ +#define GPIO_PIN_9 ((uint16_t)0x0200U) /* Pin 9 selected */ +#define GPIO_PIN_10 ((uint16_t)0x0400U) /* Pin 10 selected */ +#define GPIO_PIN_11 ((uint16_t)0x0800U) /* Pin 11 selected */ +#define GPIO_PIN_12 ((uint16_t)0x1000U) /* Pin 12 selected */ +#define GPIO_PIN_13 ((uint16_t)0x2000U) /* Pin 13 selected */ +#define GPIO_PIN_14 ((uint16_t)0x4000U) /* Pin 14 selected */ +#define GPIO_PIN_15 ((uint16_t)0x8000U) /* Pin 15 selected */ +#define GPIO_PIN_All ((uint16_t)0xFFFFU) /* All pins selected */ + +#define GPIO_PIN_MASK (0x0000FFFFU) /* PIN mask for assert test */ +/** + * @} + */ + +/** @defgroup GPIO_mode GPIO mode + * @brief GPIO Configuration Mode + * Elements values convention: 0x00WX00YZ + * - W : EXTI trigger detection on 3 bits + * - X : EXTI mode (IT or Event) on 2 bits + * - Y : Output type (Push Pull or Open Drain) on 1 bit + * - Z : GPIO mode (Input, Output, Alternate or Analog) on 2 bits + * @{ + */ +#define GPIO_MODE_INPUT MODE_INPUT /*!< Input Floating Mode */ +#define GPIO_MODE_OUTPUT_PP \ + (MODE_OUTPUT | OUTPUT_PP) /*!< Output Push Pull Mode */ +#define GPIO_MODE_OUTPUT_OD \ + (MODE_OUTPUT | OUTPUT_OD) /*!< Output Open Drain Mode */ +#define GPIO_MODE_AF_PP \ + (MODE_AF | OUTPUT_PP) /*!< Alternate Function Push Pull Mode */ +#define GPIO_MODE_AF_OD \ + (MODE_AF | OUTPUT_OD) /*!< Alternate Function Open Drain Mode */ + +#define GPIO_MODE_ANALOG MODE_ANALOG /*!< Analog Mode */ + +#define GPIO_MODE_IT_RISING \ + (MODE_INPUT | EXTI_IT | \ + TRIGGER_RISING) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define GPIO_MODE_IT_FALLING \ + (MODE_INPUT | EXTI_IT | TRIGGER_FALLING) /*!< External Interrupt Mode with Falling \ + edge trigger detection */ +#define GPIO_MODE_IT_RISING_FALLING \ + (MODE_INPUT | EXTI_IT | TRIGGER_RISING | \ + TRIGGER_FALLING) /*!< External Interrupt Mode with Rising/Falling edge trigger \ + detection */ + +#define GPIO_MODE_EVT_RISING \ + (MODE_INPUT | EXTI_EVT | \ + TRIGGER_RISING) /*!< External Event Mode with Rising edge trigger detection */ +#define GPIO_MODE_EVT_FALLING \ + (MODE_INPUT | EXTI_EVT | \ + TRIGGER_FALLING) /*!< External Event Mode with Falling edge trigger detection */ +#define GPIO_MODE_EVT_RISING_FALLING \ + (MODE_INPUT | EXTI_EVT | TRIGGER_RISING | TRIGGER_FALLING) /*!< External Event Mode with Rising/Falling edge trigger detection *//** + * @} + */ + +/** @defgroup GPIO_speed GPIO speed + * @brief GPIO Output Maximum frequency + * @{ + */ +#define GPIO_SPEED_FREQ_LOW \ + (0x00000000U) /*!< range up to 2 MHz, please refer to the product datasheet */ +#define GPIO_SPEED_FREQ_MEDIUM \ + (0x00000001U) /*!< range 4 MHz to 10 MHz, please refer to the product datasheet */ +#define GPIO_SPEED_FREQ_HIGH \ + (0x00000003U) /*!< range 10 MHz to 50 MHz, please refer to the product datasheet */ + /** + * @} + */ + + /** @defgroup GPIO_pull GPIO pull + * @brief GPIO Pull-Up or Pull-Down Activation + * @{ + */ +#define GPIO_NOPULL (0x00000000U) /*!< No Pull-up or Pull-down activation */ +#define GPIO_PULLUP (0x00000001U) /*!< Pull-up activation */ +#define GPIO_PULLDOWN (0x00000002U) /*!< Pull-down activation */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** + * @brief Check whether the specified EXTI line flag is set or not. + * @param __EXTI_LINE__ specifies the EXTI line flag to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clear the EXTI's line pending flags. + * @param __EXTI_LINE__ specifies the EXTI lines flags to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + +/** + * @brief Check whether the specified EXTI line is asserted or not. + * @param __EXTI_LINE__ specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clear the EXTI's line pending bits. + * @param __EXTI_LINE__ specifies the EXTI lines to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + +/** + * @brief Generate a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__ specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__)) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPIO_Private_Constants GPIO Private Constants + * @{ + */ +#define GPIO_MODE_Pos 0U +#define GPIO_MODE (0x3UL << GPIO_MODE_Pos) +#define MODE_INPUT (0x0UL << GPIO_MODE_Pos) +#define MODE_OUTPUT (0x1UL << GPIO_MODE_Pos) +#define MODE_AF (0x2UL << GPIO_MODE_Pos) +#define MODE_ANALOG (0x3UL << GPIO_MODE_Pos) +#define OUTPUT_TYPE_Pos 4U +#define OUTPUT_TYPE (0x1UL << OUTPUT_TYPE_Pos) +#define OUTPUT_PP (0x0UL << OUTPUT_TYPE_Pos) +#define OUTPUT_OD (0x1UL << OUTPUT_TYPE_Pos) +#define EXTI_MODE_Pos 16U +#define EXTI_MODE (0x3UL << EXTI_MODE_Pos) +#define EXTI_IT (0x1UL << EXTI_MODE_Pos) +#define EXTI_EVT (0x2UL << EXTI_MODE_Pos) +#define TRIGGER_MODE_Pos 20U +#define TRIGGER_MODE (0x7UL << TRIGGER_MODE_Pos) +#define TRIGGER_RISING (0x1UL << TRIGGER_MODE_Pos) +#define TRIGGER_FALLING (0x2UL << TRIGGER_MODE_Pos) +/** + * @} + */ + +/** @addtogroup GPIO_Private_Macros GPIO Private Macros + * @{ + */ +#define IS_GPIO_PIN_ACTION(ACTION) \ + (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET)) + +#define IS_GPIO_PIN(__PIN__) \ + (((((uint32_t)__PIN__) & GPIO_PIN_MASK) != 0x00U) && \ + ((((uint32_t)__PIN__) & ~GPIO_PIN_MASK) == 0x00U)) + +#define IS_GPIO_MODE(__MODE__) \ + (((__MODE__) == GPIO_MODE_INPUT) || ((__MODE__) == GPIO_MODE_OUTPUT_PP) || \ + ((__MODE__) == GPIO_MODE_OUTPUT_OD) || ((__MODE__) == GPIO_MODE_AF_PP) || \ + ((__MODE__) == GPIO_MODE_AF_OD) || ((__MODE__) == GPIO_MODE_IT_RISING) || \ + ((__MODE__) == GPIO_MODE_IT_FALLING) || \ + ((__MODE__) == GPIO_MODE_IT_RISING_FALLING) || \ + ((__MODE__) == GPIO_MODE_EVT_RISING) || ((__MODE__) == GPIO_MODE_EVT_FALLING) || \ + ((__MODE__) == GPIO_MODE_EVT_RISING_FALLING) || ((__MODE__) == GPIO_MODE_ANALOG)) + +#define IS_GPIO_SPEED(__SPEED__) \ + (((__SPEED__) == GPIO_SPEED_FREQ_LOW) || ((__SPEED__) == GPIO_SPEED_FREQ_MEDIUM) || \ + ((__SPEED__) == GPIO_SPEED_FREQ_HIGH)) + +#define IS_GPIO_PULL(__PULL__) \ + (((__PULL__) == GPIO_NOPULL) || ((__PULL__) == GPIO_PULLUP) || \ + ((__PULL__) == GPIO_PULLDOWN)) +/** + * @} + */ + +/* Include GPIO HAL Extended module */ +#include "stm32f0xx_hal_gpio_ex.h" + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup GPIO_Exported_Functions GPIO Exported Functions + * @{ + */ + + /** @addtogroup GPIO_Exported_Functions_Group1 Initialization/de-initialization + * functions + * @brief Initialization and Configuration functions + * @{ + */ + + /* Initialization and de-initialization functions *****************************/ + void HAL_GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_Init); + void HAL_GPIO_DeInit(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin); + + /** + * @} + */ + + /** @addtogroup GPIO_Exported_Functions_Group2 IO operation functions + * @{ + */ + + /* IO operation functions *****************************************************/ + GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, + GPIO_PinState PinState); + void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); + void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); + void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_GPIO_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_gpio_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_gpio_ex.h new file mode 100644 index 0000000000..409d76fe16 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_gpio_ex.h @@ -0,0 +1,864 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_gpio_ex.h + * @author MCD Application Team + * @brief Header file of GPIO HAL Extension module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_GPIO_EX_H +#define __STM32F0xx_HAL_GPIO_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @defgroup GPIOEx GPIOEx + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /* Exported constants --------------------------------------------------------*/ + /** @defgroup GPIOEx_Exported_Constants GPIOEx Exported Constants + * @{ + */ + + /** @defgroup GPIOEx_Alternate_function_selection GPIOEx Alternate function selection + * @{ + */ + +#if defined(STM32F030x6) +/*------------------------- STM32F030x6---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F030x6 */ + +/*---------------------------------- STM32F030x8 + * -------------------------------------------*/ +#if defined(STM32F030x8) +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F030x8 */ + +#if defined(STM32F031x6) || defined(STM32F038xx) +/*--------------------------- STM32F031x6/STM32F038xx ---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_SWDAT ((uint8_t)0x00U) /*!< AF0: SWDAT Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F031x6 || STM32F038xx */ + +#if defined(STM32F051x8) || defined(STM32F058xx) +/*--------------------------- STM32F051x8/STM32F058xx---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +/* AF 7 */ +#define GPIO_AF7_COMP1 ((uint8_t)0x07U) /*!< AF7: COMP1 Alternate Function mapping */ +#define GPIO_AF7_COMP2 ((uint8_t)0x07U) /*!< AF7: COMP2 Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x07U) + +#endif /* STM32F051x8/STM32F058xx */ + +#if defined(STM32F071xB) +/*--------------------------- STM32F071xB ---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: AEVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00U) /*!< AF0: CRS Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF0_TIM1 ((uint8_t)0x00U) /*!< AF0: TIM1 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM16 ((uint8_t)0x00U) /*!< AF0: TIM16 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_TSC ((uint8_t)0x00U) /*!< AF0: TSC Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART2 ((uint8_t)0x00U) /*!< AF0: USART2 Alternate Function mapping */ +#define GPIO_AF0_USART3 ((uint8_t)0x00U) /*!< AF0: USART3 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART3 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_TSC ((uint8_t)0x01U) /*!< AF1: TSC Alternate Function mapping */ +#define GPIO_AF1_SPI1 ((uint8_t)0x01U) /*!< AF1: SPI1 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ +#define GPIO_AF4_CRS ((uint8_t)0x04U) /*!< AF4: CRS Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +/* AF 7 */ +#define GPIO_AF7_COMP1 ((uint8_t)0x07U) /*!< AF7: COMP1 Alternate Function mapping */ +#define GPIO_AF7_COMP2 ((uint8_t)0x07U) /*!< AF7: COMP2 Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x07U) + +#endif /* STM32F071xB */ + + +#if defined(STM32F091xC) || defined(STM32F098xx) +/*--------------------------- STM32F091xC || STM32F098xx ------------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00U) /*!< AF0: CRS Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF0_TIM1 ((uint8_t)0x00U) /*!< AF0: TIM1 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM16 ((uint8_t)0x00U) /*!< AF0: TIM16 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_TSC ((uint8_t)0x00U) /*!< AF0: TSC Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART2 ((uint8_t)0x00U) /*!< AF0: USART2 Alternate Function mapping */ +#define GPIO_AF0_USART3 ((uint8_t)0x00U) /*!< AF0: USART3 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ +#define GPIO_AF0_USART8 ((uint8_t)0x00U) /*!< AF0: USART8 Alternate Function mapping */ +#define GPIO_AF0_CAN ((uint8_t)0x00U) /*!< AF0: CAN Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART3 Alternate Function mapping */ +#define GPIO_AF1_USART4 ((uint8_t)0x01U) /*!< AF1: USART4 Alternate Function mapping */ +#define GPIO_AF1_USART5 ((uint8_t)0x01U) /*!< AF1: USART5 Alternate Function mapping */ +#define GPIO_AF1_USART6 ((uint8_t)0x01U) /*!< AF1: USART6 Alternate Function mapping */ +#define GPIO_AF1_USART7 ((uint8_t)0x01U) /*!< AF1: USART7 Alternate Function mapping */ +#define GPIO_AF1_USART8 ((uint8_t)0x01U) /*!< AF1: USART8 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_TSC ((uint8_t)0x01U) /*!< AF1: TSC Alternate Function mapping */ +#define GPIO_AF1_SPI1 ((uint8_t)0x01U) /*!< AF1: SPI1 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_USART5 ((uint8_t)0x02U) /*!< AF2: USART5 Alternate Function mapping */ +#define GPIO_AF2_USART6 ((uint8_t)0x02U) /*!< AF2: USART6 Alternate Function mapping */ +#define GPIO_AF2_USART7 ((uint8_t)0x02U) /*!< AF2: USART7 Alternate Function mapping */ +#define GPIO_AF2_USART8 ((uint8_t)0x02U) /*!< AF2: USART8 Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ +#define GPIO_AF4_CRS ((uint8_t)0x04U) /*!< AF4: CRS Alternate Function mapping */ +#define GPIO_AF4_CAN ((uint8_t)0x04U) /*!< AF4: CAN Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ +#define GPIO_AF4_USART5 ((uint8_t)0x04U) /*!< AF4: USART5 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ +#define GPIO_AF5_MCO ((uint8_t)0x05U) /*!< AF5: MCO Alternate Function mapping */ +#define GPIO_AF5_USART6 ((uint8_t)0x05U) /*!< AF5: USART6 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +/* AF 7 */ +#define GPIO_AF7_COMP1 ((uint8_t)0x07U) /*!< AF7: COMP1 Alternate Function mapping */ +#define GPIO_AF7_COMP2 ((uint8_t)0x07U) /*!< AF7: COMP2 Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x07U) + +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030xC) +/*--------------------------- STM32F030xC + * ----------------------------------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART3 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_USART5 ((uint8_t)0x02U) /*!< AF2: USART5 Alternate Function mapping */ +#define GPIO_AF2_USART6 ((uint8_t)0x02U) /*!< AF2: USART6 Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ +#define GPIO_AF4_USART5 ((uint8_t)0x04U) /*!< AF4: USART5 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ +#define GPIO_AF5_MCO ((uint8_t)0x05U) /*!< AF5: MCO Alternate Function mapping */ +#define GPIO_AF5_USART6 ((uint8_t)0x05U) /*!< AF5: USART6 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F030xC */ + +#if defined(STM32F072xB) || defined(STM32F078xx) +/*--------------------------- STM32F072xB/STM32F078xx ---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00U) /*!< AF0: CRS Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF0_TIM1 ((uint8_t)0x00U) /*!< AF0: TIM1 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM16 ((uint8_t)0x00U) /*!< AF0: TIM16 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_TSC ((uint8_t)0x00U) /*!< AF0: TSC Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART2 ((uint8_t)0x00U) /*!< AF0: USART2 Alternate Function mapping */ +#define GPIO_AF0_USART3 ((uint8_t)0x00U) /*!< AF0: USART3 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ +#define GPIO_AF0_CAN ((uint8_t)0x00U) /*!< AF0: CAN Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART3 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_TSC ((uint8_t)0x01U) /*!< AF1: TSC Alternate Function mapping */ +#define GPIO_AF1_SPI1 ((uint8_t)0x01U) /*!< AF1: SPI1 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_USB ((uint8_t)0x02U) /*!< AF2: USB Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ +#define GPIO_AF4_CRS ((uint8_t)0x04U) /*!< AF4: CRS Alternate Function mapping */ +#define GPIO_AF4_CAN ((uint8_t)0x04U) /*!< AF4: CAN Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +/* AF 7 */ +#define GPIO_AF7_COMP1 ((uint8_t)0x07U) /*!< AF7: COMP1 Alternate Function mapping */ +#define GPIO_AF7_COMP2 ((uint8_t)0x07U) /*!< AF7: COMP2 Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x07U) + +#endif /* STM32F072xB || STM32F078xx */ + +#if defined(STM32F070xB) +/*---------------------------------- STM32F070xB + * ---------------------------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART4 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_USB ((uint8_t)0x02U) /*!< AF2: USB Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) +/*--------------------------- STM32F042x6/STM32F048xx ---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00U) /*!< AF0: CRS Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_USB ((uint8_t)0x02U) /*!< AF2: USB Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_CAN ((uint8_t)0x04U) /*!< AF4: CAN Alternate Function mapping */ +#define GPIO_AF4_CRS ((uint8_t)0x04U) /*!< AF4: CRS Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_MCO ((uint8_t)0x05U) /*!< AF5: MCO Alternate Function mapping */ +#define GPIO_AF5_I2C1 ((uint8_t)0x05U) /*!< AF5: I2C1 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_USB ((uint8_t)0x05U) /*!< AF5: USB Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F042x6 || STM32F048xx */ + +#if defined(STM32F070x6) +/*--------------------------------------- STM32F070x6 + * ----------------------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT \ + ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_EVENTOUT \ + ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_EVENTOUT \ + ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_USB ((uint8_t)0x02U) /*!< AF2: USB Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT \ + ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_MCO ((uint8_t)0x05U) /*!< AF5: MCO Alternate Function mapping */ +#define GPIO_AF5_I2C1 ((uint8_t)0x05U) /*!< AF5: I2C1 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_USB ((uint8_t)0x05U) /*!< AF5: USB Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT \ + ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F070x6 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Macros GPIOEx Exported Macros + * @{ + */ + +/** @defgroup GPIOEx_Get_Port_Index GPIOEx_Get Port Index + * @{ + */ +#if defined(GPIOD) && defined(GPIOE) +#define GPIO_GET_INDEX(__GPIOx__) \ + (((__GPIOx__) == (GPIOA)) ? 0U \ + : ((__GPIOx__) == (GPIOB)) ? 1U \ + : ((__GPIOx__) == (GPIOC)) ? 2U \ + : ((__GPIOx__) == (GPIOD)) ? 3U \ + : ((__GPIOx__) == (GPIOE)) ? 4U \ + : 5U) +#endif + +#if defined(GPIOD) && !defined(GPIOE) +#define GPIO_GET_INDEX(__GPIOx__) \ + (((__GPIOx__) == (GPIOA)) ? 0U \ + : ((__GPIOx__) == (GPIOB)) ? 1U \ + : ((__GPIOx__) == (GPIOC)) ? 2U \ + : ((__GPIOx__) == (GPIOD)) ? 3U \ + : 5U) +#endif + +#if !defined(GPIOD) && defined(GPIOE) +#define GPIO_GET_INDEX(__GPIOx__) \ + (((__GPIOx__) == (GPIOA)) ? 0U \ + : ((__GPIOx__) == (GPIOB)) ? 1U \ + : ((__GPIOx__) == (GPIOC)) ? 2U \ + : ((__GPIOx__) == (GPIOE)) ? 4U \ + : 5U) +#endif + +#if !defined(GPIOD) && !defined(GPIOE) +#define GPIO_GET_INDEX(__GPIOx__) \ + (((__GPIOx__) == (GPIOA)) ? 0U \ + : ((__GPIOx__) == (GPIOB)) ? 1U \ + : ((__GPIOx__) == (GPIOC)) ? 2U \ + : 5U) +#endif + + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_GPIO_EX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_i2c.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_i2c.h new file mode 100644 index 0000000000..0649b857e0 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_i2c.h @@ -0,0 +1,890 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_i2c.h + * @author MCD Application Team + * @brief Header file of I2C HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_I2C_H +#define STM32F0xx_HAL_I2C_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup I2C + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /** @defgroup I2C_Exported_Types I2C Exported Types + * @{ + */ + + /** @defgroup I2C_Configuration_Structure_definition I2C Configuration Structure + * definition + * @brief I2C Configuration Structure definition + * @{ + */ + typedef struct + { + uint32_t Timing; /*!< Specifies the I2C_TIMINGR_register value. + This parameter calculated by referring to I2C initialization + section in Reference manual */ + + uint32_t OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is + selected. This parameter can be a value of @ref + I2C_ADDRESSING_MODE */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref + I2C_DUAL_ADDRESSING_MODE */ + + uint32_t + OwnAddress2; /*!< Specifies the second device own address if dual addressing + mode is selected This parameter can be a 7-bit address. */ + + uint32_t OwnAddress2Masks; /*!< Specifies the acknowledge mask address second + device own address if dual addressing mode is + selected. This parameter can be a value of @ref + I2C_OWN_ADDRESS2_MASKS */ + + uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. + This parameter can be a value of @ref + I2C_GENERAL_CALL_ADDRESSING_MODE */ + + uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref + I2C_NOSTRETCH_MODE */ + + } I2C_InitTypeDef; + + /** + * @} + */ + + /** @defgroup HAL_state_structure_definition HAL state structure definition + * @brief HAL State structure definition + * @note HAL I2C State value coding follow below described bitmap :\n + * b7-b6 Error information\n + * 00 : No Error\n + * 01 : Abort (Abort user request on going)\n + * 10 : Timeout\n + * 11 : Error\n + * b5 Peripheral initialization status\n + * 0 : Reset (peripheral not initialized)\n + * 1 : Init done (peripheral initialized and ready to use. HAL I2C Init + * function called)\n b4 (not used)\n x : Should be set to 0\n b3\n 0 : Ready or + * Busy (No Listen mode ongoing)\n 1 : Listen (peripheral in Address Listen Mode)\n + * b2 Intrinsic process state\n + * 0 : Ready\n + * 1 : Busy (peripheral busy with some configuration or internal + * operations)\n b1 Rx state\n 0 : Ready (no Rx operation ongoing)\n 1 : Busy + * (Rx operation ongoing)\n b0 Tx state\n 0 : Ready (no Tx operation ongoing)\n + * 1 : Busy (Tx operation ongoing) + * @{ + */ + typedef enum + { + HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ + HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */ + HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */ + HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ + HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ + HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */ + HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data + Transmission process is ongoing */ + HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception + process is ongoing */ + HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ + HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ + HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ + + } HAL_I2C_StateTypeDef; + + /** + * @} + */ + + /** @defgroup HAL_mode_structure_definition HAL mode structure definition + * @brief HAL Mode structure definition + * @note HAL I2C Mode value coding follow below described bitmap :\n + * b7 (not used)\n + * x : Should be set to 0\n + * b6\n + * 0 : None\n + * 1 : Memory (HAL I2C communication is in Memory Mode)\n + * b5\n + * 0 : None\n + * 1 : Slave (HAL I2C communication is in Slave Mode)\n + * b4\n + * 0 : None\n + * 1 : Master (HAL I2C communication is in Master Mode)\n + * b3-b2-b1-b0 (not used)\n + * xxxx : Should be set to 0000 + * @{ + */ + typedef enum + { + HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */ + HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ + HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ + HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ + + } HAL_I2C_ModeTypeDef; + +/** + * @} + */ + +/** @defgroup I2C_Error_Code_definition I2C Error Code definition + * @brief I2C Error Code definition + * @{ + */ +#define HAL_I2C_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_I2C_ERROR_BERR (0x00000001U) /*!< BERR error */ +#define HAL_I2C_ERROR_ARLO (0x00000002U) /*!< ARLO error */ +#define HAL_I2C_ERROR_AF (0x00000004U) /*!< ACKF error */ +#define HAL_I2C_ERROR_OVR (0x00000008U) /*!< OVR error */ +#define HAL_I2C_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ +#define HAL_I2C_ERROR_TIMEOUT (0x00000020U) /*!< Timeout error */ +#define HAL_I2C_ERROR_SIZE (0x00000040U) /*!< Size Management error */ +#define HAL_I2C_ERROR_DMA_PARAM (0x00000080U) /*!< DMA Parameter Error */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +#define HAL_I2C_ERROR_INVALID_CALLBACK (0x00000100U) /*!< Invalid Callback error */ +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +#define HAL_I2C_ERROR_INVALID_PARAM (0x00000200U) /*!< Invalid Parameters error */ + /** + * @} + */ + + /** @defgroup I2C_handle_Structure_definition I2C handle Structure definition + * @brief I2C handle Structure definition + * @{ + */ + typedef struct __I2C_HandleTypeDef + { + I2C_TypeDef *Instance; /*!< I2C registers base address */ + + I2C_InitTypeDef Init; /*!< I2C communication parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ + + uint16_t XferSize; /*!< I2C transfer size */ + + __IO uint16_t XferCount; /*!< I2C transfer counter */ + + __IO uint32_t XferOptions; /*!< I2C sequantial transfer options, this parameter + can be a value of @ref I2C_XFEROPTIONS */ + + __IO uint32_t PreviousState; /*!< I2C communication Previous state */ + + HAL_StatusTypeDef (*XferISR)(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, + uint32_t ITSources); + /*!< I2C transfer IRQ handler function pointer */ + + DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ + + + HAL_LockTypeDef Lock; /*!< I2C locking object */ + + __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ + + __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */ + + __IO uint32_t ErrorCode; /*!< I2C Error code */ + + __IO uint32_t AddrEventCount; /*!< I2C Address Event counter */ + + __IO uint32_t Devaddress; /*!< I2C Target device address */ + + __IO uint32_t Memaddress; /*!< I2C Target memory address */ + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + void (*MasterTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Master Tx Transfer completed callback */ + void (*MasterRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Master Rx Transfer completed callback */ + void (*SlaveTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Slave Tx Transfer completed callback */ + void (*SlaveRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Slave Rx Transfer completed callback */ + void (*ListenCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Listen Complete callback */ + void (*MemTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Memory Tx Transfer completed callback */ + void (*MemRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Memory Rx Transfer completed callback */ + void (*ErrorCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Error callback */ + void (*AbortCpltCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Abort callback */ + + void (*AddrCallback)(struct __I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, + uint16_t AddrMatchCode); + /*!< I2C Slave Address Match callback */ + + void (*MspInitCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Msp Init callback */ + void (*MspDeInitCallback)(struct __I2C_HandleTypeDef *hi2c); + /*!< I2C Msp DeInit callback */ + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } I2C_HandleTypeDef; + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + /** + * @brief HAL I2C Callback ID enumeration definition + */ + typedef enum + { + HAL_I2C_MASTER_TX_COMPLETE_CB_ID = + 0x00U, /*!< I2C Master Tx Transfer completed callback ID */ + HAL_I2C_MASTER_RX_COMPLETE_CB_ID = + 0x01U, /*!< I2C Master Rx Transfer completed callback ID */ + HAL_I2C_SLAVE_TX_COMPLETE_CB_ID = + 0x02U, /*!< I2C Slave Tx Transfer completed callback ID */ + HAL_I2C_SLAVE_RX_COMPLETE_CB_ID = + 0x03U, /*!< I2C Slave Rx Transfer completed callback ID */ + HAL_I2C_LISTEN_COMPLETE_CB_ID = 0x04U, /*!< I2C Listen Complete callback ID */ + HAL_I2C_MEM_TX_COMPLETE_CB_ID = 0x05U, /*!< I2C Memory Tx Transfer callback ID */ + HAL_I2C_MEM_RX_COMPLETE_CB_ID = + 0x06U, /*!< I2C Memory Rx Transfer completed callback ID */ + HAL_I2C_ERROR_CB_ID = 0x07U, /*!< I2C Error callback ID */ + HAL_I2C_ABORT_CB_ID = 0x08U, /*!< I2C Abort callback ID */ + + HAL_I2C_MSPINIT_CB_ID = 0x09U, /*!< I2C Msp Init callback ID */ + HAL_I2C_MSPDEINIT_CB_ID = 0x0AU /*!< I2C Msp DeInit callback ID */ + + } HAL_I2C_CallbackIDTypeDef; + + /** + * @brief HAL I2C Callback pointer definition + */ + typedef void (*pI2C_CallbackTypeDef)(I2C_HandleTypeDef *hi2c); + /*!< pointer to an I2C callback function */ + typedef void (*pI2C_AddrCallbackTypeDef)(I2C_HandleTypeDef *hi2c, + uint8_t TransferDirection, + uint16_t AddrMatchCode); + /*!< pointer to an I2C Address Match callback function */ + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup I2C_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_XFEROPTIONS I2C Sequential Transfer Options + * @{ + */ +#define I2C_FIRST_FRAME ((uint32_t)I2C_SOFTEND_MODE) +#define I2C_FIRST_AND_NEXT_FRAME ((uint32_t)(I2C_RELOAD_MODE | I2C_SOFTEND_MODE)) +#define I2C_NEXT_FRAME ((uint32_t)(I2C_RELOAD_MODE | I2C_SOFTEND_MODE)) +#define I2C_FIRST_AND_LAST_FRAME ((uint32_t)I2C_AUTOEND_MODE) +#define I2C_LAST_FRAME ((uint32_t)I2C_AUTOEND_MODE) +#define I2C_LAST_FRAME_NO_STOP ((uint32_t)I2C_SOFTEND_MODE) + +/* List of XferOptions in usage of : + * 1- Restart condition in all use cases (direction change or not) + */ +#define I2C_OTHER_FRAME (0x000000AAU) +#define I2C_OTHER_AND_LAST_FRAME (0x0000AA00U) +/** + * @} + */ + +/** @defgroup I2C_ADDRESSING_MODE I2C Addressing Mode + * @{ + */ +#define I2C_ADDRESSINGMODE_7BIT (0x00000001U) +#define I2C_ADDRESSINGMODE_10BIT (0x00000002U) +/** + * @} + */ + +/** @defgroup I2C_DUAL_ADDRESSING_MODE I2C Dual Addressing Mode + * @{ + */ +#define I2C_DUALADDRESS_DISABLE (0x00000000U) +#define I2C_DUALADDRESS_ENABLE I2C_OAR2_OA2EN +/** + * @} + */ + +/** @defgroup I2C_OWN_ADDRESS2_MASKS I2C Own Address2 Masks + * @{ + */ +#define I2C_OA2_NOMASK ((uint8_t)0x00U) +#define I2C_OA2_MASK01 ((uint8_t)0x01U) +#define I2C_OA2_MASK02 ((uint8_t)0x02U) +#define I2C_OA2_MASK03 ((uint8_t)0x03U) +#define I2C_OA2_MASK04 ((uint8_t)0x04U) +#define I2C_OA2_MASK05 ((uint8_t)0x05U) +#define I2C_OA2_MASK06 ((uint8_t)0x06U) +#define I2C_OA2_MASK07 ((uint8_t)0x07U) +/** + * @} + */ + +/** @defgroup I2C_GENERAL_CALL_ADDRESSING_MODE I2C General Call Addressing Mode + * @{ + */ +#define I2C_GENERALCALL_DISABLE (0x00000000U) +#define I2C_GENERALCALL_ENABLE I2C_CR1_GCEN +/** + * @} + */ + +/** @defgroup I2C_NOSTRETCH_MODE I2C No-Stretch Mode + * @{ + */ +#define I2C_NOSTRETCH_DISABLE (0x00000000U) +#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH +/** + * @} + */ + +/** @defgroup I2C_MEMORY_ADDRESS_SIZE I2C Memory Address Size + * @{ + */ +#define I2C_MEMADD_SIZE_8BIT (0x00000001U) +#define I2C_MEMADD_SIZE_16BIT (0x00000002U) +/** + * @} + */ + +/** @defgroup I2C_XFERDIRECTION I2C Transfer Direction Master Point of View + * @{ + */ +#define I2C_DIRECTION_TRANSMIT (0x00000000U) +#define I2C_DIRECTION_RECEIVE (0x00000001U) +/** + * @} + */ + +/** @defgroup I2C_RELOAD_END_MODE I2C Reload End Mode + * @{ + */ +#define I2C_RELOAD_MODE I2C_CR2_RELOAD +#define I2C_AUTOEND_MODE I2C_CR2_AUTOEND +#define I2C_SOFTEND_MODE (0x00000000U) +/** + * @} + */ + +/** @defgroup I2C_START_STOP_MODE I2C Start or Stop Mode + * @{ + */ +#define I2C_NO_STARTSTOP (0x00000000U) +#define I2C_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP) +#define I2C_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) +#define I2C_GENERATE_START_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) +/** + * @} + */ + +/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration + * definition + * @brief I2C Interrupt definition + * Elements values convention: 0xXXXXXXXX + * - XXXXXXXX : Interrupt control mask + * @{ + */ +#define I2C_IT_ERRI I2C_CR1_ERRIE +#define I2C_IT_TCI I2C_CR1_TCIE +#define I2C_IT_STOPI I2C_CR1_STOPIE +#define I2C_IT_NACKI I2C_CR1_NACKIE +#define I2C_IT_ADDRI I2C_CR1_ADDRIE +#define I2C_IT_RXI I2C_CR1_RXIE +#define I2C_IT_TXI I2C_CR1_TXIE +/** + * @} + */ + +/** @defgroup I2C_Flag_definition I2C Flag definition + * @{ + */ +#define I2C_FLAG_TXE I2C_ISR_TXE +#define I2C_FLAG_TXIS I2C_ISR_TXIS +#define I2C_FLAG_RXNE I2C_ISR_RXNE +#define I2C_FLAG_ADDR I2C_ISR_ADDR +#define I2C_FLAG_AF I2C_ISR_NACKF +#define I2C_FLAG_STOPF I2C_ISR_STOPF +#define I2C_FLAG_TC I2C_ISR_TC +#define I2C_FLAG_TCR I2C_ISR_TCR +#define I2C_FLAG_BERR I2C_ISR_BERR +#define I2C_FLAG_ARLO I2C_ISR_ARLO +#define I2C_FLAG_OVR I2C_ISR_OVR +#define I2C_FLAG_PECERR I2C_ISR_PECERR +#define I2C_FLAG_TIMEOUT I2C_ISR_TIMEOUT +#define I2C_FLAG_ALERT I2C_ISR_ALERT +#define I2C_FLAG_BUSY I2C_ISR_BUSY +#define I2C_FLAG_DIR I2C_ISR_DIR +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup I2C_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @brief Reset I2C handle state. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) \ + do \ + { \ + (__HANDLE__)->State = HAL_I2C_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while (0) +#else +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) \ + ((__HANDLE__)->State = HAL_I2C_STATE_RESET) +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + +/** @brief Enable the specified I2C interrupt. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval None + */ +#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->CR1 |= (__INTERRUPT__)) + +/** @brief Disable the specified I2C interrupt. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval None + */ +#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__))) + +/** @brief Check whether the specified I2C interrupt source is enabled or not. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the I2C interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + ((((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified I2C flag is set or not. + * @param __HANDLE__ specifies the I2C Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref I2C_FLAG_TXE Transmit data register empty + * @arg @ref I2C_FLAG_TXIS Transmit interrupt status + * @arg @ref I2C_FLAG_RXNE Receive data register not empty + * @arg @ref I2C_FLAG_ADDR Address matched (slave mode) + * @arg @ref I2C_FLAG_AF Acknowledge failure received flag + * @arg @ref I2C_FLAG_STOPF STOP detection flag + * @arg @ref I2C_FLAG_TC Transfer complete (master mode) + * @arg @ref I2C_FLAG_TCR Transfer complete reload + * @arg @ref I2C_FLAG_BERR Bus error + * @arg @ref I2C_FLAG_ARLO Arbitration lost + * @arg @ref I2C_FLAG_OVR Overrun/Underrun + * @arg @ref I2C_FLAG_PECERR PEC error in reception + * @arg @ref I2C_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref I2C_FLAG_ALERT SMBus alert + * @arg @ref I2C_FLAG_BUSY Bus busy + * @arg @ref I2C_FLAG_DIR Transfer direction (slave mode) + * + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define I2C_FLAG_MASK (0x0001FFFFU) +#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) \ + (((((__HANDLE__)->Instance->ISR) & (__FLAG__)) == (__FLAG__)) ? SET : RESET) + +/** @brief Clear the I2C pending flags which are cleared by writing 1 in a specific bit. + * @param __HANDLE__ specifies the I2C Handle. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg @ref I2C_FLAG_TXE Transmit data register empty + * @arg @ref I2C_FLAG_ADDR Address matched (slave mode) + * @arg @ref I2C_FLAG_AF Acknowledge failure received flag + * @arg @ref I2C_FLAG_STOPF STOP detection flag + * @arg @ref I2C_FLAG_BERR Bus error + * @arg @ref I2C_FLAG_ARLO Arbitration lost + * @arg @ref I2C_FLAG_OVR Overrun/Underrun + * @arg @ref I2C_FLAG_PECERR PEC error in reception + * @arg @ref I2C_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref I2C_FLAG_ALERT SMBus alert + * + * @retval None + */ +#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + (((__FLAG__) == I2C_FLAG_TXE) ? ((__HANDLE__)->Instance->ISR |= (__FLAG__)) \ + : ((__HANDLE__)->Instance->ICR = (__FLAG__))) + +/** @brief Enable the specified I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) + +/** @brief Disable the specified I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) + +/** @brief Generate a Non-Acknowledge I2C peripheral in Slave mode. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_GENERATE_NACK(__HANDLE__) \ + (SET_BIT((__HANDLE__)->Instance->CR2, I2C_CR2_NACK)) +/** + * @} + */ + +/* Include I2C HAL Extended module */ +#include "stm32f0xx_hal_i2c_ex.h" + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup I2C_Exported_Functions + * @{ + */ + + /** @addtogroup I2C_Exported_Functions_Group1 Initialization and de-initialization + * functions + * @{ + */ + /* Initialization and de-initialization functions******************************/ + HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); + HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c); + void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); + void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, + HAL_I2C_CallbackIDTypeDef CallbackID, + pI2C_CallbackTypeDef pCallback); + HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, + HAL_I2C_CallbackIDTypeDef CallbackID); + + HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, + pI2C_AddrCallbackTypeDef pCallback); + HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + /** + * @} + */ + + /** @addtogroup I2C_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ + /* IO operation functions ****************************************************/ + /******* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t Timeout); + HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint8_t *pData, uint16_t Size, + uint32_t Timeout); + HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, + uint16_t Size, uint32_t Timeout); + HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, + uint16_t Size, uint32_t Timeout); + HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, + uint8_t *pData, uint16_t Size, uint32_t Timeout); + HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, + uint8_t *pData, uint16_t Size, uint32_t Timeout); + HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint32_t Trials, uint32_t Timeout); + + /******* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, + uint8_t *pData, uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, + uint8_t *pData, uint16_t Size); + + HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions); + HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions); + HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, + uint8_t *pData, uint16_t Size, + uint32_t XferOptions); + HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, + uint8_t *pData, uint16_t Size, + uint32_t XferOptions); + HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); + HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); + HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress); + + /******* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, + uint8_t *pData, uint16_t Size); + HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, + uint16_t MemAddress, uint16_t MemAddSize, + uint8_t *pData, uint16_t Size); + + HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size, + uint32_t XferOptions); + HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, + uint16_t DevAddress, uint8_t *pData, + uint16_t Size, uint32_t XferOptions); + HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, + uint8_t *pData, uint16_t Size, + uint32_t XferOptions); + HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, + uint8_t *pData, uint16_t Size, + uint32_t XferOptions); + /** + * @} + */ + + /** @addtogroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ + /******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) + */ + void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); + void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); + void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); + void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); + void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); + void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); + void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, + uint16_t AddrMatchCode); + void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); + void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); + void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); + void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); + void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); + /** + * @} + */ + + /** @addtogroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error + * functions + * @{ + */ + /* Peripheral State, Mode and Error functions *********************************/ + HAL_I2C_StateTypeDef HAL_I2C_GetState(const I2C_HandleTypeDef *hi2c); + HAL_I2C_ModeTypeDef HAL_I2C_GetMode(const I2C_HandleTypeDef *hi2c); + uint32_t HAL_I2C_GetError(const I2C_HandleTypeDef *hi2c); + + /** + * @} + */ + + /** + * @} + */ + + /* Private constants ---------------------------------------------------------*/ + /** @defgroup I2C_Private_Constants I2C Private Constants + * @{ + */ + + /** + * @} + */ + + /* Private macros ------------------------------------------------------------*/ + /** @defgroup I2C_Private_Macro I2C Private Macros + * @{ + */ + +#define IS_I2C_ADDRESSING_MODE(MODE) \ + (((MODE) == I2C_ADDRESSINGMODE_7BIT) || ((MODE) == I2C_ADDRESSINGMODE_10BIT)) + +#define IS_I2C_DUAL_ADDRESS(ADDRESS) \ + (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) + +#define IS_I2C_OWN_ADDRESS2_MASK(MASK) \ + (((MASK) == I2C_OA2_NOMASK) || ((MASK) == I2C_OA2_MASK01) || \ + ((MASK) == I2C_OA2_MASK02) || ((MASK) == I2C_OA2_MASK03) || \ + ((MASK) == I2C_OA2_MASK04) || ((MASK) == I2C_OA2_MASK05) || \ + ((MASK) == I2C_OA2_MASK06) || ((MASK) == I2C_OA2_MASK07)) + +#define IS_I2C_GENERAL_CALL(CALL) \ + (((CALL) == I2C_GENERALCALL_DISABLE) || ((CALL) == I2C_GENERALCALL_ENABLE)) + +#define IS_I2C_NO_STRETCH(STRETCH) \ + (((STRETCH) == I2C_NOSTRETCH_DISABLE) || ((STRETCH) == I2C_NOSTRETCH_ENABLE)) + +#define IS_I2C_MEMADD_SIZE(SIZE) \ + (((SIZE) == I2C_MEMADD_SIZE_8BIT) || ((SIZE) == I2C_MEMADD_SIZE_16BIT)) + +#define IS_TRANSFER_MODE(MODE) \ + (((MODE) == I2C_RELOAD_MODE) || ((MODE) == I2C_AUTOEND_MODE) || \ + ((MODE) == I2C_SOFTEND_MODE)) + +#define IS_TRANSFER_REQUEST(REQUEST) \ + (((REQUEST) == I2C_GENERATE_STOP) || ((REQUEST) == I2C_GENERATE_START_READ) || \ + ((REQUEST) == I2C_GENERATE_START_WRITE) || ((REQUEST) == I2C_NO_STARTSTOP)) + +#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) \ + (((REQUEST) == I2C_FIRST_FRAME) || ((REQUEST) == I2C_FIRST_AND_NEXT_FRAME) || \ + ((REQUEST) == I2C_NEXT_FRAME) || ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME) || ((REQUEST) == I2C_LAST_FRAME_NO_STOP) || \ + IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST)) + +#define IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST) \ + (((REQUEST) == I2C_OTHER_FRAME) || ((REQUEST) == I2C_OTHER_AND_LAST_FRAME)) + +#define I2C_RESET_CR2(__HANDLE__) \ + ((__HANDLE__)->Instance->CR2 &= \ + (uint32_t) ~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | \ + I2C_CR2_RELOAD | I2C_CR2_RD_WRN))) + +#define I2C_GET_ADDR_MATCH(__HANDLE__) \ + ((uint16_t)(((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) >> 16U)) +#define I2C_GET_DIR(__HANDLE__) \ + ((uint8_t)(((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) >> 16U)) +#define I2C_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND) +#define I2C_GET_OWN_ADDRESS1(__HANDLE__) \ + ((uint16_t)((__HANDLE__)->Instance->OAR1 & I2C_OAR1_OA1)) +#define I2C_GET_OWN_ADDRESS2(__HANDLE__) \ + ((uint16_t)((__HANDLE__)->Instance->OAR2 & I2C_OAR2_OA2)) + +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x000003FFU) +#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU) + +#define I2C_MEM_ADD_MSB(__ADDRESS__) \ + ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U))) +#define I2C_MEM_ADD_LSB(__ADDRESS__) \ + ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU)))) + +#define I2C_GENERATE_START(__ADDMODE__, __ADDRESS__) \ + (((__ADDMODE__) == I2C_ADDRESSINGMODE_7BIT) \ + ? (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_START) | \ + (I2C_CR2_AUTOEND)) & \ + (~I2C_CR2_RD_WRN)) \ + : (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_ADD10) | \ + (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & \ + (~I2C_CR2_RD_WRN))) + +#define I2C_CHECK_FLAG(__ISR__, __FLAG__) \ + ((((__ISR__) & ((__FLAG__)&I2C_FLAG_MASK)) == ((__FLAG__)&I2C_FLAG_MASK)) ? SET \ + : RESET) +#define I2C_CHECK_IT_SOURCE(__CR1__, __IT__) \ + ((((__CR1__) & (__IT__)) == (__IT__)) ? SET : RESET) + /** + * @} + */ + + /* Private Functions ---------------------------------------------------------*/ + /** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ + /* Private functions are defined in stm32f0xx_hal_i2c.c file */ + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32F0xx_HAL_I2C_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_i2c_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_i2c_ex.h new file mode 100644 index 0000000000..0877c5cc1f --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_i2c_ex.h @@ -0,0 +1,208 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_i2c_ex.h + * @author MCD Application Team + * @brief Header file of I2C HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_I2C_EX_H +#define STM32F0xx_HAL_I2C_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2CEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup I2CEx_Exported_Constants I2C Extended Exported Constants + * @{ + */ + +/** @defgroup I2CEx_Analog_Filter I2C Extended Analog Filter + * @{ + */ +#define I2C_ANALOGFILTER_ENABLE 0x00000000U +#define I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF +/** + * @} + */ + +/** @defgroup I2CEx_FastModePlus I2C Extended Fast Mode Plus + * @{ + */ +#define I2C_FMP_NOT_SUPPORTED 0xAAAA0000U /*!< Fast Mode Plus not supported */ +#if defined(SYSCFG_CFGR1_I2C_FMP_PA9) +#define I2C_FASTMODEPLUS_PA9 \ + SYSCFG_CFGR1_I2C_FMP_PA9 /*!< Enable Fast Mode Plus on PA9 */ +#define I2C_FASTMODEPLUS_PA10 \ + SYSCFG_CFGR1_I2C_FMP_PA10 /*!< Enable Fast Mode Plus on PA10 */ +#else +#define I2C_FASTMODEPLUS_PA9 \ + (uint32_t)(0x00000001U | \ + I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus PA9 not supported */ +#define I2C_FASTMODEPLUS_PA10 \ + (uint32_t)(0x00000002U | \ + I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus PA10 not supported */ +#endif /* SYSCFG_CFGR1_I2C_FMP_PA9 */ +#define I2C_FASTMODEPLUS_PB6 \ + SYSCFG_CFGR1_I2C_FMP_PB6 /*!< Enable Fast Mode Plus on PB6 */ +#define I2C_FASTMODEPLUS_PB7 \ + SYSCFG_CFGR1_I2C_FMP_PB7 /*!< Enable Fast Mode Plus on PB7 */ +#define I2C_FASTMODEPLUS_PB8 \ + SYSCFG_CFGR1_I2C_FMP_PB8 /*!< Enable Fast Mode Plus on PB8 */ +#define I2C_FASTMODEPLUS_PB9 \ + SYSCFG_CFGR1_I2C_FMP_PB9 /*!< Enable Fast Mode Plus on PB9 */ +#if defined(SYSCFG_CFGR1_I2C_FMP_I2C1) +#define I2C_FASTMODEPLUS_I2C1 \ + SYSCFG_CFGR1_I2C_FMP_I2C1 /*!< Enable Fast Mode Plus on I2C1 pins */ +#else +#define I2C_FASTMODEPLUS_I2C1 \ + (uint32_t)(0x00000100U | \ + I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus I2C1 not supported */ +#endif /* SYSCFG_CFGR1_I2C_FMP_I2C1 */ +#if defined(SYSCFG_CFGR1_I2C_FMP_I2C2) +#define I2C_FASTMODEPLUS_I2C2 \ + SYSCFG_CFGR1_I2C_FMP_I2C2 /*!< Enable Fast Mode Plus on I2C2 pins */ +#else +#define I2C_FASTMODEPLUS_I2C2 \ + (uint32_t)(0x00000200U | \ + I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus I2C2 not supported */ +#endif /* SYSCFG_CFGR1_I2C_FMP_I2C2 */ + /** + * @} + */ + + /** + * @} + */ + + /* Exported macro ------------------------------------------------------------*/ + /* Exported functions --------------------------------------------------------*/ + + /** @addtogroup I2CEx_Exported_Functions I2C Extended Exported Functions + * @{ + */ + + /** @addtogroup I2CEx_Exported_Functions_Group1 Extended features functions + * @brief Extended features functions + * @{ + */ + + /** @addtogroup I2CEx_Exported_Functions_Group1 Filter Mode Functions + * @{ + */ + HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, + uint32_t AnalogFilter); + HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, + uint32_t DigitalFilter); +/** + * @} + */ +#if defined(I2C_CR1_WUPEN) + + /** @addtogroup I2CEx_Exported_Functions_Group2 WakeUp Mode Functions + * @{ + */ + HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c); + HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c); +/** + * @} + */ +#endif /* I2C_CR1_WUPEN */ + + /** @addtogroup I2CEx_Exported_Functions_Group3 Fast Mode Plus Functions + * @{ + */ + void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus); + void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus); +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Constants I2C Extended Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Macro I2C Extended Private Macros + * @{ + */ +#define IS_I2C_ANALOG_FILTER(FILTER) \ + (((FILTER) == I2C_ANALOGFILTER_ENABLE) || ((FILTER) == I2C_ANALOGFILTER_DISABLE)) + +#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) + +#define IS_I2C_FASTMODEPLUS(__CONFIG__) \ + ((((__CONFIG__)&I2C_FMP_NOT_SUPPORTED) != I2C_FMP_NOT_SUPPORTED) && \ + ((((__CONFIG__) & (I2C_FASTMODEPLUS_PA9)) == I2C_FASTMODEPLUS_PA9) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PA10)) == I2C_FASTMODEPLUS_PA10) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PB6)) == I2C_FASTMODEPLUS_PB6) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PB7)) == I2C_FASTMODEPLUS_PB7) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PB8)) == I2C_FASTMODEPLUS_PB8) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PB9)) == I2C_FASTMODEPLUS_PB9) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_I2C1)) == I2C_FASTMODEPLUS_I2C1) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_I2C2)) == I2C_FASTMODEPLUS_I2C2))) + /** + * @} + */ + + /* Private Functions ---------------------------------------------------------*/ + /** @defgroup I2CEx_Private_Functions I2C Extended Private Functions + * @{ + */ + /* Private functions are defined in stm32f0xx_hal_i2c_ex.c file */ + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_I2C_EX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_pwr.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_pwr.h new file mode 100644 index 0000000000..0822174121 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_pwr.h @@ -0,0 +1,188 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pwr.h + * @author MCD Application Team + * @brief Header file of PWR HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_PWR_H +#define __STM32F0xx_HAL_PWR_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup PWR PWR + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Constants PWR Exported Constants + * @{ + */ + +/** @defgroup PWR_Regulator_state_in_STOP_mode PWR Regulator state in STOP mode + * @{ + */ +#define PWR_MAINREGULATOR_ON (0x00000000U) +#define PWR_LOWPOWERREGULATOR_ON PWR_CR_LPDS + +#define IS_PWR_REGULATOR(REGULATOR) \ + (((REGULATOR) == PWR_MAINREGULATOR_ON) || ((REGULATOR) == PWR_LOWPOWERREGULATOR_ON)) +/** + * @} + */ + +/** @defgroup PWR_SLEEP_mode_entry PWR SLEEP mode entry + * @{ + */ +#define PWR_SLEEPENTRY_WFI ((uint8_t)0x01U) +#define PWR_SLEEPENTRY_WFE ((uint8_t)0x02U) +#define IS_PWR_SLEEP_ENTRY(ENTRY) \ + (((ENTRY) == PWR_SLEEPENTRY_WFI) || ((ENTRY) == PWR_SLEEPENTRY_WFE)) +/** + * @} + */ + +/** @defgroup PWR_STOP_mode_entry PWR STOP mode entry + * @{ + */ +#define PWR_STOPENTRY_WFI ((uint8_t)0x01U) +#define PWR_STOPENTRY_WFE ((uint8_t)0x02U) +#define IS_PWR_STOP_ENTRY(ENTRY) \ + (((ENTRY) == PWR_STOPENTRY_WFI) || ((ENTRY) == PWR_STOPENTRY_WFE)) +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWR_Exported_Macro PWR Exported Macro + * @{ + */ + +/** @brief Check PWR flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event + * was received from the WKUP pin or from the RTC alarm (Alarm A), + * RTC Tamper event, RTC TimeStamp event or RTC Wakeup. + * An additional wakeup event is detected if the WKUP pin is enabled + * (by setting the EWUP bit) when the WKUP pin level is already high. + * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was + * resumed from StandBy mode. + * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled + * by the HAL_PWR_EnablePVD() function. The PVD is stopped by Standby + * mode For this reason, this bit is equal to 0 after Standby or reset until the PVDE bit + * is set. Warning: this Flag is not available on STM32F030x8 products + * @arg PWR_FLAG_VREFINTRDY: This flag indicates that the internal reference + * voltage VREFINT is ready. + * Warning: this Flag is not available on STM32F030x8 products + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_PWR_GET_FLAG(__FLAG__) ((PWR->CSR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the PWR's pending flags. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag + * @arg PWR_FLAG_SB: StandBy flag + */ +#define __HAL_PWR_CLEAR_FLAG(__FLAG__) (PWR->CR |= (__FLAG__) << 2U) + + +/** + * @} + */ + +/* Include PWR HAL Extension module */ +#include "stm32f0xx_hal_pwr_ex.h" + + /* Exported functions --------------------------------------------------------*/ + + /** @addtogroup PWR_Exported_Functions PWR Exported Functions + * @{ + */ + + /** @addtogroup PWR_Exported_Functions_Group1 Initialization and de-initialization + * functions + * @{ + */ + + /* Initialization and de-initialization functions *****************************/ + void HAL_PWR_DeInit(void); + + /** + * @} + */ + + /** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions + * @{ + */ + + /* Peripheral Control functions **********************************************/ + void HAL_PWR_EnableBkUpAccess(void); + void HAL_PWR_DisableBkUpAccess(void); + + /* WakeUp pins configuration functions ****************************************/ + void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx); + void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx); + + /* Low Power modes configuration functions ************************************/ + void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry); + void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry); + void HAL_PWR_EnterSTANDBYMode(void); + + void HAL_PWR_EnableSleepOnExit(void); + void HAL_PWR_DisableSleepOnExit(void); + void HAL_PWR_EnableSEVOnPend(void); + void HAL_PWR_DisableSEVOnPend(void); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F0xx_HAL_PWR_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_pwr_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_pwr_ex.h new file mode 100644 index 0000000000..77d7d22f56 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_pwr_ex.h @@ -0,0 +1,462 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pwr_ex.h + * @author MCD Application Team + * @brief Header file of PWR HAL Extension module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_PWR_EX_H +#define __STM32F0xx_HAL_PWR_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup PWREx + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + + /** @defgroup PWREx_Exported_Types PWREx Exported Types + * @{ + */ + +#if defined(STM32F031x6) || defined(STM32F042x6) || defined(STM32F051x8) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F091xC) + + /** + * @brief PWR PVD configuration structure definition + */ + typedef struct + { + uint32_t PVDLevel; /*!< PVDLevel: Specifies the PVD detection level + This parameter can be a value of @ref + PWREx_PVD_detection_level */ + + uint32_t Mode; /*!< Mode: Specifies the operating mode for the selected pins. + This parameter can be a value of @ref PWREx_PVD_Mode */ + } PWR_PVDTypeDef; + +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Constants PWREx Exported Constants + * @{ + */ + + +/** @defgroup PWREx_WakeUp_Pins PWREx Wakeup Pins + * @{ + */ +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F091xC) || defined(STM32F098xx) +#define PWR_WAKEUP_PIN1 ((uint32_t)PWR_CSR_EWUP1) +#define PWR_WAKEUP_PIN2 ((uint32_t)PWR_CSR_EWUP2) +#define PWR_WAKEUP_PIN3 ((uint32_t)PWR_CSR_EWUP3) +#define PWR_WAKEUP_PIN4 ((uint32_t)PWR_CSR_EWUP4) +#define PWR_WAKEUP_PIN5 ((uint32_t)PWR_CSR_EWUP5) +#define PWR_WAKEUP_PIN6 ((uint32_t)PWR_CSR_EWUP6) +#define PWR_WAKEUP_PIN7 ((uint32_t)PWR_CSR_EWUP7) +#define PWR_WAKEUP_PIN8 ((uint32_t)PWR_CSR_EWUP8) + +#define IS_PWR_WAKEUP_PIN(PIN) \ + (((PIN) == PWR_WAKEUP_PIN1) || ((PIN) == PWR_WAKEUP_PIN2) || \ + ((PIN) == PWR_WAKEUP_PIN3) || ((PIN) == PWR_WAKEUP_PIN4) || \ + ((PIN) == PWR_WAKEUP_PIN5) || ((PIN) == PWR_WAKEUP_PIN6) || \ + ((PIN) == PWR_WAKEUP_PIN7) || ((PIN) == PWR_WAKEUP_PIN8)) + +#elif defined(STM32F030xC) || defined(STM32F070xB) +#define PWR_WAKEUP_PIN1 ((uint32_t)PWR_CSR_EWUP1) +#define PWR_WAKEUP_PIN2 ((uint32_t)PWR_CSR_EWUP2) +#define PWR_WAKEUP_PIN4 ((uint32_t)PWR_CSR_EWUP4) +#define PWR_WAKEUP_PIN5 ((uint32_t)PWR_CSR_EWUP5) +#define PWR_WAKEUP_PIN6 ((uint32_t)PWR_CSR_EWUP6) +#define PWR_WAKEUP_PIN7 ((uint32_t)PWR_CSR_EWUP7) + +#define IS_PWR_WAKEUP_PIN(PIN) \ + (((PIN) == PWR_WAKEUP_PIN1) || ((PIN) == PWR_WAKEUP_PIN2) || \ + ((PIN) == PWR_WAKEUP_PIN4) || ((PIN) == PWR_WAKEUP_PIN5) || \ + ((PIN) == PWR_WAKEUP_PIN6) || ((PIN) == PWR_WAKEUP_PIN7)) + +#elif defined(STM32F042x6) || defined(STM32F048xx) +#define PWR_WAKEUP_PIN1 ((uint32_t)PWR_CSR_EWUP1) +#define PWR_WAKEUP_PIN2 ((uint32_t)PWR_CSR_EWUP2) +#define PWR_WAKEUP_PIN4 ((uint32_t)PWR_CSR_EWUP4) +#define PWR_WAKEUP_PIN6 ((uint32_t)PWR_CSR_EWUP6) +#define PWR_WAKEUP_PIN7 ((uint32_t)PWR_CSR_EWUP7) + +#define IS_PWR_WAKEUP_PIN(PIN) \ + (((PIN) == PWR_WAKEUP_PIN1) || ((PIN) == PWR_WAKEUP_PIN2) || \ + ((PIN) == PWR_WAKEUP_PIN4) || ((PIN) == PWR_WAKEUP_PIN6) || \ + ((PIN) == PWR_WAKEUP_PIN7)) + +#else +#define PWR_WAKEUP_PIN1 ((uint32_t)PWR_CSR_EWUP1) +#define PWR_WAKEUP_PIN2 ((uint32_t)PWR_CSR_EWUP2) + + +#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WAKEUP_PIN1) || ((PIN) == PWR_WAKEUP_PIN2)) + +#endif + +/** + * @} + */ + +/** @defgroup PWREx_EXTI_Line PWREx EXTI Line + * @{ + */ +#if defined(STM32F031x6) || defined(STM32F042x6) || defined(STM32F051x8) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F091xC) + +#define PWR_EXTI_LINE_PVD \ + ((uint32_t)EXTI_IMR_MR16) /*!< External interrupt line 16 Connected to the PVD EXTI \ + Line */ + +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || \ + defined(STM32F098xx) + +#define PWR_EXTI_LINE_VDDIO2 \ + ((uint32_t)EXTI_IMR_MR31) /*!< External interrupt line 31 Connected to the Vddio2 \ + Monitor EXTI Line */ + +#endif /* defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) ||*/ + /** + * @} + */ + +#if defined(STM32F031x6) || defined(STM32F042x6) || defined(STM32F051x8) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F091xC) +/** @defgroup PWREx_PVD_detection_level PWREx PVD detection level + * @{ + */ +#define PWR_PVDLEVEL_0 PWR_CR_PLS_LEV0 +#define PWR_PVDLEVEL_1 PWR_CR_PLS_LEV1 +#define PWR_PVDLEVEL_2 PWR_CR_PLS_LEV2 +#define PWR_PVDLEVEL_3 PWR_CR_PLS_LEV3 +#define PWR_PVDLEVEL_4 PWR_CR_PLS_LEV4 +#define PWR_PVDLEVEL_5 PWR_CR_PLS_LEV5 +#define PWR_PVDLEVEL_6 PWR_CR_PLS_LEV6 +#define PWR_PVDLEVEL_7 PWR_CR_PLS_LEV7 +#define IS_PWR_PVD_LEVEL(LEVEL) \ + (((LEVEL) == PWR_PVDLEVEL_0) || ((LEVEL) == PWR_PVDLEVEL_1) || \ + ((LEVEL) == PWR_PVDLEVEL_2) || ((LEVEL) == PWR_PVDLEVEL_3) || \ + ((LEVEL) == PWR_PVDLEVEL_4) || ((LEVEL) == PWR_PVDLEVEL_5) || \ + ((LEVEL) == PWR_PVDLEVEL_6) || ((LEVEL) == PWR_PVDLEVEL_7)) +/** + * @} + */ + +/** @defgroup PWREx_PVD_Mode PWREx PVD Mode + * @{ + */ +#define PWR_PVD_MODE_NORMAL (0x00000000U) /*!< basic mode is used */ +#define PWR_PVD_MODE_IT_RISING \ + (0x00010001U) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_IT_FALLING \ + (0x00010002U) /*!< External Interrupt Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_IT_RISING_FALLING \ + (0x00010003U) /*!< External Interrupt Mode with Rising/Falling edge trigger \ + detection */ +#define PWR_PVD_MODE_EVENT_RISING \ + (0x00020001U) /*!< Event Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_EVENT_FALLING \ + (0x00020002U) /*!< Event Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING_FALLING \ + (0x00020003U) /*!< Event Mode with Rising/Falling edge trigger detection */ + +#define IS_PWR_PVD_MODE(MODE) \ + (((MODE) == PWR_PVD_MODE_IT_RISING) || ((MODE) == PWR_PVD_MODE_IT_FALLING) || \ + ((MODE) == PWR_PVD_MODE_IT_RISING_FALLING) || \ + ((MODE) == PWR_PVD_MODE_EVENT_RISING) || ((MODE) == PWR_PVD_MODE_EVENT_FALLING) || \ + ((MODE) == PWR_PVD_MODE_EVENT_RISING_FALLING) || ((MODE) == PWR_PVD_MODE_NORMAL)) +/** + * @} + */ +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + +/** @defgroup PWREx_Flag PWREx Flag + * @{ + */ +#if defined(STM32F031x6) || defined(STM32F042x6) || defined(STM32F051x8) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F091xC) + +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF +#define PWR_FLAG_PVDO PWR_CSR_PVDO +#define PWR_FLAG_VREFINTRDY PWR_CSR_VREFINTRDYF +#elif defined(STM32F070x6) || defined(STM32F070xB) || defined(STM32F030xC) +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF +#define PWR_FLAG_VREFINTRDY PWR_CSR_VREFINTRDYF +#else +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF + +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWREx_Exported_Macros PWREx Exported Macros + * @{ + */ +#if defined(STM32F031x6) || defined(STM32F042x6) || defined(STM32F051x8) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F091xC) +/** + * @brief Enable interrupt on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_IT() (EXTI->IMR |= (PWR_EXTI_LINE_PVD)) + +/** + * @brief Disable interrupt on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_IT() (EXTI->IMR &= ~(PWR_EXTI_LINE_PVD)) + +/** + * @brief Enable event on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_EVENT() (EXTI->EMR |= (PWR_EXTI_LINE_PVD)) + +/** + * @brief Disable event on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_EVENT() (EXTI->EMR &= ~(PWR_EXTI_LINE_PVD)) + +/** + * @brief Disable the PVD Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Extended Interrupt Rising & Falling Trigger. + * @retval None + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_FALLING_EDGE() \ + __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE(); \ + __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); + + +/** + * @brief PVD EXTI line configuration: set falling edge trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE() EXTI->FTSR |= (PWR_EXTI_LINE_PVD) + +/** + * @brief PVD EXTI line configuration: set rising edge trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE() EXTI->RTSR |= (PWR_EXTI_LINE_PVD) + +/** + * @brief Enable the PVD Extended Interrupt Rising & Falling Trigger. + * @retval None + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_FALLING_EDGE() \ + __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE(); \ + __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); + +/** + * @brief Check whether the specified PVD EXTI interrupt flag is set or not. + * @retval EXTI PVD Line Status. + */ +#define __HAL_PWR_PVD_EXTI_GET_FLAG() (EXTI->PR & (PWR_EXTI_LINE_PVD)) + +/** + * @brief Clear the PVD EXTI flag. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_CLEAR_FLAG() (EXTI->PR = (PWR_EXTI_LINE_PVD)) + +/** + * @brief Generate a Software interrupt on selected EXTI line. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_GENERATE_SWIT() (EXTI->SWIER |= (PWR_EXTI_LINE_PVD)) + +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || \ + defined(STM32F098xx) +/** + * @brief Enable interrupt on Vddio2 Monitor Exti Line 31. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_ENABLE_IT() (EXTI->IMR |= (PWR_EXTI_LINE_VDDIO2)) + +/** + * @brief Disable interrupt on Vddio2 Monitor Exti Line 31. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_DISABLE_IT() (EXTI->IMR &= ~(PWR_EXTI_LINE_VDDIO2)) + +/** + * @brief Vddio2 Monitor EXTI line configuration: clear falling edge and rising edge + * trigger. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_DISABLE_FALLING_EDGE() \ + do \ + { \ + EXTI->FTSR &= ~(PWR_EXTI_LINE_VDDIO2); \ + EXTI->RTSR &= ~(PWR_EXTI_LINE_VDDIO2); \ + } while (0) + +/** + * @brief Vddio2 Monitor EXTI line configuration: set falling edge trigger. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_ENABLE_FALLING_EDGE() EXTI->FTSR |= (PWR_EXTI_LINE_VDDIO2) + +/** + * @brief Check whether the specified VDDIO2 monitor EXTI interrupt flag is set or not. + * @retval EXTI VDDIO2 Monitor Line Status. + */ +#define __HAL_PWR_VDDIO2_EXTI_GET_FLAG() (EXTI->PR & (PWR_EXTI_LINE_VDDIO2)) + +/** + * @brief Clear the VDDIO2 Monitor EXTI flag. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_CLEAR_FLAG() (EXTI->PR = (PWR_EXTI_LINE_VDDIO2)) + +/** + * @brief Generate a Software interrupt on selected EXTI line. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_GENERATE_SWIT() (EXTI->SWIER |= (PWR_EXTI_LINE_VDDIO2)) + + +#endif /* defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup PWREx_Exported_Functions PWREx Exported Functions + * @{ + */ + +/** @addtogroup PWREx_Exported_Functions_Group1 + * @{ + */ +/* I/O operation functions ***************************************************/ +#if defined(STM32F031x6) || defined(STM32F042x6) || defined(STM32F051x8) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F091xC) + void HAL_PWR_PVD_IRQHandler(void); + void HAL_PWR_PVDCallback(void); +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || \ + defined(STM32F098xx) + void HAL_PWREx_Vddio2Monitor_IRQHandler(void); + void HAL_PWREx_Vddio2MonitorCallback(void); +#endif /* defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) */ + +/* Peripheral Control functions **********************************************/ +#if defined(STM32F031x6) || defined(STM32F042x6) || defined(STM32F051x8) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F091xC) + void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD); + void HAL_PWR_EnablePVD(void); + void HAL_PWR_DisablePVD(void); +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || \ + defined(STM32F098xx) + void HAL_PWREx_EnableVddio2Monitor(void); + void HAL_PWREx_DisableVddio2Monitor(void); +#endif /* defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_PWR_EX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc.c b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc.c new file mode 100644 index 0000000000..325fdc98e8 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc.c @@ -0,0 +1,1415 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_rcc.c + * @author MCD Application Team + * @brief RCC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Reset and Clock Control (RCC) peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + @verbatim + ============================================================================== + ##### RCC specific features ##### + ============================================================================== + [..] + After reset the device is running from Internal High Speed oscillator + (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is disabled, + and all peripherals are off except internal SRAM, Flash and JTAG. + (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses; + all peripherals mapped on these buses are running at HSI speed. + (+) The clock for all peripherals is switched off, except the SRAM and FLASH. + (+) All GPIOs are in input floating state, except the JTAG pins which + are assigned to be used for debug purpose. + [..] Once the device started from reset, the user application has to: + (+) Configure the clock source to be used to drive the System clock + (if the application needs higher frequency/performance) + (+) Configure the System clock frequency and Flash settings + (+) Configure the AHB and APB buses prescalers + (+) Enable the clock for the peripheral(s) to be used + (+) Configure the clock source(s) for peripherals whose clocks are not + derived from the System clock (RTC, ADC, I2C, USART, TIM, USB FS, etc..) + + ##### RCC Limitations ##### + ============================================================================== + [..] + A delay between an RCC peripheral clock enable and the effective peripheral + enabling should be taken into account in order to manage the peripheral read/write + from/to registers. + (+) This delay depends on the peripheral mapping. + (++) AHB & APB peripherals, 1 dummy read is necessary + + [..] + Workarounds: + (#) For AHB & APB peripherals, a dummy read to the peripheral register has been + inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro. + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup RCC RCC + * @brief RCC HAL module driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup RCC_Private_Constants RCC Private Constants + * @{ + */ +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/** @defgroup RCC_Private_Macros RCC Private Macros + * @{ + */ + +#define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define MCO1_GPIO_PORT GPIOA +#define MCO1_PIN GPIO_PIN_8 + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Variables RCC Private Variables + * @{ + */ +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Functions RCC Exported Functions + * @{ + */ + +/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to configure the internal/external + oscillators (HSE, HSI, HSI14, HSI48, LSE, LSI, PLL, CSS and MCO) and the System buses + clocks (SYSCLK, AHB and APB1). + + [..] Internal/external clock and PLL configuration + (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through + the PLL as System clock source. + The HSI clock can be used also to clock the USART and I2C peripherals. + + (#) HSI14 (high-speed internal), 14 MHz factory-trimmed RC used directly to clock + the ADC peripheral. + + (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC + clock source. + + (#) HSE (high-speed external), 4 to 32 MHz crystal oscillator used directly or + through the PLL as System clock source. Can be used also as RTC clock source. + + (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source. + + (#) PLL (clocked by HSI, HSI48 or HSE), featuring different output clocks: + (++) The first output is used to generate the high speed system clock (up to 48 + MHz) + (++) The second output is used to generate the clock for the USB FS (48 MHz) + (++) The third output may be used to generate the clock for the TIM, I2C and USART + peripherals (up to 48 MHz) + + (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE() + and if a HSE clock failure occurs(HSE used directly or through PLL as System + clock source), the System clocks automatically switched to HSI and an interrupt + is generated if enabled. The interrupt is linked to the Cortex-M0 NMI + (Non-Maskable Interrupt) exception vector. + + (#) MCO (microcontroller clock output), used to output SYSCLK, HSI, HSE, LSI, LSE or + PLL clock (divided by 2) output on pin (such as PA8 pin). + + [..] System, AHB and APB buses clocks configuration + (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI, + HSE and PLL. + The AHB clock (HCLK) is derived from System clock through configurable + prescaler and used to clock the CPU, memory and peripherals mapped + on AHB bus (DMA, GPIO...). APB1 (PCLK1) clock is derived + from AHB clock through configurable prescalers and used to clock + the peripherals mapped on these buses. You can use + "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these + clocks. + + (#) All the peripheral clocks are derived from the System clock (SYSCLK) except: + (++) The FLASH program/erase clock which is always HSI 8MHz clock. + (++) The USB 48 MHz clock which is derived from the PLL VCO clock. + (++) The USART clock which can be derived as well from HSI 8MHz, LSI or LSE. + (++) The I2C clock which can be derived as well from HSI 8MHz clock. + (++) The ADC clock which is derived from PLL output. + (++) The RTC clock which is derived from the LSE, LSI or 1 MHz HSE_RTC + (HSE divided by a programmable prescaler). The System clock (SYSCLK) + frequency must be higher or equal to the RTC clock frequency. + (++) IWDG clock which is always the LSI clock. + + (#) For the STM32F0xx devices, the maximum frequency of the SYSCLK, HCLK and PCLK1 + is 48 MHz, Depending on the SYSCLK frequency, the flash latency should be adapted + accordingly. + + (#) After reset, the System clock source is the HSI (8 MHz) with 0 WS and + prefetch is disabled. + @endverbatim + * @{ + */ + +/* + Additional consideration on the SYSCLK based on Latency settings: + +-----------------------------------------------+ + | Latency | SYSCLK clock frequency (MHz) | + |---------------|-------------------------------| + |0WS(1CPU cycle)| 0 < SYSCLK <= 24 | + |---------------|-------------------------------| + |1WS(2CPU cycle)| 24 < SYSCLK <= 48 | + +-----------------------------------------------+ + */ + +/** + * @brief Resets the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * - HSI ON and used as system clock source + * - HSE and PLL OFF + * - AHB, APB1 prescaler set to 1. + * - CSS and MCO1 OFF + * - All interrupts disabled + * - All interrupt and reset flags cleared + * @note This function does not modify the configuration of the + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_DeInit(void) +{ + uint32_t tickstart; + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Set HSION bit, HSITRIM[4:0] bits to the reset value*/ + SET_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSITRIM_4); + + /* Wait till HSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset SW[1:0], HPRE[3:0], PPRE[2:0] and MCOSEL[2:0] bits */ + CLEAR_BIT(RCC->CFGR, RCC_CFGR_SW | RCC_CFGR_HPRE | RCC_CFGR_PPRE | RCC_CFGR_MCO); + + /* Wait till HSI as SYSCLK status is enabled */ + while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET) + { + if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Update the SystemCoreClock global variable for HSI as system clock source */ + SystemCoreClock = HSI_VALUE; + + /* Adapt Systick interrupt period */ + if (HAL_InitTick(uwTickPrio) != HAL_OK) + { + return HAL_ERROR; + } + + /* Reset HSEON, CSSON, PLLON bits */ + CLEAR_BIT(RCC->CR, RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_HSEON); + + /* Reset HSEBYP bit */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + + /* Get start tick */ + tickstart = HAL_GetTick(); + + /* Wait till PLLRDY is cleared */ + while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset CFGR register */ + CLEAR_REG(RCC->CFGR); + + /* Reset CFGR2 register */ + CLEAR_REG(RCC->CFGR2); + + /* Reset CFGR3 register */ + CLEAR_REG(RCC->CFGR3); + + /* Disable all interrupts */ + CLEAR_REG(RCC->CIR); + + /* Clear all reset flags */ + __HAL_RCC_CLEAR_RESET_FLAGS(); + + return HAL_OK; +} + +/** + * @brief Initializes the RCC Oscillators according to the specified parameters in the + * RCC_OscInitTypeDef. + * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC Oscillators. + * @note The PLL is not disabled when used as system clock. + * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not + * supported by this macro. User should request a transition to LSE Off + * first and then LSE On or LSE Bypass. + * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not + * supported by this macro. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + uint32_t tickstart; + uint32_t pll_config; + uint32_t pll_config2; + + /* Check Null pointer */ + if (RCC_OscInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + + /*------------------------------- HSE Configuration ------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == + RCC_OSCILLATORTYPE_HSE) + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); + + /* When the HSE is used as system clock or clock source for PLL in these cases it + * is not allowed to be disabled */ + if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) || + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && + (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE))) + { + if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && + (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + { + return HAL_ERROR; + } + } + else + { + /* Set the new HSE configuration ---------------------------------------*/ + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + + + /* Check the HSE State */ + if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF) + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSE is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSE is disabled */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*----------------------------- HSI Configuration --------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == + RCC_OSCILLATORTYPE_HSI) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); + + /* Check if HSI is used as system clock or as PLL source when PLL is selected as + * system clock */ + if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) || + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && + (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI))) + { + /* When HSI is used as system clock it will not disabled */ + if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && + (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) + { + return HAL_ERROR; + } + /* Otherwise, just the calibration is allowed */ + else + { + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST( + RCC_OscInitStruct->HSICalibrationValue); + } + } + else + { + /* Check the HSI State */ + if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF) + { + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST( + RCC_OscInitStruct->HSICalibrationValue); + } + else + { + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is disabled */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*------------------------------ LSI Configuration -------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == + RCC_OSCILLATORTYPE_LSI) + { + /* Check the parameters */ + assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); + + /* Check the LSI State */ + if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF) + { + /* Enable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSI is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSI is disabled */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + /*------------------------------ LSE Configuration -------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == + RCC_OSCILLATORTYPE_LSE) + { + FlagStatus pwrclkchanged = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); + + /* Update LSE configuration in Backup Domain control register */ + /* Requires to enable write access to Backup Domain of necessary */ + if (__HAL_RCC_PWR_IS_CLK_DISABLED()) + { + __HAL_RCC_PWR_CLK_ENABLE(); + pwrclkchanged = SET; + } + + if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR, PWR_CR_DBP); + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + + while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + { + if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Set the new LSE configuration -----------------------------------------*/ + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + /* Check the LSE State */ + if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF) + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is disabled */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Require to disable power clock if necessary */ + if (pwrclkchanged == SET) + { + __HAL_RCC_PWR_CLK_DISABLE(); + } + } + + /*----------------------------- HSI14 Configuration --------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI14) == + RCC_OSCILLATORTYPE_HSI14) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI14(RCC_OscInitStruct->HSI14State)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSI14CalibrationValue)); + + /* Check the HSI14 State */ + if (RCC_OscInitStruct->HSI14State == RCC_HSI14_ON) + { + /* Disable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_DISABLE(); + + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI14_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. + */ + __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST( + RCC_OscInitStruct->HSI14CalibrationValue); + } + else if (RCC_OscInitStruct->HSI14State == RCC_HSI14_ADC_CONTROL) + { + /* Enable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_ENABLE(); + + /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. + */ + __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST( + RCC_OscInitStruct->HSI14CalibrationValue); + } + else + { + /* Disable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_DISABLE(); + + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI14_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + +#if defined(RCC_HSI48_SUPPORT) + /*----------------------------- HSI48 Configuration --------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == + RCC_OSCILLATORTYPE_HSI48) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State)); + + /* When the HSI48 is used as system clock it is not allowed to be disabled */ + if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) || + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && + (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48))) + { + if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && + (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON)) + { + return HAL_ERROR; + } + } + else + { + /* Check the HSI48 State */ + if (RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF) + { + /* Enable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI48 is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI48 is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } +#endif /* RCC_HSI48_SUPPORT */ + + /*-------------------------------- PLL Configuration -----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); + if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) + { + /* Check if the PLL is used as system clock or not */ + if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) + { + /* Check the parameters */ + assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); + assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL)); + assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV)); + + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till PLL is disabled */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Configure the main PLL clock source, predivider and multiplication + * factor. */ + __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, + RCC_OscInitStruct->PLL.PREDIV, + RCC_OscInitStruct->PLL.PLLMUL); + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till PLL is disabled */ + while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + else + { + /* Check if there is a request to disable the PLL used as System clock source + */ + if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) + { + return HAL_ERROR; + } + else + { + /* Do not return HAL_ERROR if request repeats the current configuration */ + pll_config = RCC->CFGR; + pll_config2 = RCC->CFGR2; + if ((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != + RCC_OscInitStruct->PLL.PLLSource) || + (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != + RCC_OscInitStruct->PLL.PREDIV) || + (READ_BIT(pll_config, RCC_CFGR_PLLMUL) != + RCC_OscInitStruct->PLL.PLLMUL)) + { + return HAL_ERROR; + } + } + } + } + + return HAL_OK; +} + +/** + * @brief Initializes the CPU, AHB and APB buses clocks according to the specified + * parameters in the RCC_ClkInitStruct. + * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC peripheral. + * @param FLatency FLASH Latency + * The value of this parameter depend on device used within the same series + * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency + * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function + * + * @note The HSI is used (enabled by hardware) as system clock source after + * start-up from Reset, wake-up from STOP and STANDBY mode, or in case + * of failure of the HSE used directly or indirectly as system clock + * (if the Clock Security System CSS is enabled). + * + * @note A switch from one clock source to another occurs only if the target + * clock source is ready (clock stable after start-up delay or PLL locked). + * If a clock source which is not yet ready is selected, the switch will + * occur when the clock source will be ready. + * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is + * currently used as system clock source. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, + uint32_t FLatency) +{ + uint32_t tickstart; + + /* Check Null pointer */ + if (RCC_ClkInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType)); + assert_param(IS_FLASH_LATENCY(FLatency)); + + /* To correctly read data from FLASH memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the CPU clock + (HCLK) of the device. */ + + /* Increasing the number of wait states because of higher CPU frequency */ + if (FLatency > __HAL_FLASH_GET_LATENCY()) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR + * register */ + __HAL_FLASH_SET_LATENCY(FLatency); + + /* Check that the new number of wait states is taken into account to access the + Flash memory by reading the FLASH_ACR register */ + if (__HAL_FLASH_GET_LATENCY() != FLatency) + { + return HAL_ERROR; + } + } + + /*-------------------------- HCLK Configuration --------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + /* Set the highest APB divider in order to ensure that we do not go through + a non-spec phase whatever we decrease or increase HCLK. */ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16); + } + + /* Set the new HCLK clock divider */ + assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); + } + + /*------------------------- SYSCLK Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + { + assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); + + /* HSE is selected as System Clock Source */ + if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + /* Check the HSE ready flag */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + { + return HAL_ERROR; + } + } + /* PLL is selected as System Clock Source */ + else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + { + /* Check the PLL ready flag */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + return HAL_ERROR; + } + } +#if defined(RCC_CFGR_SWS_HSI48) + /* HSI48 is selected as System Clock Source */ + else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48) + { + /* Check the HSI48 ready flag */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + { + return HAL_ERROR; + } + } +#endif /* RCC_CFGR_SWS_HSI48 */ + /* HSI is selected as System Clock Source */ + else + { + /* Check the HSI ready flag */ + if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + { + return HAL_ERROR; + } + } + __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + while (__HAL_RCC_GET_SYSCLK_SOURCE() != + (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + { + if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Decreasing the number of wait states because of lower CPU frequency */ + if (FLatency < __HAL_FLASH_GET_LATENCY()) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR + * register */ + __HAL_FLASH_SET_LATENCY(FLatency); + + /* Check that the new number of wait states is taken into account to access the + Flash memory by reading the FLASH_ACR register */ + if (__HAL_FLASH_GET_LATENCY() != FLatency) + { + return HAL_ERROR; + } + } + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider); + } + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = + HAL_RCC_GetSysClockFreq() >> + AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_BITNUMBER]; + + /* Configure the source of time base considering new system clocks settings*/ + HAL_InitTick(TICK_INT_PRIORITY); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions + * @brief RCC clocks control functions + * + @verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the RCC Clocks + frequencies. + + @endverbatim + * @{ + */ + +#if defined(RCC_CFGR_MCOPRE) +/** + * @brief Selects the clock source to output on MCO pin. + * @note MCO pin should be configured in alternate function mode. + * @param RCC_MCOx specifies the output direction for the clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8). + * @param RCC_MCOSource specifies the clock source to output. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected + * @arg @ref RCC_MCO1SOURCE_SYSCLK System Clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI14 HSI14 selected as MCO clock + @if STM32F042x6 + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F048xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F071xB + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F072xB + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F078xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F091xC + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F098xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F030x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F030xC + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F031x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F038xx + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F070x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F070xB + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @endif + * @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO + clock + * @param RCC_MCODiv specifies the MCO DIV. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 no division applied to MCO clock + * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock + * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock + * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock + * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock + * @arg @ref RCC_MCODIV_32 division by 32 applied to MCO clock + * @arg @ref RCC_MCODIV_64 division by 64 applied to MCO clock + * @arg @ref RCC_MCODIV_128 division by 128 applied to MCO clock + * @retval None + */ +#else +/** + * @brief Selects the clock source to output on MCO pin. + * @note MCO pin should be configured in alternate function mode. + * @param RCC_MCOx specifies the output direction for the clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8). + * @param RCC_MCOSource specifies the clock source to output. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI14 HSI14 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO + * clock + * @param RCC_MCODiv specifies the MCO DIV. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 no division applied to MCO clock + * @retval None + */ +#endif +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv) +{ + GPIO_InitTypeDef gpio; + + /* Check the parameters */ + assert_param(IS_RCC_MCO(RCC_MCOx)); + assert_param(IS_RCC_MCODIV(RCC_MCODiv)); + assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource)); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(RCC_MCOx); + + /* Configure the MCO1 pin in alternate function mode */ + gpio.Mode = GPIO_MODE_AF_PP; + gpio.Speed = GPIO_SPEED_FREQ_HIGH; + gpio.Pull = GPIO_NOPULL; + gpio.Pin = MCO1_PIN; + gpio.Alternate = GPIO_AF0_MCO; + + /* MCO1 Clock Enable */ + MCO1_CLK_ENABLE(); + + HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio); + + /* Configure the MCO clock source */ + __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv); +} + +/** + * @brief Enables the Clock Security System. + * @note If a failure is detected on the HSE oscillator clock, this oscillator + * is automatically disabled and an interrupt is generated to inform the + * software about the failure (Clock Security System Interrupt, CSSI), + * allowing the MCU to perform rescue operations. The CSSI is linked to + * the Cortex-M0 NMI (Non-Maskable Interrupt) exception vector. + * @retval None + */ +void HAL_RCC_EnableCSS(void) +{ + SET_BIT(RCC->CR, RCC_CR_CSSON); +} + +/** + * @brief Disables the Clock Security System. + * @retval None + */ +void HAL_RCC_DisableCSS(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_CSSON); +} + +/** + * @brief Returns the SYSCLK frequency + * @note The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE + * divided by PREDIV factor(**) + * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE + * divided by PREDIV factor(**) or depending on STM32F0xxxx devices either a + * value based on HSI_VALUE divided by 2 or HSI_VALUE divided by PREDIV factor(*) + * multiplied by the PLL factor. + * @note (*) HSI_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default + * value 8 MHz) but the real value may vary depending on the variations in voltage and + * temperature. + * @note (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default + * value 8 MHz), user has to ensure that HSE_VALUE is same as the real frequency of the + * crystal used. Otherwise, this function may have wrong result. + * + * @note The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @note This function can be used by the user application to compute the + * baud-rate for the communication peripherals or configure other parameters. + * + * @note Each time SYSCLK changes, this function must be called to update the + * right SYSCLK value. Otherwise, any configuration based on this function will be + * incorrect. + * + * @retval SYSCLK frequency + */ +uint32_t HAL_RCC_GetSysClockFreq(void) +{ + static const uint8_t aPLLMULFactorTable[16U] = { + 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 16U, 16U}; + static const uint8_t aPredivFactorTable[16U] = { + 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 16U}; + + uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U; + uint32_t sysclockfreq = 0U; + + tmpreg = RCC->CFGR; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (tmpreg & RCC_CFGR_SWS) + { + case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */ + { + sysclockfreq = HSE_VALUE; + break; + } + case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */ + { + pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> + RCC_CFGR_PLLMUL_BITNUMBER]; + prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV) >> + RCC_CFGR2_PREDIV_BITNUMBER]; + if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + { + /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t)HSE_VALUE / (uint64_t)(prediv)) * + ((uint64_t)pllmul); + } +#if defined(RCC_CFGR_PLLSRC_HSI48_PREDIV) + else if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSI48) + { + /* HSI48 used as PLL clock source : PLLCLK = HSI48/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t)HSI48_VALUE / (uint64_t)(prediv)) * + ((uint64_t)pllmul); + } +#endif /* RCC_CFGR_PLLSRC_HSI48_PREDIV */ + else + { +#if (defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC)) + /* HSI used as PLL clock source : PLLCLK = HSI/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t)HSI_VALUE / (uint64_t)(prediv)) * + ((uint64_t)pllmul); +#else + /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */ + pllclk = (uint32_t)((uint64_t)(HSI_VALUE >> 1U) * ((uint64_t)pllmul)); +#endif + } + sysclockfreq = pllclk; + break; + } +#if defined(RCC_CFGR_SWS_HSI48) + case RCC_SYSCLKSOURCE_STATUS_HSI48: /* HSI48 used as system clock source */ + { + sysclockfreq = HSI48_VALUE; + break; + } +#endif /* RCC_CFGR_SWS_HSI48 */ + case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ + default: /* HSI used as system clock */ + { + sysclockfreq = HSI_VALUE; + break; + } + } + return sysclockfreq; +} + +/** + * @brief Returns the HCLK frequency + * @note Each time HCLK changes, this function must be called to update the + * right HCLK value. Otherwise, any configuration based on this function will be + * incorrect. + * + * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency + * and updated within this function + * @retval HCLK frequency + */ +uint32_t HAL_RCC_GetHCLKFreq(void) +{ + return SystemCoreClock; +} + +/** + * @brief Returns the PCLK1 frequency + * @note Each time PCLK1 changes, this function must be called to update the + * right PCLK1 value. Otherwise, any configuration based on this function will be + * incorrect. + * @retval PCLK1 frequency + */ +uint32_t HAL_RCC_GetPCLK1Freq(void) +{ + /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq() >> + APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE) >> RCC_CFGR_PPRE_BITNUMBER]); +} + +/** + * @brief Configures the RCC_OscInitStruct according to the internal + * RCC configuration registers. + * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that + * will be configured. + * @retval None + */ +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + /* Check the parameters */ + assert_param(RCC_OscInitStruct != NULL); + + /* Set all possible values for the Oscillator type parameter ---------------*/ + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | + RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | + RCC_OSCILLATORTYPE_HSI14; +#if defined(RCC_HSI48_SUPPORT) + RCC_OscInitStruct->OscillatorType |= RCC_OSCILLATORTYPE_HSI48; +#endif /* RCC_HSI48_SUPPORT */ + + + /* Get the HSE configuration -----------------------------------------------*/ + if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP) + { + RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; + } + else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON) + { + RCC_OscInitStruct->HSEState = RCC_HSE_ON; + } + else + { + RCC_OscInitStruct->HSEState = RCC_HSE_OFF; + } + + /* Get the HSI configuration -----------------------------------------------*/ + if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION) + { + RCC_OscInitStruct->HSIState = RCC_HSI_ON; + } + else + { + RCC_OscInitStruct->HSIState = RCC_HSI_OFF; + } + + RCC_OscInitStruct->HSICalibrationValue = + (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_BitNumber); + + /* Get the LSE configuration -----------------------------------------------*/ + if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) + { + RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; + } + else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON) + { + RCC_OscInitStruct->LSEState = RCC_LSE_ON; + } + else + { + RCC_OscInitStruct->LSEState = RCC_LSE_OFF; + } + + /* Get the LSI configuration -----------------------------------------------*/ + if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION) + { + RCC_OscInitStruct->LSIState = RCC_LSI_ON; + } + else + { + RCC_OscInitStruct->LSIState = RCC_LSI_OFF; + } + + /* Get the HSI14 configuration -----------------------------------------------*/ + if ((RCC->CR2 & RCC_CR2_HSI14ON) == RCC_CR2_HSI14ON) + { + RCC_OscInitStruct->HSI14State = RCC_HSI_ON; + } + else + { + RCC_OscInitStruct->HSI14State = RCC_HSI_OFF; + } + + RCC_OscInitStruct->HSI14CalibrationValue = + (uint32_t)((RCC->CR2 & RCC_CR2_HSI14TRIM) >> RCC_HSI14TRIM_BIT_NUMBER); + +#if defined(RCC_HSI48_SUPPORT) + /* Get the HSI48 configuration if any-----------------------------------------*/ + RCC_OscInitStruct->HSI48State = __HAL_RCC_GET_HSI48_STATE(); +#endif /* RCC_HSI48_SUPPORT */ + + /* Get the PLL configuration -----------------------------------------------*/ + if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON) + { + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON; + } + else + { + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; + } + RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC); + RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMUL); + RCC_OscInitStruct->PLL.PREDIV = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV); +} + +/** + * @brief Get the RCC_ClkInitStruct according to the internal + * RCC configuration registers. + * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that + * contains the current clock configuration. + * @param pFLatency Pointer on the Flash Latency. + * @retval None + */ +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency) +{ + /* Check the parameters */ + assert_param(RCC_ClkInitStruct != NULL); + assert_param(pFLatency != NULL); + + /* Set all possible values for the Clock type parameter --------------------*/ + RCC_ClkInitStruct->ClockType = + RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1; + + /* Get the SYSCLK configuration --------------------------------------------*/ + RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW); + + /* Get the HCLK configuration ----------------------------------------------*/ + RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE); + + /* Get the APB1 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE); + /* Get the Flash Wait State (Latency) configuration ------------------------*/ + *pFLatency = __HAL_FLASH_GET_LATENCY(); +} + +/** + * @brief This function handles the RCC CSS interrupt request. + * @note This API should be called under the NMI_Handler(). + * @retval None + */ +void HAL_RCC_NMI_IRQHandler(void) +{ + /* Check RCC CSSF flag */ + if (__HAL_RCC_GET_IT(RCC_IT_CSS)) + { + /* RCC Clock Security System interrupt user callback */ + HAL_RCC_CSSCallback(); + + /* Clear RCC CSS pending bit */ + __HAL_RCC_CLEAR_IT(RCC_IT_CSS); + } +} + +/** + * @brief RCC Clock Security System interrupt callback + * @retval none + */ +__weak void HAL_RCC_CSSCallback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RCC_CSSCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_RCC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc.h new file mode 100644 index 0000000000..125f7a283d --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc.h @@ -0,0 +1,1811 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_rcc.h + * @author MCD Application Team + * @brief Header file of RCC HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_RCC_H +#define __STM32F0xx_HAL_RCC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/** @addtogroup RCC_Private_Constants + * @{ + */ + +/** @defgroup RCC_Timeout RCC Timeout + * @{ + */ + +/* Disable Backup domain write protection state change timeout */ +#define RCC_DBP_TIMEOUT_VALUE (100U) /* 100 ms */ +/* LSE state change timeout */ +#define RCC_LSE_TIMEOUT_VALUE LSE_STARTUP_TIMEOUT +#define CLOCKSWITCH_TIMEOUT_VALUE (5000U) /* 5 s */ +#define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT +#define HSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#define LSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#define PLL_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#define HSI14_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#if defined(RCC_HSI48_SUPPORT) +#define HSI48_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#endif /* RCC_HSI48_SUPPORT */ +/** + * @} + */ + +/** @defgroup RCC_Register_Offset Register offsets + * @{ + */ +#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) +#define RCC_CR_OFFSET 0x00 +#define RCC_CFGR_OFFSET 0x04 +#define RCC_CIR_OFFSET 0x08 +#define RCC_BDCR_OFFSET 0x20 +#define RCC_CSR_OFFSET 0x24 + +/** + * @} + */ + + +/* CR register byte 2 (Bits[23:16]) base address */ +#define RCC_CR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + RCC_CR_OFFSET + 0x02U)) + +/* CIR register byte 1 (Bits[15:8]) base address */ +#define RCC_CIR_BYTE1_ADDRESS ((uint32_t)(RCC_BASE + RCC_CIR_OFFSET + 0x01U)) + +/* CIR register byte 2 (Bits[23:16]) base address */ +#define RCC_CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + RCC_CIR_OFFSET + 0x02U)) + +/* Defines used for Flags */ +#define CR_REG_INDEX ((uint8_t)1U) +#define CR2_REG_INDEX ((uint8_t)2U) +#define BDCR_REG_INDEX ((uint8_t)3U) +#define CSR_REG_INDEX ((uint8_t)4U) + +/* Bits position in in the CFGR register */ +#define RCC_CFGR_PLLMUL_BITNUMBER 18U +#define RCC_CFGR_HPRE_BITNUMBER 4U +#define RCC_CFGR_PPRE_BITNUMBER 8U +/* Flags in the CFGR2 register */ +#define RCC_CFGR2_PREDIV_BITNUMBER 0 +/* Flags in the CR register */ +#define RCC_CR_HSIRDY_BitNumber 1 +#define RCC_CR_HSERDY_BitNumber 17 +#define RCC_CR_PLLRDY_BitNumber 25 +/* Flags in the CR2 register */ +#define RCC_CR2_HSI14RDY_BitNumber 1 +#define RCC_CR2_HSI48RDY_BitNumber 17 +/* Flags in the BDCR register */ +#define RCC_BDCR_LSERDY_BitNumber 1 +/* Flags in the CSR register */ +#define RCC_CSR_LSIRDY_BitNumber 1 +#define RCC_CSR_V18PWRRSTF_BitNumber 23 +#define RCC_CSR_RMVF_BitNumber 24 +#define RCC_CSR_OBLRSTF_BitNumber 25 +#define RCC_CSR_PINRSTF_BitNumber 26 +#define RCC_CSR_PORRSTF_BitNumber 27 +#define RCC_CSR_SFTRSTF_BitNumber 28 +#define RCC_CSR_IWDGRSTF_BitNumber 29 +#define RCC_CSR_WWDGRSTF_BitNumber 30 +#define RCC_CSR_LPWRRSTF_BitNumber 31 +/* Flags in the HSITRIM register */ +#define RCC_CR_HSITRIM_BitNumber 3 +#define RCC_HSI14TRIM_BIT_NUMBER 3 +#define RCC_FLAG_MASK ((uint8_t)0x1FU) + +/** + * @} + */ + +/** @addtogroup RCC_Private_Macros + * @{ + */ +#define IS_RCC_HSE(__HSE__) \ + (((__HSE__) == RCC_HSE_OFF) || ((__HSE__) == RCC_HSE_ON) || \ + ((__HSE__) == RCC_HSE_BYPASS)) +#define IS_RCC_LSE(__LSE__) \ + (((__LSE__) == RCC_LSE_OFF) || ((__LSE__) == RCC_LSE_ON) || \ + ((__LSE__) == RCC_LSE_BYPASS)) +#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON)) +#define IS_RCC_HSI14(__HSI14__) \ + (((__HSI14__) == RCC_HSI14_OFF) || ((__HSI14__) == RCC_HSI14_ON) || \ + ((__HSI14__) == RCC_HSI14_ADC_CONTROL)) +#define IS_RCC_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0x1FU) +#define IS_RCC_LSI(__LSI__) (((__LSI__) == RCC_LSI_OFF) || ((__LSI__) == RCC_LSI_ON)) +#define IS_RCC_PLL(__PLL__) \ + (((__PLL__) == RCC_PLL_NONE) || ((__PLL__) == RCC_PLL_OFF) || \ + ((__PLL__) == RCC_PLL_ON)) +#define IS_RCC_PREDIV(__PREDIV__) \ + (((__PREDIV__) == RCC_PREDIV_DIV1) || ((__PREDIV__) == RCC_PREDIV_DIV2) || \ + ((__PREDIV__) == RCC_PREDIV_DIV3) || ((__PREDIV__) == RCC_PREDIV_DIV4) || \ + ((__PREDIV__) == RCC_PREDIV_DIV5) || ((__PREDIV__) == RCC_PREDIV_DIV6) || \ + ((__PREDIV__) == RCC_PREDIV_DIV7) || ((__PREDIV__) == RCC_PREDIV_DIV8) || \ + ((__PREDIV__) == RCC_PREDIV_DIV9) || ((__PREDIV__) == RCC_PREDIV_DIV10) || \ + ((__PREDIV__) == RCC_PREDIV_DIV11) || ((__PREDIV__) == RCC_PREDIV_DIV12) || \ + ((__PREDIV__) == RCC_PREDIV_DIV13) || ((__PREDIV__) == RCC_PREDIV_DIV14) || \ + ((__PREDIV__) == RCC_PREDIV_DIV15) || ((__PREDIV__) == RCC_PREDIV_DIV16)) + +#define IS_RCC_PLL_MUL(__MUL__) \ + (((__MUL__) == RCC_PLL_MUL2) || ((__MUL__) == RCC_PLL_MUL3) || \ + ((__MUL__) == RCC_PLL_MUL4) || ((__MUL__) == RCC_PLL_MUL5) || \ + ((__MUL__) == RCC_PLL_MUL6) || ((__MUL__) == RCC_PLL_MUL7) || \ + ((__MUL__) == RCC_PLL_MUL8) || ((__MUL__) == RCC_PLL_MUL9) || \ + ((__MUL__) == RCC_PLL_MUL10) || ((__MUL__) == RCC_PLL_MUL11) || \ + ((__MUL__) == RCC_PLL_MUL12) || ((__MUL__) == RCC_PLL_MUL13) || \ + ((__MUL__) == RCC_PLL_MUL14) || ((__MUL__) == RCC_PLL_MUL15) || \ + ((__MUL__) == RCC_PLL_MUL16)) +#define IS_RCC_CLOCKTYPE(__CLK__) \ + ((((__CLK__)&RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) || \ + (((__CLK__)&RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) || \ + (((__CLK__)&RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)) +#define IS_RCC_HCLK(__HCLK__) \ + (((__HCLK__) == RCC_SYSCLK_DIV1) || ((__HCLK__) == RCC_SYSCLK_DIV2) || \ + ((__HCLK__) == RCC_SYSCLK_DIV4) || ((__HCLK__) == RCC_SYSCLK_DIV8) || \ + ((__HCLK__) == RCC_SYSCLK_DIV16) || ((__HCLK__) == RCC_SYSCLK_DIV64) || \ + ((__HCLK__) == RCC_SYSCLK_DIV128) || ((__HCLK__) == RCC_SYSCLK_DIV256) || \ + ((__HCLK__) == RCC_SYSCLK_DIV512)) +#define IS_RCC_PCLK(__PCLK__) \ + (((__PCLK__) == RCC_HCLK_DIV1) || ((__PCLK__) == RCC_HCLK_DIV2) || \ + ((__PCLK__) == RCC_HCLK_DIV4) || ((__PCLK__) == RCC_HCLK_DIV8) || \ + ((__PCLK__) == RCC_HCLK_DIV16)) +#define IS_RCC_MCO(__MCO__) ((__MCO__) == RCC_MCO) +#define IS_RCC_RTCCLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_RTCCLKSOURCE_NO_CLK) || \ + ((__SOURCE__) == RCC_RTCCLKSOURCE_LSE) || ((__SOURCE__) == RCC_RTCCLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_RTCCLKSOURCE_HSE_DIV32)) +#define IS_RCC_USART1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_USART1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_SYSCLK) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_HSI)) +#define IS_RCC_I2C1CLKSOURCE(__SOURCE__) \ + (((__SOURCE__) == RCC_I2C1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_SYSCLK)) + + /** + * @} + */ + + /* Exported types ------------------------------------------------------------*/ + + /** @defgroup RCC_Exported_Types RCC Exported Types + * @{ + */ + + /** + * @brief RCC PLL configuration structure definition + */ + typedef struct + { + uint32_t PLLState; /*!< PLLState: The new state of the PLL. + This parameter can be a value of @ref RCC_PLL_Config */ + + uint32_t + PLLSource; /*!< PLLSource: PLL entry clock source. + This parameter must be a value of @ref RCC_PLL_Clock_Source */ + + uint32_t PLLMUL; /*!< PLLMUL: Multiplication factor for PLL VCO input clock + This parameter must be a value of @ref + RCC_PLL_Multiplication_Factor*/ + + uint32_t + PREDIV; /*!< PREDIV: Predivision factor for PLL VCO input clock + This parameter must be a value of @ref RCC_PLL_Prediv_Factor */ + + } RCC_PLLInitTypeDef; + + /** + * @brief RCC Internal/External Oscillator (HSE, HSI, LSE and LSI) configuration + * structure definition + */ + typedef struct + { + uint32_t OscillatorType; /*!< The oscillators to be configured. + This parameter can be a value of @ref + RCC_Oscillator_Type */ + + uint32_t HSEState; /*!< The new state of the HSE. + This parameter can be a value of @ref RCC_HSE_Config */ + + uint32_t LSEState; /*!< The new state of the LSE. + This parameter can be a value of @ref RCC_LSE_Config */ + + uint32_t HSIState; /*!< The new state of the HSI. + This parameter can be a value of @ref RCC_HSI_Config */ + + uint32_t + HSICalibrationValue; /*!< The HSI calibration trimming value (default is + RCC_HSICALIBRATION_DEFAULT). This parameter must be a + number between Min_Data = 0x00 and Max_Data = 0x1FU */ + + uint32_t + HSI14State; /*!< The new state of the HSI14. + This parameter can be a value of @ref RCC_HSI14_Config */ + + uint32_t HSI14CalibrationValue; /*!< The HSI14 calibration trimming value (default + is RCC_HSI14CALIBRATION_DEFAULT). This + parameter must be a number between Min_Data = + 0x00 and Max_Data = 0x1FU */ + + uint32_t LSIState; /*!< The new state of the LSI. + This parameter can be a value of @ref RCC_LSI_Config */ + +#if defined(RCC_HSI48_SUPPORT) + uint32_t + HSI48State; /*!< The new state of the HSI48. + This parameter can be a value of @ref RCC_HSI48_Config */ + +#endif /* RCC_HSI48_SUPPORT */ + RCC_PLLInitTypeDef PLL; /*!< PLL structure parameters */ + + } RCC_OscInitTypeDef; + + /** + * @brief RCC System, AHB and APB busses clock configuration structure definition + */ + typedef struct + { + uint32_t + ClockType; /*!< The clock to be configured. + This parameter can be a value of @ref RCC_System_Clock_Type */ + + uint32_t SYSCLKSource; /*!< The clock source (SYSCLKS) used as system clock. + This parameter can be a value of @ref + RCC_System_Clock_Source */ + + uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived + from the system clock (SYSCLK). This parameter can be a + value of @ref RCC_AHB_Clock_Source */ + + uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is + derived from the AHB clock (HCLK). This parameter can + be a value of @ref RCC_APB1_Clock_Source */ + + } RCC_ClkInitTypeDef; + + /** + * @} + */ + + /* Exported constants --------------------------------------------------------*/ + /** @defgroup RCC_Exported_Constants RCC Exported Constants + * @{ + */ + + /** @defgroup RCC_PLL_Clock_Source PLL Clock Source + * @{ + */ + +#define RCC_PLLSOURCE_HSE \ + RCC_CFGR_PLLSRC_HSE_PREDIV /*!< HSE clock selected as PLL entry clock source */ + +/** + * @} + */ + +/** @defgroup RCC_Oscillator_Type Oscillator Type + * @{ + */ +#define RCC_OSCILLATORTYPE_NONE (0x00000000U) +#define RCC_OSCILLATORTYPE_HSE (0x00000001U) +#define RCC_OSCILLATORTYPE_HSI (0x00000002U) +#define RCC_OSCILLATORTYPE_LSE (0x00000004U) +#define RCC_OSCILLATORTYPE_LSI (0x00000008U) +#define RCC_OSCILLATORTYPE_HSI14 (0x00000010U) +#if defined(RCC_HSI48_SUPPORT) +#define RCC_OSCILLATORTYPE_HSI48 (0x00000020U) +#endif /* RCC_HSI48_SUPPORT */ +/** + * @} + */ + +/** @defgroup RCC_HSE_Config HSE Config + * @{ + */ +#define RCC_HSE_OFF (0x00000000U) /*!< HSE clock deactivation */ +#define RCC_HSE_ON (0x00000001U) /*!< HSE clock activation */ +#define RCC_HSE_BYPASS (0x00000005U) /*!< External clock source for HSE clock */ +/** + * @} + */ + +/** @defgroup RCC_LSE_Config LSE Config + * @{ + */ +#define RCC_LSE_OFF (0x00000000U) /*!< LSE clock deactivation */ +#define RCC_LSE_ON (0x00000001U) /*!< LSE clock activation */ +#define RCC_LSE_BYPASS (0x00000005U) /*!< External clock source for LSE clock */ + +/** + * @} + */ + +/** @defgroup RCC_HSI_Config HSI Config + * @{ + */ +#define RCC_HSI_OFF (0x00000000U) /*!< HSI clock deactivation */ +#define RCC_HSI_ON RCC_CR_HSION /*!< HSI clock activation */ + +#define RCC_HSICALIBRATION_DEFAULT (0x10U) /* Default HSI calibration trimming value */ + +/** + * @} + */ + +/** @defgroup RCC_HSI14_Config RCC HSI14 Config + * @{ + */ +#define RCC_HSI14_OFF (0x00000000U) +#define RCC_HSI14_ON RCC_CR2_HSI14ON +#define RCC_HSI14_ADC_CONTROL (~RCC_CR2_HSI14DIS) + +#define RCC_HSI14CALIBRATION_DEFAULT \ + (0x10U) /* Default HSI14 calibration trimming value */ +/** + * @} + */ + +/** @defgroup RCC_LSI_Config LSI Config + * @{ + */ +#define RCC_LSI_OFF (0x00000000U) /*!< LSI clock deactivation */ +#define RCC_LSI_ON RCC_CSR_LSION /*!< LSI clock activation */ + + /** + * @} + */ + +#if defined(RCC_HSI48_SUPPORT) +/** @defgroup RCC_HSI48_Config HSI48 Config + * @{ + */ +#define RCC_HSI48_OFF ((uint8_t)0x00U) +#define RCC_HSI48_ON ((uint8_t)0x01U) + +/** + * @} + */ +#endif /* RCC_HSI48_SUPPORT */ + +/** @defgroup RCC_PLL_Config PLL Config + * @{ + */ +#define RCC_PLL_NONE (0x00000000U) /*!< PLL is not configured */ +#define RCC_PLL_OFF (0x00000001U) /*!< PLL deactivation */ +#define RCC_PLL_ON (0x00000002U) /*!< PLL activation */ + +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Type System Clock Type + * @{ + */ +#define RCC_CLOCKTYPE_SYSCLK (0x00000001U) /*!< SYSCLK to configure */ +#define RCC_CLOCKTYPE_HCLK (0x00000002U) /*!< HCLK to configure */ +#define RCC_CLOCKTYPE_PCLK1 (0x00000004U) /*!< PCLK1 to configure */ + +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source System Clock Source + * @{ + */ +#define RCC_SYSCLKSOURCE_HSI RCC_CFGR_SW_HSI /*!< HSI selected as system clock */ +#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_HSE /*!< HSE selected as system clock */ +#define RCC_SYSCLKSOURCE_PLLCLK RCC_CFGR_SW_PLL /*!< PLL selected as system clock */ + +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status + * @{ + */ +#define RCC_SYSCLKSOURCE_STATUS_HSI RCC_CFGR_SWS_HSI /*!< HSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_HSE /*!< HSE used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_PLLCLK RCC_CFGR_SWS_PLL /*!< PLL used as system clock */ + +/** + * @} + */ + +/** @defgroup RCC_AHB_Clock_Source AHB Clock Source + * @{ + */ +#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1 /*!< SYSCLK not divided */ +#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2 /*!< SYSCLK divided by 2 */ +#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4 /*!< SYSCLK divided by 4 */ +#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8 /*!< SYSCLK divided by 8 */ +#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16 /*!< SYSCLK divided by 16 */ +#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64 /*!< SYSCLK divided by 64 */ +#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128 /*!< SYSCLK divided by 128 */ +#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256 /*!< SYSCLK divided by 256 */ +#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512 /*!< SYSCLK divided by 512 */ + +/** + * @} + */ + +/** @defgroup RCC_APB1_Clock_Source RCC APB1 Clock Source + * @{ + */ +#define RCC_HCLK_DIV1 RCC_CFGR_PPRE_DIV1 /*!< HCLK not divided */ +#define RCC_HCLK_DIV2 RCC_CFGR_PPRE_DIV2 /*!< HCLK divided by 2 */ +#define RCC_HCLK_DIV4 RCC_CFGR_PPRE_DIV4 /*!< HCLK divided by 4 */ +#define RCC_HCLK_DIV8 RCC_CFGR_PPRE_DIV8 /*!< HCLK divided by 8 */ +#define RCC_HCLK_DIV16 RCC_CFGR_PPRE_DIV16 /*!< HCLK divided by 16 */ + +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_Source RTC Clock Source + * @{ + */ +#define RCC_RTCCLKSOURCE_NO_CLK (0x00000000U) /*!< No clock */ +#define RCC_RTCCLKSOURCE_LSE \ + RCC_BDCR_RTCSEL_LSE /*!< LSE oscillator clock used as RTC clock */ +#define RCC_RTCCLKSOURCE_LSI \ + RCC_BDCR_RTCSEL_LSI /*!< LSI oscillator clock used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV32 \ + RCC_BDCR_RTCSEL_HSE /*!< HSE oscillator clock divided by 32 used as RTC clock */ +/** + * @} + */ + +/** @defgroup RCC_PLL_Multiplication_Factor RCC PLL Multiplication Factor + * @{ + */ +#define RCC_PLL_MUL2 RCC_CFGR_PLLMUL2 +#define RCC_PLL_MUL3 RCC_CFGR_PLLMUL3 +#define RCC_PLL_MUL4 RCC_CFGR_PLLMUL4 +#define RCC_PLL_MUL5 RCC_CFGR_PLLMUL5 +#define RCC_PLL_MUL6 RCC_CFGR_PLLMUL6 +#define RCC_PLL_MUL7 RCC_CFGR_PLLMUL7 +#define RCC_PLL_MUL8 RCC_CFGR_PLLMUL8 +#define RCC_PLL_MUL9 RCC_CFGR_PLLMUL9 +#define RCC_PLL_MUL10 RCC_CFGR_PLLMUL10 +#define RCC_PLL_MUL11 RCC_CFGR_PLLMUL11 +#define RCC_PLL_MUL12 RCC_CFGR_PLLMUL12 +#define RCC_PLL_MUL13 RCC_CFGR_PLLMUL13 +#define RCC_PLL_MUL14 RCC_CFGR_PLLMUL14 +#define RCC_PLL_MUL15 RCC_CFGR_PLLMUL15 +#define RCC_PLL_MUL16 RCC_CFGR_PLLMUL16 + + /** + * @} + */ + + /** @defgroup RCC_PLL_Prediv_Factor RCC PLL Prediv Factor + * @{ + */ + +#define RCC_PREDIV_DIV1 RCC_CFGR2_PREDIV_DIV1 +#define RCC_PREDIV_DIV2 RCC_CFGR2_PREDIV_DIV2 +#define RCC_PREDIV_DIV3 RCC_CFGR2_PREDIV_DIV3 +#define RCC_PREDIV_DIV4 RCC_CFGR2_PREDIV_DIV4 +#define RCC_PREDIV_DIV5 RCC_CFGR2_PREDIV_DIV5 +#define RCC_PREDIV_DIV6 RCC_CFGR2_PREDIV_DIV6 +#define RCC_PREDIV_DIV7 RCC_CFGR2_PREDIV_DIV7 +#define RCC_PREDIV_DIV8 RCC_CFGR2_PREDIV_DIV8 +#define RCC_PREDIV_DIV9 RCC_CFGR2_PREDIV_DIV9 +#define RCC_PREDIV_DIV10 RCC_CFGR2_PREDIV_DIV10 +#define RCC_PREDIV_DIV11 RCC_CFGR2_PREDIV_DIV11 +#define RCC_PREDIV_DIV12 RCC_CFGR2_PREDIV_DIV12 +#define RCC_PREDIV_DIV13 RCC_CFGR2_PREDIV_DIV13 +#define RCC_PREDIV_DIV14 RCC_CFGR2_PREDIV_DIV14 +#define RCC_PREDIV_DIV15 RCC_CFGR2_PREDIV_DIV15 +#define RCC_PREDIV_DIV16 RCC_CFGR2_PREDIV_DIV16 + +/** + * @} + */ + + +/** @defgroup RCC_USART1_Clock_Source RCC USART1 Clock Source + * @{ + */ +#define RCC_USART1CLKSOURCE_PCLK1 RCC_CFGR3_USART1SW_PCLK +#define RCC_USART1CLKSOURCE_SYSCLK RCC_CFGR3_USART1SW_SYSCLK +#define RCC_USART1CLKSOURCE_LSE RCC_CFGR3_USART1SW_LSE +#define RCC_USART1CLKSOURCE_HSI RCC_CFGR3_USART1SW_HSI + +/** + * @} + */ + +/** @defgroup RCC_I2C1_Clock_Source RCC I2C1 Clock Source + * @{ + */ +#define RCC_I2C1CLKSOURCE_HSI RCC_CFGR3_I2C1SW_HSI +#define RCC_I2C1CLKSOURCE_SYSCLK RCC_CFGR3_I2C1SW_SYSCLK + +/** + * @} + */ +/** @defgroup RCC_MCO_Index MCO Index + * @{ + */ +#define RCC_MCO1 (0x00000000U) +#define RCC_MCO RCC_MCO1 /*!< MCO1 to be compliant with other families with 2 MCOs*/ + +/** + * @} + */ + +/** @defgroup RCC_MCO_Clock_Source RCC MCO Clock Source + * @{ + */ +#define RCC_MCO1SOURCE_NOCLOCK RCC_CFGR_MCO_NOCLOCK +#define RCC_MCO1SOURCE_LSI RCC_CFGR_MCO_LSI +#define RCC_MCO1SOURCE_LSE RCC_CFGR_MCO_LSE +#define RCC_MCO1SOURCE_SYSCLK RCC_CFGR_MCO_SYSCLK +#define RCC_MCO1SOURCE_HSI RCC_CFGR_MCO_HSI +#define RCC_MCO1SOURCE_HSE RCC_CFGR_MCO_HSE +#define RCC_MCO1SOURCE_PLLCLK_DIV2 RCC_CFGR_MCO_PLL +#define RCC_MCO1SOURCE_HSI14 RCC_CFGR_MCO_HSI14 + +/** + * @} + */ + +/** @defgroup RCC_Interrupt Interrupts + * @{ + */ +#define RCC_IT_LSIRDY ((uint8_t)RCC_CIR_LSIRDYF) /*!< LSI Ready Interrupt flag */ +#define RCC_IT_LSERDY ((uint8_t)RCC_CIR_LSERDYF) /*!< LSE Ready Interrupt flag */ +#define RCC_IT_HSIRDY ((uint8_t)RCC_CIR_HSIRDYF) /*!< HSI Ready Interrupt flag */ +#define RCC_IT_HSERDY ((uint8_t)RCC_CIR_HSERDYF) /*!< HSE Ready Interrupt flag */ +#define RCC_IT_PLLRDY ((uint8_t)RCC_CIR_PLLRDYF) /*!< PLL Ready Interrupt flag */ +#define RCC_IT_HSI14RDY ((uint8_t)RCC_CIR_HSI14RDYF) /*!< HSI14 Ready Interrupt flag */ +#if defined(RCC_CIR_HSI48RDYF) +#define RCC_IT_HSI48RDY ((uint8_t)RCC_CIR_HSI48RDYF) /*!< HSI48 Ready Interrupt flag */ +#endif +#define RCC_IT_CSS ((uint8_t)RCC_CIR_CSSF) /*!< Clock Security System Interrupt flag */ +/** + * @} + */ + +/** @defgroup RCC_Flag Flags + * Elements values convention: XXXYYYYYb + * - YYYYY : Flag position in the register + * - XXX : Register index + * - 001: CR register + * - 010: CR2 register + * - 011: BDCR register + * - 0100: CSR register + * @{ + */ +/* Flags in the CR register */ +#define RCC_FLAG_HSIRDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_HSIRDY_BitNumber)) +#define RCC_FLAG_HSERDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_HSERDY_BitNumber)) +#define RCC_FLAG_PLLRDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_PLLRDY_BitNumber)) +/* Flags in the CR2 register */ +#define RCC_FLAG_HSI14RDY ((uint8_t)((CR2_REG_INDEX << 5U) | RCC_CR2_HSI14RDY_BitNumber)) + +/* Flags in the CSR register */ +#define RCC_FLAG_LSIRDY ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_LSIRDY_BitNumber)) +#if defined(RCC_CSR_V18PWRRSTF) +#define RCC_FLAG_V18PWRRST \ + ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_V18PWRRSTF_BitNumber)) +#endif +#define RCC_FLAG_OBLRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_OBLRSTF_BitNumber)) +#define RCC_FLAG_PINRST \ + ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_PINRSTF_BitNumber)) /*!< PIN reset flag \ + */ +#define RCC_FLAG_PORRST \ + ((uint8_t)((CSR_REG_INDEX << 5U) | \ + RCC_CSR_PORRSTF_BitNumber)) /*!< POR/PDR reset flag */ +#define RCC_FLAG_SFTRST \ + ((uint8_t)((CSR_REG_INDEX << 5U) | \ + RCC_CSR_SFTRSTF_BitNumber)) /*!< Software Reset flag */ +#define RCC_FLAG_IWDGRST \ + ((uint8_t)((CSR_REG_INDEX << 5U) | \ + RCC_CSR_IWDGRSTF_BitNumber)) /*!< Independent Watchdog reset flag */ +#define RCC_FLAG_WWDGRST \ + ((uint8_t)((CSR_REG_INDEX << 5U) | \ + RCC_CSR_WWDGRSTF_BitNumber)) /*!< Window watchdog reset flag */ +#define RCC_FLAG_LPWRRST \ + ((uint8_t)((CSR_REG_INDEX << 5U) | \ + RCC_CSR_LPWRRSTF_BitNumber)) /*!< Low-Power reset flag */ + +/* Flags in the BDCR register */ +#define RCC_FLAG_LSERDY \ + ((uint8_t)((BDCR_REG_INDEX << 5U) | \ + RCC_BDCR_LSERDY_BitNumber)) /*!< External Low Speed oscillator Ready */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Macros RCC Exported Macros + * @{ + */ + +/** @defgroup RCC_AHB_Clock_Enable_Disable RCC AHB Clock Enable Disable + * @brief Enable or disable the AHB peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_GPIOA_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_GPIOB_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOBEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOBEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_GPIOC_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOCEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOCEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_GPIOF_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOFEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOFEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_CRC_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_DMA1_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_SRAM_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_SRAMEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_SRAMEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_FLITF_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_FLITFEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FLITFEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_GPIOA_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOAEN)) +#define __HAL_RCC_GPIOB_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOBEN)) +#define __HAL_RCC_GPIOC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOCEN)) +#define __HAL_RCC_GPIOF_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOFEN)) +#define __HAL_RCC_CRC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_CRCEN)) +#define __HAL_RCC_DMA1_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_DMA1EN)) +#define __HAL_RCC_SRAM_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_SRAMEN)) +#define __HAL_RCC_FLITF_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_FLITFEN)) +/** + * @} + */ + +/** @defgroup RCC_AHB_Peripheral_Clock_Enable_Disable_Status AHB Peripheral Clock Enable + * Disable Status + * @brief Get the enable or disable status of the AHB peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_GPIOA_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOAEN)) != RESET) +#define __HAL_RCC_GPIOB_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOBEN)) != RESET) +#define __HAL_RCC_GPIOC_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOCEN)) != RESET) +#define __HAL_RCC_GPIOF_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOFEN)) != RESET) +#define __HAL_RCC_CRC_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_CRCEN)) != RESET) +#define __HAL_RCC_DMA1_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA1EN)) != RESET) +#define __HAL_RCC_SRAM_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_SRAMEN)) != RESET) +#define __HAL_RCC_FLITF_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_FLITFEN)) != RESET) +#define __HAL_RCC_GPIOA_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOAEN)) == RESET) +#define __HAL_RCC_GPIOB_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOBEN)) == RESET) +#define __HAL_RCC_GPIOC_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOCEN)) == RESET) +#define __HAL_RCC_GPIOF_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOFEN)) == RESET) +#define __HAL_RCC_CRC_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_CRCEN)) == RESET) +#define __HAL_RCC_DMA1_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA1EN)) == RESET) +#define __HAL_RCC_SRAM_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_SRAMEN)) == RESET) +#define __HAL_RCC_FLITF_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_FLITFEN)) == RESET) +/** + * @} + */ + +/** @defgroup RCC_APB1_Clock_Enable_Disable RCC APB1 Clock Enable Disable + * @brief Enable or disable the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_TIM3_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_TIM14_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_WWDG_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_I2C1_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_PWR_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_TIM3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM3EN)) +#define __HAL_RCC_TIM14_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM14EN)) +#define __HAL_RCC_WWDG_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_WWDGEN)) +#define __HAL_RCC_I2C1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_PWR_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_PWREN)) +/** + * @} + */ + +/** @defgroup RCC_APB1_Peripheral_Clock_Enable_Disable_Status APB1 Peripheral Clock Enable + * Disable Status + * @brief Get the enable or disable status of the APB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_TIM3_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM3EN)) != RESET) +#define __HAL_RCC_TIM14_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM14EN)) != RESET) +#define __HAL_RCC_WWDG_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_WWDGEN)) != RESET) +#define __HAL_RCC_I2C1_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C1EN)) != RESET) +#define __HAL_RCC_PWR_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_PWREN)) != RESET) +#define __HAL_RCC_TIM3_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM3EN)) == RESET) +#define __HAL_RCC_TIM14_IS_CLK_DISABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_TIM14EN)) == RESET) +#define __HAL_RCC_WWDG_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_WWDGEN)) == RESET) +#define __HAL_RCC_I2C1_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C1EN)) == RESET) +#define __HAL_RCC_PWR_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_PWREN)) == RESET) +/** + * @} + */ + + +/** @defgroup RCC_APB2_Clock_Enable_Disable RCC APB2 Clock Enable Disable + * @brief Enable or disable the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_SYSCFG_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_ADC1_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_TIM1_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_SPI1_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_TIM16_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_TIM17_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_USART1_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_DBGMCU_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_DBGMCUEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_DBGMCUEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_SYSCFG_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SYSCFGEN)) +#define __HAL_RCC_ADC1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN)) +#define __HAL_RCC_TIM1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM1EN)) +#define __HAL_RCC_SPI1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI1EN)) +#define __HAL_RCC_TIM16_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM16EN)) +#define __HAL_RCC_TIM17_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM17EN)) +#define __HAL_RCC_USART1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN)) +#define __HAL_RCC_DBGMCU_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_DBGMCUEN)) +/** + * @} + */ + +/** @defgroup RCC_APB2_Peripheral_Clock_Enable_Disable_Status APB2 Peripheral Clock Enable + * Disable Status + * @brief Get the enable or disable status of the APB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_SYSCFG_IS_CLK_ENABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_SYSCFGEN)) != RESET) +#define __HAL_RCC_ADC1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_ADC1EN)) != RESET) +#define __HAL_RCC_TIM1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM1EN)) != RESET) +#define __HAL_RCC_SPI1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SPI1EN)) != RESET) +#define __HAL_RCC_TIM16_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM16EN)) != RESET) +#define __HAL_RCC_TIM17_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM17EN)) != RESET) +#define __HAL_RCC_USART1_IS_CLK_ENABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_USART1EN)) != RESET) +#define __HAL_RCC_DBGMCU_IS_CLK_ENABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_DBGMCUEN)) != RESET) +#define __HAL_RCC_SYSCFG_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_SYSCFGEN)) == RESET) +#define __HAL_RCC_ADC1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_ADC1EN)) == RESET) +#define __HAL_RCC_TIM1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM1EN)) == RESET) +#define __HAL_RCC_SPI1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SPI1EN)) == RESET) +#define __HAL_RCC_TIM16_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_TIM16EN)) == RESET) +#define __HAL_RCC_TIM17_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_TIM17EN)) == RESET) +#define __HAL_RCC_USART1_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_USART1EN)) == RESET) +#define __HAL_RCC_DBGMCU_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_DBGMCUEN)) == RESET) +/** + * @} + */ + +/** @defgroup RCC_AHB_Force_Release_Reset RCC AHB Force Release Reset + * @brief Force or release AHB peripheral reset. + * @{ + */ +#define __HAL_RCC_AHB_FORCE_RESET() (RCC->AHBRSTR = 0xFFFFFFFFU) +#define __HAL_RCC_GPIOA_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOARST)) +#define __HAL_RCC_GPIOB_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOBRST)) +#define __HAL_RCC_GPIOC_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOCRST)) +#define __HAL_RCC_GPIOF_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOFRST)) + +#define __HAL_RCC_AHB_RELEASE_RESET() (RCC->AHBRSTR = 0x00000000U) +#define __HAL_RCC_GPIOA_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOARST)) +#define __HAL_RCC_GPIOB_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOBRST)) +#define __HAL_RCC_GPIOC_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOCRST)) +#define __HAL_RCC_GPIOF_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOFRST)) +/** + * @} + */ + +/** @defgroup RCC_APB1_Force_Release_Reset RCC APB1 Force Release Reset + * @brief Force or release APB1 peripheral reset. + * @{ + */ +#define __HAL_RCC_APB1_FORCE_RESET() (RCC->APB1RSTR = 0xFFFFFFFFU) +#define __HAL_RCC_TIM3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM3RST)) +#define __HAL_RCC_TIM14_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_WWDG_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_WWDGRST)) +#define __HAL_RCC_I2C1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_PWR_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_PWRRST)) + +#define __HAL_RCC_APB1_RELEASE_RESET() (RCC->APB1RSTR = 0x00000000U) +#define __HAL_RCC_TIM3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM3RST)) +#define __HAL_RCC_TIM14_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_WWDG_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_WWDGRST)) +#define __HAL_RCC_I2C1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_PWR_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_PWRRST)) +/** + * @} + */ + +/** @defgroup RCC_APB2_Force_Release_Reset RCC APB2 Force Release Reset + * @brief Force or release APB2 peripheral reset. + * @{ + */ +#define __HAL_RCC_APB2_FORCE_RESET() (RCC->APB2RSTR = 0xFFFFFFFFU) +#define __HAL_RCC_SYSCFG_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SYSCFGRST)) +#define __HAL_RCC_ADC1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_ADC1RST)) +#define __HAL_RCC_TIM1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM1RST)) +#define __HAL_RCC_SPI1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_USART1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART1RST)) +#define __HAL_RCC_TIM16_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM16RST)) +#define __HAL_RCC_TIM17_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM17RST)) +#define __HAL_RCC_DBGMCU_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_DBGMCURST)) + +#define __HAL_RCC_APB2_RELEASE_RESET() (RCC->APB2RSTR = 0x00000000U) +#define __HAL_RCC_SYSCFG_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SYSCFGRST)) +#define __HAL_RCC_ADC1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_ADC1RST)) +#define __HAL_RCC_TIM1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM1RST)) +#define __HAL_RCC_SPI1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_USART1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART1RST)) +#define __HAL_RCC_TIM16_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM16RST)) +#define __HAL_RCC_TIM17_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM17RST)) +#define __HAL_RCC_DBGMCU_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_DBGMCURST)) +/** + * @} + */ +/** @defgroup RCC_HSI_Configuration HSI Configuration + * @{ + */ + +/** @brief Macros to enable or disable the Internal High Speed oscillator (HSI). + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * @note HSI can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI. + * @note After enabling the HSI, the application software should wait on HSIRDY + * flag to be set indicating that HSI clock is stable and can be used as + * system clock source. + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + */ +#define __HAL_RCC_HSI_ENABLE() SET_BIT(RCC->CR, RCC_CR_HSION) +#define __HAL_RCC_HSI_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_HSION) + +/** @brief Macro to adjust the Internal High Speed oscillator (HSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI RC. + * @param _HSICALIBRATIONVALUE_ specifies the calibration trimming value. + * (default is RCC_HSICALIBRATION_DEFAULT). + * This parameter must be a number between 0 and 0x1F. + */ +#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(_HSICALIBRATIONVALUE_) \ + MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, \ + (uint32_t)(_HSICALIBRATIONVALUE_) << RCC_CR_HSITRIM_BitNumber) + +/** + * @} + */ + +/** @defgroup RCC_LSI_Configuration LSI Configuration + * @{ + */ + +/** @brief Macro to enable the Internal Low Speed oscillator (LSI). + * @note After enabling the LSI, the application software should wait on + * LSIRDY flag to be set indicating that LSI clock is stable and can + * be used to clock the IWDG and/or the RTC. + */ +#define __HAL_RCC_LSI_ENABLE() SET_BIT(RCC->CSR, RCC_CSR_LSION) + +/** @brief Macro to disable the Internal Low Speed oscillator (LSI). + * @note LSI can not be disabled if the IWDG is running. + * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator + * clock cycles. + */ +#define __HAL_RCC_LSI_DISABLE() CLEAR_BIT(RCC->CSR, RCC_CSR_LSION) + +/** + * @} + */ + +/** @defgroup RCC_HSE_Configuration HSE Configuration + * @{ + */ + +/** + * @brief Macro to configure the External High Speed oscillator (HSE). + * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not + * supported by this macro. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application + * software should wait on HSERDY flag to be set indicating that HSE clock + * is stable and can be used to clock the PLL and/or system clock. + * @note HSE state can not be changed if it is used directly or through the + * PLL as system clock. In this case, you have to select another source + * of the system clock then change the HSE state (ex. disable it). + * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. + * @note This function reset the CSSON bit, so if the clock security system(CSS) + * was previously enabled you have to enable it again after calling this + * function. + * @param __STATE__ specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg @ref RCC_HSE_OFF turn OFF the HSE oscillator, HSERDY flag goes low + * after 6 HSE oscillator clock cycles. + * @arg @ref RCC_HSE_ON turn ON the HSE oscillator + * @arg @ref RCC_HSE_BYPASS HSE oscillator bypassed with external clock + */ +#define __HAL_RCC_HSE_CONFIG(__STATE__) \ + do \ + { \ + if ((__STATE__) == RCC_HSE_ON) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else if ((__STATE__) == RCC_HSE_OFF) \ + { \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \ + } \ + else if ((__STATE__) == RCC_HSE_BYPASS) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEBYP); \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else \ + { \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \ + } \ + } while (0U) + +/** + * @brief Macro to configure the External High Speed oscillator (HSE) Predivision factor + * for PLL. + * @note Predivision factor can not be changed if PLL is used as system clock + * In this case, you have to select another source of the system clock, disable + * the PLL and then change the HSE predivision factor. + * @param __HSE_PREDIV_VALUE__ specifies the division value applied to HSE. + * This parameter must be a number between RCC_HSE_PREDIV_DIV1 and + * RCC_HSE_PREDIV_DIV16. + */ +#define __HAL_RCC_HSE_PREDIV_CONFIG(__HSE_PREDIV_VALUE__) \ + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV, (uint32_t)(__HSE_PREDIV_VALUE__)) + +/** + * @} + */ + +/** @defgroup RCC_LSE_Configuration LSE Configuration + * @{ + */ + +/** + * @brief Macro to configure the External Low Speed oscillator (LSE). + * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not supported by + * this macro. + * @note As the LSE is in the Backup domain and write access is denied to + * this domain after reset, you have to enable write access using + * @ref HAL_PWR_EnableBkUpAccess() function before to configure the LSE + * (to be done once after reset). + * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_BYPASS), the application + * software should wait on LSERDY flag to be set indicating that LSE clock + * is stable and can be used to clock the RTC. + * @param __STATE__ specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg @ref RCC_LSE_OFF turn OFF the LSE oscillator, LSERDY flag goes low + * after 6 LSE oscillator clock cycles. + * @arg @ref RCC_LSE_ON turn ON the LSE oscillator. + * @arg @ref RCC_LSE_BYPASS LSE oscillator bypassed with external clock. + */ +#define __HAL_RCC_LSE_CONFIG(__STATE__) \ + do \ + { \ + if ((__STATE__) == RCC_LSE_ON) \ + { \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + } \ + else if ((__STATE__) == RCC_LSE_OFF) \ + { \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + } \ + else if ((__STATE__) == RCC_LSE_BYPASS) \ + { \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + } \ + else \ + { \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + } \ + } while (0U) + +/** + * @} + */ + +/** @defgroup RCC_HSI14_Configuration RCC_HSI14_Configuration + * @{ + */ + +/** @brief Macro to enable the Internal 14Mhz High Speed oscillator (HSI14). + * @note After enabling the HSI14 with @ref __HAL_RCC_HSI14_ENABLE(), the application + * software should wait on HSI14RDY flag to be set indicating that HSI clock is stable and + * can be used as system clock source. This is not necessary if @ref HAL_RCC_OscConfig() + * is used. clock cycles. + */ +#define __HAL_RCC_HSI14_ENABLE() SET_BIT(RCC->CR2, RCC_CR2_HSI14ON) + +/** @brief Macro to disable the Internal 14Mhz High Speed oscillator (HSI14). + * @note The HSI14 is stopped by hardware when entering STOP and STANDBY modes. + * @note HSI14 can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI14. + * @note When the HSI14 is stopped, HSI14RDY flag goes low after 6 HSI14 oscillator + * clock cycles. + */ +#define __HAL_RCC_HSI14_DISABLE() CLEAR_BIT(RCC->CR2, RCC_CR2_HSI14ON) + +/** @brief Macro to enable the Internal 14Mhz High Speed oscillator (HSI14) used by ADC. + */ +#define __HAL_RCC_HSI14ADC_ENABLE() CLEAR_BIT(RCC->CR2, RCC_CR2_HSI14DIS) + +/** @brief Macro to disable the Internal 14Mhz High Speed oscillator (HSI14) used by ADC. + */ +#define __HAL_RCC_HSI14ADC_DISABLE() SET_BIT(RCC->CR2, RCC_CR2_HSI14DIS) + +/** @brief Macro to adjust the Internal 14Mhz High Speed oscillator (HSI) calibration + * value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI14 RC. + * @param __HSI14CALIBRATIONVALUE__ specifies the calibration trimming value + * (default is RCC_HSI14CALIBRATION_DEFAULT). + * This parameter must be a number between 0 and 0x1F. + */ +#define __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(__HSI14CALIBRATIONVALUE__) \ + MODIFY_REG(RCC->CR2, RCC_CR2_HSI14TRIM, \ + (uint32_t)(__HSI14CALIBRATIONVALUE__) << RCC_HSI14TRIM_BIT_NUMBER) +/** + * @} + */ + +/** @defgroup RCC_USARTx_Clock_Config RCC USARTx Clock Config + * @{ + */ + +/** @brief Macro to configure the USART1 clock (USART1CLK). + * @param __USART1CLKSOURCE__ specifies the USART1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART1CLKSOURCE_PCLK1 PCLK1 selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_SYSCLK System Clock selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock + */ +#define __HAL_RCC_USART1_CONFIG(__USART1CLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USART1SW, (uint32_t)(__USART1CLKSOURCE__)) + +/** @brief Macro to get the USART1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART1CLKSOURCE_PCLK1 PCLK1 selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_SYSCLK System Clock selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock + */ +#define __HAL_RCC_GET_USART1_SOURCE() \ + ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_USART1SW))) + +/** + * @} + */ + +/** @defgroup RCC_I2Cx_Clock_Config RCC I2Cx Clock Config + * @{ + */ + +/** @brief Macro to configure the I2C1 clock (I2C1CLK). + * @param __I2C1CLKSOURCE__ specifies the I2C1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_I2C1CLKSOURCE_HSI HSI selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_SYSCLK System Clock selected as I2C1 clock + */ +#define __HAL_RCC_I2C1_CONFIG(__I2C1CLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_I2C1SW, (uint32_t)(__I2C1CLKSOURCE__)) + +/** @brief Macro to get the I2C1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_I2C1CLKSOURCE_HSI HSI selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_SYSCLK System Clock selected as I2C1 clock + */ +#define __HAL_RCC_GET_I2C1_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_I2C1SW))) +/** + * @} + */ + +/** @defgroup RCC_PLL_Configuration PLL Configuration + * @{ + */ + +/** @brief Macro to enable the main PLL. + * @note After enabling the main PLL, the application software should wait on + * PLLRDY flag to be set indicating that PLL clock is stable and can + * be used as system clock source. + * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes. + */ +#define __HAL_RCC_PLL_ENABLE() SET_BIT(RCC->CR, RCC_CR_PLLON) + +/** @brief Macro to disable the main PLL. + * @note The main PLL can not be disabled if it is used as system clock source + */ +#define __HAL_RCC_PLL_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_PLLON) + +/** @brief Macro to configure the PLL clock source, multiplication and division factors. + * @note This function must be used only when the main PLL is disabled. + * + * @param __RCC_PLLSOURCE__ specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_PLLSOURCE_HSI HSI oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL clock entry + * @param __PLLMUL__ specifies the multiplication factor for PLL VCO output clock + * This parameter can be one of the following values: + * This parameter must be a number between RCC_PLL_MUL2 and RCC_PLL_MUL16. + * @param __PREDIV__ specifies the predivider factor for PLL VCO input clock + * This parameter must be a number between RCC_PREDIV_DIV1 and RCC_PREDIV_DIV16. + * + */ +#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSOURCE__, __PREDIV__, __PLLMUL__) \ + do \ + { \ + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV, (__PREDIV__)); \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC, \ + (uint32_t)((__PLLMUL__) | (__RCC_PLLSOURCE__))); \ + } while (0U) + + +/** @brief Get oscillator clock selected as PLL input clock + * @retval The clock source used for PLL entry. The returned value can be one + * of the following: + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL input + * clock + */ +#define __HAL_RCC_GET_PLL_OSCSOURCE() ((uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PLLSRC))) + +/** + * @} + */ + +/** @defgroup RCC_Get_Clock_source Get Clock source + * @{ + */ + +/** + * @brief Macro to configure the system clock source. + * @param __SYSCLKSOURCE__ specifies the system clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_SYSCLKSOURCE_HSI HSI oscillator is used as system clock + * source. + * @arg @ref RCC_SYSCLKSOURCE_HSE HSE oscillator is used as system clock + * source. + * @arg @ref RCC_SYSCLKSOURCE_PLLCLK PLL output is used as system clock + * source. + */ +#define __HAL_RCC_SYSCLK_CONFIG(__SYSCLKSOURCE__) \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, (__SYSCLKSOURCE__)) + +/** @brief Macro to get the clock source used as system clock. + * @retval The clock source used as system clock. The returned value can be one + * of the following: + * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSI HSI used as system clock + * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSE HSE used as system clock + * @arg @ref RCC_SYSCLKSOURCE_STATUS_PLLCLK PLL used as system clock + */ +#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(RCC->CFGR & RCC_CFGR_SWS)) + + /** + * @} + */ + + /** @defgroup RCCEx_MCOx_Clock_Config RCC Extended MCOx Clock Config + * @{ + */ + +#if defined(RCC_CFGR_MCOPRE) +/** @brief Macro to configure the MCO clock. + * @param __MCOCLKSOURCE__ specifies the MCO clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_SYSCLK System Clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI oscillator clock selected as MCO + clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI14 HSI14 selected as MCO clock + @if STM32F042x6 + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F048xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F071xB + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F072xB + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F078xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F091xC + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F098xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F030x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F030xC + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F031x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F038xx + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F070x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F070xB + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @endif + * @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO + clock + * @param __MCODIV__ specifies the MCO clock prescaler. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 MCO clock source is divided by 1 + * @arg @ref RCC_MCODIV_2 MCO clock source is divided by 2 + * @arg @ref RCC_MCODIV_4 MCO clock source is divided by 4 + * @arg @ref RCC_MCODIV_8 MCO clock source is divided by 8 + * @arg @ref RCC_MCODIV_16 MCO clock source is divided by 16 + * @arg @ref RCC_MCODIV_32 MCO clock source is divided by 32 + * @arg @ref RCC_MCODIV_64 MCO clock source is divided by 64 + * @arg @ref RCC_MCODIV_128 MCO clock source is divided by 128 + */ +#else +/** @brief Macro to configure the MCO clock. + * @param __MCOCLKSOURCE__ specifies the MCO clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_SYSCLK System Clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI14 HSI14 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO + * clock + * @param __MCODIV__ specifies the MCO clock prescaler. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 No division applied on MCO clock source + */ +#endif +#if defined(RCC_CFGR_MCOPRE) +#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO | RCC_CFGR_MCOPRE), \ + ((__MCOCLKSOURCE__) | (__MCODIV__))) +#else + +#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_MCO, (__MCOCLKSOURCE__)) + +#endif + + /** + * @} + */ + + /** @defgroup RCC_RTC_Clock_Configuration RCC RTC Clock Configuration + * @{ + */ + +/** @brief Macro to configure the RTC clock (RTCCLK). + * @note As the RTC clock configuration bits are in the Backup domain and write + * access is denied to this domain after reset, you have to enable write + * access using the Power Backup Access macro before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it cannot be changed unless the + * Backup domain is reset using @ref __HAL_RCC_BACKUPRESET_FORCE() macro, or by + * a Power On Reset (POR). + * + * @param __RTC_CLKSOURCE__ specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV32 HSE clock divided by 32 + * @note If the LSE or LSI is used as RTC clock source, the RTC continues to + * work in STOP and STANDBY modes, and can be used as wakeup source. + * However, when the LSI clock and HSE clock divided by 32 is used as RTC clock + * source, the RTC cannot be used in STOP and STANDBY modes. + * @note The system must always be configured so as to get a PCLK frequency greater than + * or equal to the RTCCLK frequency for a proper operation of the RTC. + */ +#define __HAL_RCC_RTC_CONFIG(__RTC_CLKSOURCE__) \ + MODIFY_REG(RCC->BDCR, RCC_BDCR_RTCSEL, (__RTC_CLKSOURCE__)) + +/** @brief Macro to get the RTC clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV32 HSE clock divided by 32 + */ +#define __HAL_RCC_GET_RTC_SOURCE() (READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL)) + +/** @brief Macro to enable the the RTC clock. + * @note These macros must be used only after the RTC clock source was selected. + */ +#define __HAL_RCC_RTC_ENABLE() SET_BIT(RCC->BDCR, RCC_BDCR_RTCEN) + +/** @brief Macro to disable the the RTC clock. + * @note These macros must be used only after the RTC clock source was selected. + */ +#define __HAL_RCC_RTC_DISABLE() CLEAR_BIT(RCC->BDCR, RCC_BDCR_RTCEN) + +/** @brief Macro to force the Backup domain reset. + * @note This function resets the RTC peripheral (including the backup registers) + * and the RTC clock source selection in RCC_BDCR register. + */ +#define __HAL_RCC_BACKUPRESET_FORCE() SET_BIT(RCC->BDCR, RCC_BDCR_BDRST) + +/** @brief Macros to release the Backup domain reset. + */ +#define __HAL_RCC_BACKUPRESET_RELEASE() CLEAR_BIT(RCC->BDCR, RCC_BDCR_BDRST) + +/** + * @} + */ + +/** @defgroup RCC_Flags_Interrupts_Management Flags Interrupts Management + * @brief macros to manage the specified RCC Flags and interrupts. + * @{ + */ + +/** @brief Enable RCC interrupt. + * @param __INTERRUPT__ specifies the RCC interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt + * @arg @ref RCC_IT_HSI14RDY HSI14 ready interrupt + @if STM32F042x6 + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F048xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F071xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F072xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F078xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F091xC + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F098xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @endif + */ +#define __HAL_RCC_ENABLE_IT(__INTERRUPT__) \ + (*(__IO uint8_t *)RCC_CIR_BYTE1_ADDRESS |= (__INTERRUPT__)) + +/** @brief Disable RCC interrupt. + * @param __INTERRUPT__ specifies the RCC interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt + * @arg @ref RCC_IT_HSI14RDY HSI14 ready interrupt + @if STM32F042x6 + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F048xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F071xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F072xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F078xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F091xC + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F098xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @endif + */ +#define __HAL_RCC_DISABLE_IT(__INTERRUPT__) \ + (*(__IO uint8_t *)RCC_CIR_BYTE1_ADDRESS &= (uint8_t)(~(__INTERRUPT__))) + +/** @brief Clear the RCC's interrupt pending bits. + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt. + * @arg @ref RCC_IT_LSERDY LSE ready interrupt. + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt. + * @arg @ref RCC_IT_HSERDY HSE ready interrupt. + * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt. + * @arg @ref RCC_IT_CSS Clock Security System interrupt + * @arg @ref RCC_IT_HSI14RDY HSI14 ready interrupt + @if STM32F042x6 + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F048xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F071xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F072xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F078xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F091xC + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F098xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @endif + */ +#define __HAL_RCC_CLEAR_IT(__INTERRUPT__) \ + (*(__IO uint8_t *)RCC_CIR_BYTE2_ADDRESS = (__INTERRUPT__)) + +/** @brief Check the RCC's interrupt has occurred or not. + * @param __INTERRUPT__ specifies the RCC interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt. + * @arg @ref RCC_IT_LSERDY LSE ready interrupt. + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt. + * @arg @ref RCC_IT_HSERDY HSE ready interrupt. + * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt. + * @arg @ref RCC_IT_CSS Clock Security System interrupt + * @arg @ref RCC_IT_HSI14RDY HSI14 ready interrupt enable + @if STM32F042x6 + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F048xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F071xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F072xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F078xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F091xC + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F098xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @endif + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_RCC_GET_IT(__INTERRUPT__) ((RCC->CIR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Set RMVF bit to clear the reset flags. + * The reset flags are RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, + * RCC_FLAG_OBLRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST + */ +#define __HAL_RCC_CLEAR_RESET_FLAGS() (RCC->CSR |= RCC_CSR_RMVF) + +/** @brief Check RCC flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref RCC_FLAG_HSIRDY HSI oscillator clock ready. + * @arg @ref RCC_FLAG_HSERDY HSE oscillator clock ready. + * @arg @ref RCC_FLAG_PLLRDY Main PLL clock ready. + * @arg @ref RCC_FLAG_HSI14RDY HSI14 oscillator clock ready + @if STM32F038xx + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @elseif STM32F042x6 + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + @elseif STM32F048xx + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @elseif STM32F058xx + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @elseif STM32F071xB + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + @elseif STM32F072xB + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + @elseif STM32F078xx + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @elseif STM32F091xC + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + @elseif STM32F098xx + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @endif + * @arg @ref RCC_FLAG_LSERDY LSE oscillator clock ready. + * @arg @ref RCC_FLAG_LSIRDY LSI oscillator clock ready. + * @arg @ref RCC_FLAG_OBLRST Option Byte Load reset + * @arg @ref RCC_FLAG_PINRST Pin reset. + * @arg @ref RCC_FLAG_PORRST POR/PDR reset. + * @arg @ref RCC_FLAG_SFTRST Software reset. + * @arg @ref RCC_FLAG_IWDGRST Independent Watchdog reset. + * @arg @ref RCC_FLAG_WWDGRST Window Watchdog reset. + * @arg @ref RCC_FLAG_LPWRRST Low Power reset. + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_RCC_GET_FLAG(__FLAG__) \ + (((((__FLAG__) >> 5U) == CR_REG_INDEX) ? RCC->CR \ + : (((__FLAG__) >> 5U) == CR2_REG_INDEX) ? RCC->CR2 \ + : (((__FLAG__) >> 5U) == BDCR_REG_INDEX) ? RCC->BDCR \ + : RCC->CSR) & \ + (1U << ((__FLAG__)&RCC_FLAG_MASK))) + +/** + * @} + */ + +/** + * @} + */ + +/* Include RCC HAL Extension module */ +#include "stm32f0xx_hal_rcc_ex.h" + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup RCC_Exported_Functions + * @{ + */ + + /** @addtogroup RCC_Exported_Functions_Group1 + * @{ + */ + + /* Initialization and de-initialization functions ******************************/ + HAL_StatusTypeDef HAL_RCC_DeInit(void); + HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); + HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, + uint32_t FLatency); + + /** + * @} + */ + + /** @addtogroup RCC_Exported_Functions_Group2 + * @{ + */ + + /* Peripheral Control functions ************************************************/ + void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, + uint32_t RCC_MCODiv); + void HAL_RCC_EnableCSS(void); + /* CSS NMI IRQ handler */ + void HAL_RCC_NMI_IRQHandler(void); + /* User Callbacks in non blocking mode (IT mode) */ + void HAL_RCC_CSSCallback(void); + void HAL_RCC_DisableCSS(void); + uint32_t HAL_RCC_GetSysClockFreq(void); + uint32_t HAL_RCC_GetHCLKFreq(void); + uint32_t HAL_RCC_GetPCLK1Freq(void); + void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); + void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, + uint32_t *pFLatency); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_RCC_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc_ex.h new file mode 100644 index 0000000000..1e450d56c7 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_rcc_ex.h @@ -0,0 +1,2220 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_rcc_ex.h + * @author MCD Application Team + * @brief Header file of RCC HAL Extension module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_RCC_EX_H +#define __STM32F0xx_HAL_RCC_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/** @addtogroup RCC_Private_Macros + * @{ + */ +#if defined(RCC_HSI48_SUPPORT) +#define IS_RCC_OSCILLATORTYPE(OSCILLATOR) \ + (((OSCILLATOR) == RCC_OSCILLATORTYPE_NONE) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)) + +#define IS_RCC_SYSCLKSOURCE(SOURCE) \ + (((SOURCE) == RCC_SYSCLKSOURCE_HSI) || ((SOURCE) == RCC_SYSCLKSOURCE_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_PLLCLK) || ((SOURCE) == RCC_SYSCLKSOURCE_HSI48)) + +#define IS_RCC_SYSCLKSOURCE_STATUS(SOURCE) \ + (((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSI) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_PLLCLK) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSI48)) + +#define IS_RCC_PLLSOURCE(SOURCE) \ + (((SOURCE) == RCC_PLLSOURCE_HSI) || ((SOURCE) == RCC_PLLSOURCE_HSI48) || \ + ((SOURCE) == RCC_PLLSOURCE_HSE)) + +#define IS_RCC_HSI48(HSI48) (((HSI48) == RCC_HSI48_OFF) || ((HSI48) == RCC_HSI48_ON)) + +#else + +#define IS_RCC_OSCILLATORTYPE(OSCILLATOR) \ + (((OSCILLATOR) == RCC_OSCILLATORTYPE_NONE) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) || \ + (((OSCILLATOR)&RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14)) +#define IS_RCC_SYSCLKSOURCE(SOURCE) \ + (((SOURCE) == RCC_SYSCLKSOURCE_HSI) || ((SOURCE) == RCC_SYSCLKSOURCE_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_PLLCLK)) + +#define IS_RCC_SYSCLKSOURCE_STATUS(SOURCE) \ + (((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSI) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_PLLCLK)) +#define IS_RCC_PLLSOURCE(SOURCE) \ + (((SOURCE) == RCC_PLLSOURCE_HSI) || ((SOURCE) == RCC_PLLSOURCE_HSE)) + +#endif /* RCC_HSI48_SUPPORT */ + +#if defined(RCC_CFGR_PLLNODIV) && !defined(RCC_CFGR_MCO_HSI48) + +#define IS_RCC_MCO1SOURCE(SOURCE) \ + (((SOURCE) == RCC_MCO1SOURCE_NOCLOCK) || ((SOURCE) == RCC_MCO1SOURCE_LSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSE) || ((SOURCE) == RCC_MCO1SOURCE_SYSCLK) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI) || ((SOURCE) == RCC_MCO1SOURCE_HSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_PLLCLK) || ((SOURCE) == RCC_MCO1SOURCE_PLLCLK_DIV2) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI14)) + +#elif defined(RCC_CFGR_PLLNODIV) && defined(RCC_CFGR_MCO_HSI48) + +#define IS_RCC_MCO1SOURCE(SOURCE) \ + (((SOURCE) == RCC_MCO1SOURCE_NOCLOCK) || ((SOURCE) == RCC_MCO1SOURCE_LSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSE) || ((SOURCE) == RCC_MCO1SOURCE_SYSCLK) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI) || ((SOURCE) == RCC_MCO1SOURCE_HSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_PLLCLK) || ((SOURCE) == RCC_MCO1SOURCE_PLLCLK_DIV2) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI14) || ((SOURCE) == RCC_MCO1SOURCE_HSI48)) + +#elif !defined(RCC_CFGR_PLLNODIV) && !defined(RCC_CFGR_MCO_HSI48) + +#define IS_RCC_MCO1SOURCE(SOURCE) \ + (((SOURCE) == RCC_MCO1SOURCE_NOCLOCK) || ((SOURCE) == RCC_MCO1SOURCE_LSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSE) || ((SOURCE) == RCC_MCO1SOURCE_SYSCLK) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI) || ((SOURCE) == RCC_MCO1SOURCE_HSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_PLLCLK_DIV2) || ((SOURCE) == RCC_MCO1SOURCE_HSI14)) + +#endif /* RCC_CFGR_PLLNODIV && !RCC_CFGR_MCO_HSI48 */ + +/** + * @} + */ + +/** @addtogroup RCC_Exported_Constants + * @{ + */ +#if defined(RCC_HSI48_SUPPORT) + +/** @addtogroup RCC_PLL_Clock_Source + * @{ + */ +#define RCC_PLLSOURCE_HSI RCC_CFGR_PLLSRC_HSI_PREDIV +#define RCC_PLLSOURCE_HSI48 RCC_CFGR_PLLSRC_HSI48_PREDIV + +/** + * @} + */ + +/** @addtogroup RCC_Interrupt + * @{ + */ +#define RCC_IT_HSI48 RCC_CIR_HSI48RDYF /*!< HSI48 Ready Interrupt flag */ +/** + * @} + */ + +/** @addtogroup RCC_Flag + * @{ + */ +#define RCC_FLAG_HSI48RDY ((uint8_t)((CR2_REG_INDEX << 5U) | RCC_CR2_HSI48RDY_BitNumber)) +/** + * @} + */ + +/** @addtogroup RCC_System_Clock_Source + * @{ + */ +#define RCC_SYSCLKSOURCE_HSI48 RCC_CFGR_SW_HSI48 +/** + * @} + */ + +/** @addtogroup RCC_System_Clock_Source_Status + * @{ + */ +#define RCC_SYSCLKSOURCE_STATUS_HSI48 RCC_CFGR_SWS_HSI48 + /** + * @} + */ + +#else +/** @addtogroup RCC_PLL_Clock_Source + * @{ + */ + +#if defined(STM32F070xB) || defined(STM32F070x6) || defined(STM32F030xC) +#define RCC_PLLSOURCE_HSI RCC_CFGR_PLLSRC_HSI_PREDIV +#else +#define RCC_PLLSOURCE_HSI RCC_CFGR_PLLSRC_HSI_DIV2 +#endif + +/** + * @} + */ + +#endif /* RCC_HSI48_SUPPORT */ + + /** @addtogroup RCC_MCO_Clock_Source + * @{ + */ + +#if defined(RCC_CFGR_PLLNODIV) + +#define RCC_MCO1SOURCE_PLLCLK (RCC_CFGR_MCO_PLL | RCC_CFGR_PLLNODIV) + +#endif /* RCC_CFGR_PLLNODIV */ + +#if defined(RCC_CFGR_MCO_HSI48) + +#define RCC_MCO1SOURCE_HSI48 RCC_CFGR_MCO_HSI48 + +#endif /* SRCC_CFGR_MCO_HSI48 */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup RCCEx + * @{ + */ + +/* Private Constants -------------------------------------------------------------*/ +#if defined(CRS) +/** @addtogroup RCCEx_Private_Constants + * @{ + */ + +/* CRS IT Error Mask */ +#define RCC_CRS_IT_ERROR_MASK \ + ((uint32_t)(RCC_CRS_IT_TRIMOVF | RCC_CRS_IT_SYNCERR | RCC_CRS_IT_SYNCMISS)) + +/* CRS Flag Error Mask */ +#define RCC_CRS_FLAG_ERROR_MASK \ + ((uint32_t)(RCC_CRS_FLAG_TRIMOVF | RCC_CRS_FLAG_SYNCERR | RCC_CRS_FLAG_SYNCMISS)) + +/** + * @} + */ +#endif /* CRS */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup RCCEx_Private_Macros RCCEx Private Macros + * @{ + */ +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || \ + defined(STM32F038xx) || defined(STM32F030xC) + +#define IS_RCC_PERIPHCLOCK(SELECTION) \ + ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC)) +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F038xx || \ + STM32F030xC */ + +#if defined(STM32F070x6) || defined(STM32F070xB) + +#define IS_RCC_PERIPHCLOCK(SELECTION) \ + ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_USB)) +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) + +#define IS_RCC_PERIPHCLOCK(SELECTION) \ + ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_CEC | \ + RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USB)) +#endif /* STM32F042x6 || STM32F048xx */ + +#if defined(STM32F051x8) || defined(STM32F058xx) + +#define IS_RCC_PERIPHCLOCK(SELECTION) \ + ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_CEC | \ + RCC_PERIPHCLK_RTC)) +#endif /* STM32F051x8 || STM32F058xx */ + +#if defined(STM32F071xB) + +#define IS_RCC_PERIPHCLOCK(SELECTION) \ + ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_I2C1 | \ + RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_RTC)) +#endif /* STM32F071xB */ + +#if defined(STM32F072xB) || defined(STM32F078xx) + +#define IS_RCC_PERIPHCLOCK(SELECTION) \ + ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_I2C1 | \ + RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USB)) +#endif /* STM32F072xB || STM32F078xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define IS_RCC_PERIPHCLOCK(SELECTION) \ + ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_I2C1 | \ + RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USART3)) +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || \ + defined(STM32F078xx) + +#define IS_RCC_USBCLKSOURCE(SOURCE) \ + (((SOURCE) == RCC_USBCLKSOURCE_HSI48) || ((SOURCE) == RCC_USBCLKSOURCE_PLL)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx */ + +#if defined(STM32F070x6) || defined(STM32F070xB) + +#define IS_RCC_USBCLKSOURCE(SOURCE) \ + (((SOURCE) == RCC_USBCLKSOURCE_NONE) || ((SOURCE) == RCC_USBCLKSOURCE_PLL)) + +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F091xC) || defined(STM32F098xx) + +#define IS_RCC_USART2CLKSOURCE(SOURCE) \ + (((SOURCE) == RCC_USART2CLKSOURCE_PCLK1) || \ + ((SOURCE) == RCC_USART2CLKSOURCE_SYSCLK) || \ + ((SOURCE) == RCC_USART2CLKSOURCE_LSE) || ((SOURCE) == RCC_USART2CLKSOURCE_HSI)) + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define IS_RCC_USART3CLKSOURCE(SOURCE) \ + (((SOURCE) == RCC_USART3CLKSOURCE_PCLK1) || \ + ((SOURCE) == RCC_USART3CLKSOURCE_SYSCLK) || \ + ((SOURCE) == RCC_USART3CLKSOURCE_LSE) || ((SOURCE) == RCC_USART3CLKSOURCE_HSI)) +#endif /* STM32F091xC || STM32F098xx */ + + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +#define IS_RCC_CECCLKSOURCE(SOURCE) \ + (((SOURCE) == RCC_CECCLKSOURCE_HSI) || ((SOURCE) == RCC_CECCLKSOURCE_LSE)) +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(RCC_CFGR_MCOPRE) + +#define IS_RCC_MCODIV(DIV) \ + (((DIV) == RCC_MCODIV_1) || ((DIV) == RCC_MCODIV_2) || ((DIV) == RCC_MCODIV_4) || \ + ((DIV) == RCC_MCODIV_8) || ((DIV) == RCC_MCODIV_16) || ((DIV) == RCC_MCODIV_32) || \ + ((DIV) == RCC_MCODIV_64) || ((DIV) == RCC_MCODIV_128)) +#else + +#define IS_RCC_MCODIV(DIV) (((DIV) == RCC_MCODIV_1)) + +#endif /* RCC_CFGR_MCOPRE */ + +#define IS_RCC_LSE_DRIVE(__DRIVE__) \ + (((__DRIVE__) == RCC_LSEDRIVE_LOW) || ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMLOW) || \ + ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMHIGH) || ((__DRIVE__) == RCC_LSEDRIVE_HIGH)) + +#if defined(CRS) + +#define IS_RCC_CRS_SYNC_SOURCE(_SOURCE_) \ + (((_SOURCE_) == RCC_CRS_SYNC_SOURCE_GPIO) || \ + ((_SOURCE_) == RCC_CRS_SYNC_SOURCE_LSE) || ((_SOURCE_) == RCC_CRS_SYNC_SOURCE_USB)) +#define IS_RCC_CRS_SYNC_DIV(_DIV_) \ + (((_DIV_) == RCC_CRS_SYNC_DIV1) || ((_DIV_) == RCC_CRS_SYNC_DIV2) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV4) || ((_DIV_) == RCC_CRS_SYNC_DIV8) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV16) || ((_DIV_) == RCC_CRS_SYNC_DIV32) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV64) || ((_DIV_) == RCC_CRS_SYNC_DIV128)) +#define IS_RCC_CRS_SYNC_POLARITY(_POLARITY_) \ + (((_POLARITY_) == RCC_CRS_SYNC_POLARITY_RISING) || \ + ((_POLARITY_) == RCC_CRS_SYNC_POLARITY_FALLING)) +#define IS_RCC_CRS_RELOADVALUE(_VALUE_) (((_VALUE_) <= 0xFFFFU)) +#define IS_RCC_CRS_ERRORLIMIT(_VALUE_) (((_VALUE_) <= 0xFFU)) +#define IS_RCC_CRS_HSI48CALIBRATION(_VALUE_) (((_VALUE_) <= 0x3FU)) +#define IS_RCC_CRS_FREQERRORDIR(_DIR_) \ + (((_DIR_) == RCC_CRS_FREQERRORDIR_UP) || ((_DIR_) == RCC_CRS_FREQERRORDIR_DOWN)) +#endif /* CRS */ +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup RCCEx_Exported_Types RCCEx Exported Types + * @{ + */ + +/** + * @brief RCC extended clocks structure definition + */ +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || \ + defined(STM32F038xx) || defined(STM32F030xC) + typedef struct + { + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref + RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref + RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref + RCC_USART1_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref + RCC_I2C1_Clock_Source */ + + } RCC_PeriphCLKInitTypeDef; +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F038xx || \ + STM32F030xC */ + +#if defined(STM32F070x6) || defined(STM32F070xB) + typedef struct + { + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref + RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref + RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref + RCC_USART1_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref + RCC_I2C1_Clock_Source */ + + uint32_t UsbClockSelection; /*!< USB clock source + This parameter can be a value of @ref + RCCEx_USB_Clock_Source */ + + } RCC_PeriphCLKInitTypeDef; +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) + typedef struct + { + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref + RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref + RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref + RCC_USART1_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref + RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref + RCCEx_CEC_Clock_Source */ + + uint32_t UsbClockSelection; /*!< USB clock source + This parameter can be a value of @ref + RCCEx_USB_Clock_Source */ + + } RCC_PeriphCLKInitTypeDef; +#endif /* STM32F042x6 || STM32F048xx */ + +#if defined(STM32F051x8) || defined(STM32F058xx) + typedef struct + { + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref + RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref + RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref + RCC_USART1_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref + RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref + RCCEx_CEC_Clock_Source */ + + } RCC_PeriphCLKInitTypeDef; +#endif /* STM32F051x8 || STM32F058xx */ + +#if defined(STM32F071xB) + typedef struct + { + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref + RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref + RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref + RCC_USART1_Clock_Source */ + + uint32_t Usart2ClockSelection; /*!< USART2 clock source + This parameter can be a value of @ref + RCCEx_USART2_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref + RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref + RCCEx_CEC_Clock_Source */ + + } RCC_PeriphCLKInitTypeDef; +#endif /* STM32F071xB */ + +#if defined(STM32F072xB) || defined(STM32F078xx) + typedef struct + { + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref + RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref + RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref + RCC_USART1_Clock_Source */ + + uint32_t Usart2ClockSelection; /*!< USART2 clock source + This parameter can be a value of @ref + RCCEx_USART2_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref + RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref + RCCEx_CEC_Clock_Source */ + + uint32_t UsbClockSelection; /*!< USB clock source + This parameter can be a value of @ref + RCCEx_USB_Clock_Source */ + + } RCC_PeriphCLKInitTypeDef; +#endif /* STM32F072xB || STM32F078xx */ + + +#if defined(STM32F091xC) || defined(STM32F098xx) + typedef struct + { + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref + RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref + RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref + RCC_USART1_Clock_Source */ + + uint32_t Usart2ClockSelection; /*!< USART2 clock source + This parameter can be a value of @ref + RCCEx_USART2_Clock_Source */ + + uint32_t Usart3ClockSelection; /*!< USART3 clock source + This parameter can be a value of @ref + RCCEx_USART3_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref + RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref + RCCEx_CEC_Clock_Source */ + + } RCC_PeriphCLKInitTypeDef; +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(CRS) + + /** + * @brief RCC_CRS Init structure definition + */ + typedef struct + { + uint32_t Prescaler; /*!< Specifies the division factor of the SYNC signal. + This parameter can be a value of @ref + RCCEx_CRS_SynchroDivider */ + + uint32_t + Source; /*!< Specifies the SYNC signal source. + This parameter can be a value of @ref RCCEx_CRS_SynchroSource */ + + uint32_t Polarity; /*!< Specifies the input polarity for the SYNC signal source. + This parameter can be a value of @ref + RCCEx_CRS_SynchroPolarity */ + + uint32_t + ReloadValue; /*!< Specifies the value to be loaded in the frequency error + counter with each SYNC event. It can be calculated in using + macro @ref __HAL_RCC_CRS_RELOADVALUE_CALCULATE(__FTARGET__, + __FSYNC__) This parameter must be a number between 0 and + 0xFFFF or a value of @ref RCCEx_CRS_ReloadValueDefault .*/ + + uint32_t ErrorLimitValue; /*!< Specifies the value to be used to evaluate the + captured frequency error value. This parameter must + be a number between 0 and 0xFF or a value of @ref + RCCEx_CRS_ErrorLimitDefault */ + + uint32_t HSI48CalibrationValue; /*!< Specifies a user-programmable trimming value + to the HSI48 oscillator. This parameter must be + a number between 0 and 0x3F or a value of @ref + RCCEx_CRS_HSI48CalibrationDefault */ + + } RCC_CRSInitTypeDef; + + /** + * @brief RCC_CRS Synchronization structure definition + */ + typedef struct + { + uint32_t ReloadValue; /*!< Specifies the value loaded in the Counter reload value. + This parameter must be a number between 0 and 0xFFFFU */ + + uint32_t HSI48CalibrationValue; /*!< Specifies value loaded in HSI48 oscillator + smooth trimming. This parameter must be a + number between 0 and 0x3FU */ + + uint32_t FreqErrorCapture; /*!< Specifies the value loaded in the .FECAP, the + frequency error counter value latched in the time of + the last SYNC event. This parameter must be a number + between 0 and 0xFFFFU */ + + uint32_t FreqErrorDirection; /*!< Specifies the value loaded in the .FEDIR, the + counting direction of the frequency error counter + latched in the time of the last SYNC event. It + shows whether the actual frequency is below or + above the target. This parameter must be a value of + @ref RCCEx_CRS_FreqErrorDirection*/ + + } RCC_CRSSynchroInfoTypeDef; + +#endif /* CRS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RCCEx_Exported_Constants RCCEx Exported Constants + * @{ + */ + +/** @defgroup RCCEx_Periph_Clock_Selection RCCEx Periph Clock Selection + * @{ + */ +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || \ + defined(STM32F038xx) || defined(STM32F030xC) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_RTC (0x00010000U) + +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F038xx || \ + STM32F030xC */ + +#if defined(STM32F070x6) || defined(STM32F070xB) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_RTC (0x00010000U) +#define RCC_PERIPHCLK_USB (0x00020000U) + +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) +#define RCC_PERIPHCLK_USB (0x00020000U) + +#endif /* STM32F042x6 || STM32F048xx */ + +#if defined(STM32F051x8) || defined(STM32F058xx) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) + +#endif /* STM32F051x8 || STM32F058xx */ + +#if defined(STM32F071xB) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_USART2 (0x00000002U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) + +#endif /* STM32F071xB */ + +#if defined(STM32F072xB) || defined(STM32F078xx) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_USART2 (0x00000002U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) +#define RCC_PERIPHCLK_USB (0x00020000U) + +#endif /* STM32F072xB || STM32F078xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_USART2 (0x00000002U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) +#define RCC_PERIPHCLK_USART3 (0x00040000U) + +#endif /* STM32F091xC || STM32F098xx */ + + /** + * @} + */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || \ + defined(STM32F078xx) + +/** @defgroup RCCEx_USB_Clock_Source RCCEx USB Clock Source + * @{ + */ +#define RCC_USBCLKSOURCE_HSI48 \ + RCC_CFGR3_USBSW_HSI48 /*!< HSI48 clock selected as USB clock source */ +#define RCC_USBCLKSOURCE_PLL \ + RCC_CFGR3_USBSW_PLLCLK /*!< PLL clock (PLLCLK) selected as USB clock */ + + /** + * @} + */ + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx */ + +#if defined(STM32F070x6) || defined(STM32F070xB) + +/** @defgroup RCCEx_USB_Clock_Source RCCEx USB Clock Source + * @{ + */ +#define RCC_USBCLKSOURCE_NONE (0x00000000U) /*!< USB clock disabled */ +#define RCC_USBCLKSOURCE_PLL \ + RCC_CFGR3_USBSW_PLLCLK /*!< PLL clock (PLLCLK) selected as USB clock */ + + /** + * @} + */ + +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F091xC) || defined(STM32F098xx) + +/** @defgroup RCCEx_USART2_Clock_Source RCCEx USART2 Clock Source + * @{ + */ +#define RCC_USART2CLKSOURCE_PCLK1 RCC_CFGR3_USART2SW_PCLK +#define RCC_USART2CLKSOURCE_SYSCLK RCC_CFGR3_USART2SW_SYSCLK +#define RCC_USART2CLKSOURCE_LSE RCC_CFGR3_USART2SW_LSE +#define RCC_USART2CLKSOURCE_HSI RCC_CFGR3_USART2SW_HSI + + /** + * @} + */ + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +/** @defgroup RCCEx_USART3_Clock_Source RCCEx USART3 Clock Source + * @{ + */ +#define RCC_USART3CLKSOURCE_PCLK1 RCC_CFGR3_USART3SW_PCLK +#define RCC_USART3CLKSOURCE_SYSCLK RCC_CFGR3_USART3SW_SYSCLK +#define RCC_USART3CLKSOURCE_LSE RCC_CFGR3_USART3SW_LSE +#define RCC_USART3CLKSOURCE_HSI RCC_CFGR3_USART3SW_HSI + + /** + * @} + */ + +#endif /* STM32F091xC || STM32F098xx */ + + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +/** @defgroup RCCEx_CEC_Clock_Source RCCEx CEC Clock Source + * @{ + */ +#define RCC_CECCLKSOURCE_HSI RCC_CFGR3_CECSW_HSI_DIV244 +#define RCC_CECCLKSOURCE_LSE RCC_CFGR3_CECSW_LSE + + /** + * @} + */ + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + + /** @defgroup RCCEx_MCOx_Clock_Prescaler RCCEx MCOx Clock Prescaler + * @{ + */ + +#if defined(RCC_CFGR_MCOPRE) + +#define RCC_MCODIV_1 (0x00000000U) +#define RCC_MCODIV_2 (0x10000000U) +#define RCC_MCODIV_4 (0x20000000U) +#define RCC_MCODIV_8 (0x30000000U) +#define RCC_MCODIV_16 (0x40000000U) +#define RCC_MCODIV_32 (0x50000000U) +#define RCC_MCODIV_64 (0x60000000U) +#define RCC_MCODIV_128 (0x70000000U) + +#else + +#define RCC_MCODIV_1 (0x00000000U) + +#endif /* RCC_CFGR_MCOPRE */ + + /** + * @} + */ + + /** @defgroup RCCEx_LSEDrive_Configuration RCC LSE Drive Configuration + * @{ + */ + +#define RCC_LSEDRIVE_LOW (0x00000000U) /*!< Xtal mode lower driving capability */ +#define RCC_LSEDRIVE_MEDIUMLOW \ + RCC_BDCR_LSEDRV_1 /*!< Xtal mode medium low driving capability */ +#define RCC_LSEDRIVE_MEDIUMHIGH \ + RCC_BDCR_LSEDRV_0 /*!< Xtal mode medium high driving capability */ +#define RCC_LSEDRIVE_HIGH RCC_BDCR_LSEDRV /*!< Xtal mode higher driving capability */ + + /** + * @} + */ + +#if defined(CRS) + +/** @defgroup RCCEx_CRS_Status RCCEx CRS Status + * @{ + */ +#define RCC_CRS_NONE (0x00000000U) +#define RCC_CRS_TIMEOUT (0x00000001U) +#define RCC_CRS_SYNCOK (0x00000002U) +#define RCC_CRS_SYNCWARN (0x00000004U) +#define RCC_CRS_SYNCERR (0x00000008U) +#define RCC_CRS_SYNCMISS (0x00000010U) +#define RCC_CRS_TRIMOVF (0x00000020U) + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroSource RCCEx CRS Synchronization Source + * @{ + */ +#define RCC_CRS_SYNC_SOURCE_GPIO (0x00000000U) /*!< Synchro Signal source GPIO */ +#define RCC_CRS_SYNC_SOURCE_LSE CRS_CFGR_SYNCSRC_0 /*!< Synchro Signal source LSE */ +#define RCC_CRS_SYNC_SOURCE_USB \ + CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source USB SOF (default)*/ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroDivider RCCEx CRS Synchronization Divider + * @{ + */ +#define RCC_CRS_SYNC_DIV1 (0x00000000U) /*!< Synchro Signal not divided (default) */ +#define RCC_CRS_SYNC_DIV2 CRS_CFGR_SYNCDIV_0 /*!< Synchro Signal divided by 2 */ +#define RCC_CRS_SYNC_DIV4 CRS_CFGR_SYNCDIV_1 /*!< Synchro Signal divided by 4 */ +#define RCC_CRS_SYNC_DIV8 \ + (CRS_CFGR_SYNCDIV_1 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 8 */ +#define RCC_CRS_SYNC_DIV16 CRS_CFGR_SYNCDIV_2 /*!< Synchro Signal divided by 16 */ +#define RCC_CRS_SYNC_DIV32 \ + (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 32 */ +#define RCC_CRS_SYNC_DIV64 \ + (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_1) /*!< Synchro Signal divided by 64 */ +#define RCC_CRS_SYNC_DIV128 CRS_CFGR_SYNCDIV /*!< Synchro Signal divided by 128 */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroPolarity RCCEx CRS Synchronization Polarity + * @{ + */ +#define RCC_CRS_SYNC_POLARITY_RISING \ + (0x00000000U) /*!< Synchro Active on rising edge (default) */ +#define RCC_CRS_SYNC_POLARITY_FALLING \ + CRS_CFGR_SYNCPOL /*!< Synchro Active on falling edge */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_ReloadValueDefault RCCEx CRS Default Reload Value + * @{ + */ +#define RCC_CRS_RELOADVALUE_DEFAULT \ + (0x0000BB7FU) /*!< The reset value of the RELOAD field corresponds \ + to a target frequency of 48 MHz and a synchronization \ + signal frequency of 1 kHz (SOF signal from USB). */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_ErrorLimitDefault RCCEx CRS Default Error Limit Value + * @{ + */ +#define RCC_CRS_ERRORLIMIT_DEFAULT (0x00000022U) /*!< Default Frequency error limit */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_HSI48CalibrationDefault RCCEx CRS Default HSI48 Calibration vakye + * @{ + */ +#define RCC_CRS_HSI48CALIBRATION_DEFAULT \ + (0x00000020U) /*!< The default value is 32, which corresponds to the middle of the \ + trimming interval. The trimming step is around 67 kHz between two \ + consecutive TRIM steps. A higher TRIM value corresponds to a higher \ + output frequency */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_FreqErrorDirection RCCEx CRS Frequency Error Direction + * @{ + */ +#define RCC_CRS_FREQERRORDIR_UP \ + (0x00000000U) /*!< Upcounting direction, the actual frequency is above the target */ +#define RCC_CRS_FREQERRORDIR_DOWN \ + ((uint32_t)CRS_ISR_FEDIR) /*!< Downcounting direction, the actual frequency is below \ + the target */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Interrupt_Sources RCCEx CRS Interrupt Sources + * @{ + */ +#define RCC_CRS_IT_SYNCOK CRS_CR_SYNCOKIE /*!< SYNC event OK */ +#define RCC_CRS_IT_SYNCWARN CRS_CR_SYNCWARNIE /*!< SYNC warning */ +#define RCC_CRS_IT_ERR CRS_CR_ERRIE /*!< Error */ +#define RCC_CRS_IT_ESYNC CRS_CR_ESYNCIE /*!< Expected SYNC */ +#define RCC_CRS_IT_SYNCERR CRS_CR_ERRIE /*!< SYNC error */ +#define RCC_CRS_IT_SYNCMISS CRS_CR_ERRIE /*!< SYNC missed */ +#define RCC_CRS_IT_TRIMOVF CRS_CR_ERRIE /*!< Trimming overflow or underflow */ + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Flags RCCEx CRS Flags + * @{ + */ +#define RCC_CRS_FLAG_SYNCOK CRS_ISR_SYNCOKF /*!< SYNC event OK flag */ +#define RCC_CRS_FLAG_SYNCWARN CRS_ISR_SYNCWARNF /*!< SYNC warning flag */ +#define RCC_CRS_FLAG_ERR CRS_ISR_ERRF /*!< Error flag */ +#define RCC_CRS_FLAG_ESYNC CRS_ISR_ESYNCF /*!< Expected SYNC flag */ +#define RCC_CRS_FLAG_SYNCERR CRS_ISR_SYNCERR /*!< SYNC error */ +#define RCC_CRS_FLAG_SYNCMISS CRS_ISR_SYNCMISS /*!< SYNC missed*/ +#define RCC_CRS_FLAG_TRIMOVF CRS_ISR_TRIMOVF /*!< Trimming overflow or underflow */ + + /** + * @} + */ + +#endif /* CRS */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Macros RCCEx Exported Macros + * @{ + */ + +/** @defgroup RCCEx_Peripheral_Clock_Enable_Disable RCCEx_Peripheral_Clock_Enable_Disable + * @brief Enables or disables the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#if defined(GPIOD) + +#define __HAL_RCC_GPIOD_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIODEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIODEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_GPIOD_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIODEN)) + +#endif /* GPIOD */ + +#if defined(GPIOE) + +#define __HAL_RCC_GPIOE_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOEEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOEEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_GPIOE_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOEEN)) + +#endif /* GPIOE */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TSC_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_TSCEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_TSCEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_TSC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_TSCEN)) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_DMA2_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_DMA2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA2EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_DMA2_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_DMA2EN)) + +#endif /* STM32F091xC || STM32F098xx */ + +/** @brief Enable or disable the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F070x6) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_USART2_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_USART2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART2EN)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || STM32F070x6 || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F051x8) || defined(STM32F058xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || \ + defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_SPI2_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_SPI2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_SPI2EN)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F031x6) || defined(STM32F038xx) || defined(STM32F042x6) || \ + defined(STM32F048xx) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TIM2_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_TIM2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM2EN)) + +#endif /* STM32F031x6 || STM32F038xx || */ + /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030x8) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM6_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_I2C2_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_TIM6_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_I2C2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C2EN)) + +#endif /* STM32F030x8 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F051x8) || defined(STM32F058xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || \ + defined(STM32F098xx) + +#define __HAL_RCC_DAC1_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_DAC1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_DACEN)) + +#endif /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CEC_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CECEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CECEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_CEC_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CECEN)) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM7_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_USART3_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_USART4_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART4EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART4EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_TIM7_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM7EN)) +#define __HAL_RCC_USART3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART3EN)) +#define __HAL_RCC_USART4_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART4EN)) + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) + +#define __HAL_RCC_USB_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USBEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USBEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_USB_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USBEN)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F072xB || STM32F078xx || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || \ + defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CAN1_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CANEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CANEN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_CAN1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CANEN)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(CRS) + +#define __HAL_RCC_CRS_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CRSEN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CRSEN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_CRS_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CRSEN)) + +#endif /* CRS */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART5_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART5EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART5EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_USART5_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART5EN)) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +/** @brief Enable or disable the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F070x6) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM15_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_TIM15_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM15EN)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART6_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART6EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART6EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_USART6_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART6EN)) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_USART7_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART7EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART7EN); \ + UNUSED(tmpreg); \ + } while (0U) +#define __HAL_RCC_USART8_CLK_ENABLE() \ + do \ + { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART8EN); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART8EN); \ + UNUSED(tmpreg); \ + } while (0U) + +#define __HAL_RCC_USART7_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART7EN)) +#define __HAL_RCC_USART8_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART8EN)) + +#endif /* STM32F091xC || STM32F098xx */ + +/** + * @} + */ + + +/** @defgroup RCCEx_Force_Release_Peripheral_Reset RCCEx Force Release Peripheral Reset + * @brief Forces or releases peripheral reset. + * @{ + */ + +/** @brief Force or release AHB peripheral reset. + */ +#if defined(GPIOD) + +#define __HAL_RCC_GPIOD_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIODRST)) + +#define __HAL_RCC_GPIOD_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIODRST)) + +#endif /* GPIOD */ + +#if defined(GPIOE) + +#define __HAL_RCC_GPIOE_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOERST)) + +#define __HAL_RCC_GPIOE_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOERST)) + +#endif /* GPIOE */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TSC_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_TSCRST)) + +#define __HAL_RCC_TSC_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_TSCRST)) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +/** @brief Force or release APB1 peripheral reset. + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F070x6) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_USART2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_SPI2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_SPI2RST)) + +#define __HAL_RCC_USART2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_SPI2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_SPI2RST)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F031x6) || defined(STM32F038xx) || defined(STM32F042x6) || \ + defined(STM32F048xx) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TIM2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM2RST)) + +#define __HAL_RCC_TIM2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM2RST)) + +#endif /* STM32F031x6 || STM32F038xx || */ + /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030x8) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM6_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_I2C2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C2RST)) + +#define __HAL_RCC_TIM6_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_I2C2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C2RST)) + +#endif /* STM32F030x8 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F051x8) || defined(STM32F058xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || \ + defined(STM32F098xx) + +#define __HAL_RCC_DAC1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_DACRST)) + +#define __HAL_RCC_DAC1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_DACRST)) + +#endif /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CEC_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CECRST)) + +#define __HAL_RCC_CEC_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CECRST)) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM7_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_USART3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_USART4_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART4RST)) + +#define __HAL_RCC_TIM7_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_USART3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_USART4_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART4RST)) + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) + +#define __HAL_RCC_USB_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USBRST)) + +#define __HAL_RCC_USB_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USBRST)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F072xB || STM32F078xx || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || \ + defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CAN1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CANRST)) + +#define __HAL_RCC_CAN1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CANRST)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(CRS) + +#define __HAL_RCC_CRS_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CRSRST)) + +#define __HAL_RCC_CRS_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CRSRST)) + +#endif /* CRS */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART5_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART5RST)) + +#define __HAL_RCC_USART5_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART5RST)) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + + +/** @brief Force or release APB2 peripheral reset. + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F070x6) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM15_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM15RST)) + +#define __HAL_RCC_TIM15_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM15RST)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART6_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART6RST)) + +#define __HAL_RCC_USART6_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART6RST)) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_USART7_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART7RST)) +#define __HAL_RCC_USART8_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART8RST)) + +#define __HAL_RCC_USART7_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART7RST)) +#define __HAL_RCC_USART8_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART8RST)) + +#endif /* STM32F091xC || STM32F098xx */ + +/** + * @} + */ + +/** @defgroup RCCEx_Peripheral_Clock_Enable_Disable_Status Peripheral Clock Enable Disable + * Status + * @brief Get the enable or disable status of peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +/** @brief AHB Peripheral Clock Enable Disable Status + */ +#if defined(GPIOD) + +#define __HAL_RCC_GPIOD_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIODEN)) != RESET) +#define __HAL_RCC_GPIOD_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIODEN)) == RESET) + +#endif /* GPIOD */ + +#if defined(GPIOE) + +#define __HAL_RCC_GPIOE_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOEEN)) != RESET) +#define __HAL_RCC_GPIOE_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOEEN)) == RESET) + +#endif /* GPIOE */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TSC_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_TSCEN)) != RESET) +#define __HAL_RCC_TSC_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_TSCEN)) == RESET) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_DMA2_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA2EN)) != RESET) +#define __HAL_RCC_DMA2_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA2EN)) == RESET) + +#endif /* STM32F091xC || STM32F098xx */ + +/** @brief APB1 Peripheral Clock Enable Disable Status + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F070x6) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_USART2_IS_CLK_ENABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) != RESET) +#define __HAL_RCC_USART2_IS_CLK_DISABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) == RESET) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || STM32F070x6 || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F051x8) || defined(STM32F058xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || \ + defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_SPI2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_SPI2EN)) != RESET) +#define __HAL_RCC_SPI2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_SPI2EN)) == RESET) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F031x6) || defined(STM32F038xx) || defined(STM32F042x6) || \ + defined(STM32F048xx) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TIM2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM2EN)) != RESET) +#define __HAL_RCC_TIM2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM2EN)) == RESET) + +#endif /* STM32F031x6 || STM32F038xx || */ + /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030x8) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM6_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM6EN)) != RESET) +#define __HAL_RCC_I2C2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C2EN)) != RESET) +#define __HAL_RCC_TIM6_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM6EN)) == RESET) +#define __HAL_RCC_I2C2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C2EN)) == RESET) + +#endif /* STM32F030x8 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F051x8) || defined(STM32F058xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || \ + defined(STM32F098xx) + +#define __HAL_RCC_DAC1_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_DAC1EN)) != RESET) +#define __HAL_RCC_DAC1_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_DAC1EN)) == RESET) + +#endif /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CEC_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CECEN)) != RESET) +#define __HAL_RCC_CEC_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CECEN)) == RESET) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM7_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM7EN)) != RESET) +#define __HAL_RCC_USART3_IS_CLK_ENABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_USART3EN)) != RESET) +#define __HAL_RCC_USART4_IS_CLK_ENABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_USART4EN)) != RESET) +#define __HAL_RCC_TIM7_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM7EN)) == RESET) +#define __HAL_RCC_USART3_IS_CLK_DISABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_USART3EN)) == RESET) +#define __HAL_RCC_USART4_IS_CLK_DISABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_USART4EN)) == RESET) + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) + +#define __HAL_RCC_USB_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USBEN)) != RESET) +#define __HAL_RCC_USB_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USBEN)) == RESET) + +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F072xB || STM32F078xx || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || \ + defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CAN1_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CAN1EN)) != RESET) +#define __HAL_RCC_CAN1_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CAN1EN)) == RESET) + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(CRS) + +#define __HAL_RCC_CRS_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CRSEN)) != RESET) +#define __HAL_RCC_CRS_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CRSEN)) == RESET) + +#endif /* CRS */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART5_IS_CLK_ENABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_USART5EN)) != RESET) +#define __HAL_RCC_USART5_IS_CLK_DISABLED() \ + ((RCC->APB1ENR & (RCC_APB1ENR_USART5EN)) == RESET) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +/** @brief APB1 Peripheral Clock Enable Disable Status + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F070x6) || defined(STM32F051x8) || defined(STM32F058xx) || \ + defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + +#define __HAL_RCC_TIM15_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM15EN)) != RESET) +#define __HAL_RCC_TIM15_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_TIM15EN)) == RESET) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART6_IS_CLK_ENABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_USART6EN)) != RESET) +#define __HAL_RCC_USART6_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_USART6EN)) == RESET) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_USART7_IS_CLK_ENABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_USART7EN)) != RESET) +#define __HAL_RCC_USART8_IS_CLK_ENABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_USART8EN)) != RESET) +#define __HAL_RCC_USART7_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_USART7EN)) == RESET) +#define __HAL_RCC_USART8_IS_CLK_DISABLED() \ + ((RCC->APB2ENR & (RCC_APB2ENR_USART8EN)) == RESET) + +#endif /* STM32F091xC || STM32F098xx */ +/** + * @} + */ + + +/** @defgroup RCCEx_HSI48_Enable_Disable RCCEx HSI48 Enable Disable + * @brief Macros to enable or disable the Internal 48Mhz High Speed oscillator (HSI48). + * @note The HSI48 is stopped by hardware when entering STOP and STANDBY modes. + * @note HSI48 can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI14. + * @note After enabling the HSI48 with __HAL_RCC_HSI48_ENABLE(), the application + * software should wait on HSI48RDY flag to be set indicating that HSI48 clock is stable + * and can be used as system clock source. This is not necessary if HAL_RCC_OscConfig() is + * used. + * @note When the HSI48 is stopped, HSI48RDY flag goes low after 6 HSI48 oscillator + * clock cycles. + * @{ + */ +#if defined(RCC_HSI48_SUPPORT) + +#define __HAL_RCC_HSI48_ENABLE() SET_BIT(RCC->CR2, RCC_CR2_HSI48ON) +#define __HAL_RCC_HSI48_DISABLE() CLEAR_BIT(RCC->CR2, RCC_CR2_HSI48ON) + +/** @brief Macro to get the Internal 48Mhz High Speed oscillator (HSI48) state. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_HSI48_ON HSI48 enabled + * @arg @ref RCC_HSI48_OFF HSI48 disabled + */ +#define __HAL_RCC_GET_HSI48_STATE() \ + (((uint32_t)(READ_BIT(RCC->CR2, RCC_CR2_HSI48ON)) != RESET) ? RCC_HSI48_ON \ + : RCC_HSI48_OFF) + +#endif /* RCC_HSI48_SUPPORT */ + +/** + * @} + */ + +/** @defgroup RCCEx_Peripheral_Clock_Source_Config RCCEx Peripheral Clock Source Config + * @{ + */ +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F070x6) || defined(STM32F070xB) + +/** @brief Macro to configure the USB clock (USBCLK). + * @param __USBCLKSOURCE__ specifies the USB clock source. + * This parameter can be one of the following values: +@if STM32F070xB +@elseif STM32F070x6 +@else + * @arg @ref RCC_USBCLKSOURCE_HSI48 HSI48 selected as USB clock +@endif + * @arg @ref RCC_USBCLKSOURCE_PLL PLL Clock selected as USB clock + */ +#define __HAL_RCC_USB_CONFIG(__USBCLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USBSW, (uint32_t)(__USBCLKSOURCE__)) + +/** @brief Macro to get the USB clock source. + * @retval The clock source can be one of the following values: +@if STM32F070xB +@elseif STM32F070x6 +@else + * @arg @ref RCC_USBCLKSOURCE_HSI48 HSI48 selected as USB clock +@endif + * @arg @ref RCC_USBCLKSOURCE_PLL PLL Clock selected as USB clock + */ +#define __HAL_RCC_GET_USB_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_USBSW))) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F072xB || STM32F078xx || */ + /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || \ + defined(STM32F058xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + +/** @brief Macro to configure the CEC clock. + * @param __CECCLKSOURCE__ specifies the CEC clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_CECCLKSOURCE_HSI HSI selected as CEC clock + * @arg @ref RCC_CECCLKSOURCE_LSE LSE selected as CEC clock + */ +#define __HAL_RCC_CEC_CONFIG(__CECCLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_CECSW, (uint32_t)(__CECCLKSOURCE__)) + +/** @brief Macro to get the HDMI CEC clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_CECCLKSOURCE_HSI HSI selected as CEC clock + * @arg @ref RCC_CECCLKSOURCE_LSE LSE selected as CEC clock + */ +#define __HAL_RCC_GET_CEC_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_CECSW))) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || defined(STM32F098xx) */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \ + defined(STM32F091xC) || defined(STM32F098xx) +/** @brief Macro to configure the USART2 clock (USART2CLK). + * @param __USART2CLKSOURCE__ specifies the USART2 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART2CLKSOURCE_PCLK1 PCLK1 selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_HSI HSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_SYSCLK System Clock selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_LSE LSE selected as USART2 clock + */ +#define __HAL_RCC_USART2_CONFIG(__USART2CLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USART2SW, (uint32_t)(__USART2CLKSOURCE__)) + +/** @brief Macro to get the USART2 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART2CLKSOURCE_PCLK1 PCLK1 selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_HSI HSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_SYSCLK System Clock selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_LSE LSE selected as USART2 clock + */ +#define __HAL_RCC_GET_USART2_SOURCE() \ + ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_USART2SW))) +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx*/ + +#if defined(STM32F091xC) || defined(STM32F098xx) +/** @brief Macro to configure the USART3 clock (USART3CLK). + * @param __USART3CLKSOURCE__ specifies the USART3 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART3CLKSOURCE_PCLK1 PCLK1 selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_HSI HSI selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_SYSCLK System Clock selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_LSE LSE selected as USART3 clock + */ +#define __HAL_RCC_USART3_CONFIG(__USART3CLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USART3SW, (uint32_t)(__USART3CLKSOURCE__)) + +/** @brief Macro to get the USART3 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART3CLKSOURCE_PCLK1 PCLK1 selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_HSI HSI selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_SYSCLK System Clock selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_LSE LSE selected as USART3 clock + */ +#define __HAL_RCC_GET_USART3_SOURCE() \ + ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_USART3SW))) + +#endif /* STM32F091xC || STM32F098xx */ +/** + * @} + */ + +/** @defgroup RCCEx_LSE_Configuration LSE Drive Configuration + * @{ + */ + +/** + * @brief Macro to configure the External Low Speed oscillator (LSE) drive capability. + * @param __RCC_LSEDRIVE__ specifies the new state of the LSE drive capability. + * This parameter can be one of the following values: + * @arg @ref RCC_LSEDRIVE_LOW LSE oscillator low drive capability. + * @arg @ref RCC_LSEDRIVE_MEDIUMLOW LSE oscillator medium low drive + * capability. + * @arg @ref RCC_LSEDRIVE_MEDIUMHIGH LSE oscillator medium high drive + * capability. + * @arg @ref RCC_LSEDRIVE_HIGH LSE oscillator high drive capability. + * @retval None + */ +#define __HAL_RCC_LSEDRIVE_CONFIG(__RCC_LSEDRIVE__) \ + (MODIFY_REG(RCC->BDCR, RCC_BDCR_LSEDRV, (uint32_t)(__RCC_LSEDRIVE__))) + + /** + * @} + */ + +#if defined(CRS) + +/** @defgroup RCCEx_IT_And_Flag RCCEx IT and Flag + * @{ + */ +/* Interrupt & Flag management */ + +/** + * @brief Enable the specified CRS interrupts. + * @param __INTERRUPT__ specifies the CRS interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval None + */ +#define __HAL_RCC_CRS_ENABLE_IT(__INTERRUPT__) SET_BIT(CRS->CR, (__INTERRUPT__)) + +/** + * @brief Disable the specified CRS interrupts. + * @param __INTERRUPT__ specifies the CRS interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval None + */ +#define __HAL_RCC_CRS_DISABLE_IT(__INTERRUPT__) CLEAR_BIT(CRS->CR, (__INTERRUPT__)) + +/** @brief Check whether the CRS interrupt has occurred or not. + * @param __INTERRUPT__ specifies the CRS interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_RCC_CRS_GET_IT_SOURCE(__INTERRUPT__) \ + ((READ_BIT(CRS->CR, (__INTERRUPT__)) != RESET) ? SET : RESET) + +/** @brief Clear the CRS interrupt pending bits + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @arg @ref RCC_CRS_IT_TRIMOVF Trimming overflow or underflow interrupt + * @arg @ref RCC_CRS_IT_SYNCERR SYNC error interrupt + * @arg @ref RCC_CRS_IT_SYNCMISS SYNC missed interrupt + */ +#define __HAL_RCC_CRS_CLEAR_IT(__INTERRUPT__) \ + do \ + { \ + if (((__INTERRUPT__)&RCC_CRS_IT_ERROR_MASK) != RESET) \ + { \ + WRITE_REG(CRS->ICR, \ + CRS_ICR_ERRC | ((__INTERRUPT__) & ~RCC_CRS_IT_ERROR_MASK)); \ + } \ + else \ + { \ + WRITE_REG(CRS->ICR, (__INTERRUPT__)); \ + } \ + } while (0U) + +/** + * @brief Check whether the specified CRS flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref RCC_CRS_FLAG_SYNCOK SYNC event OK + * @arg @ref RCC_CRS_FLAG_SYNCWARN SYNC warning + * @arg @ref RCC_CRS_FLAG_ERR Error + * @arg @ref RCC_CRS_FLAG_ESYNC Expected SYNC + * @arg @ref RCC_CRS_FLAG_TRIMOVF Trimming overflow or underflow + * @arg @ref RCC_CRS_FLAG_SYNCERR SYNC error + * @arg @ref RCC_CRS_FLAG_SYNCMISS SYNC missed + * @retval The new state of _FLAG_ (TRUE or FALSE). + */ +#define __HAL_RCC_CRS_GET_FLAG(__FLAG__) (READ_BIT(CRS->ISR, (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the CRS specified FLAG. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref RCC_CRS_FLAG_SYNCOK SYNC event OK + * @arg @ref RCC_CRS_FLAG_SYNCWARN SYNC warning + * @arg @ref RCC_CRS_FLAG_ERR Error + * @arg @ref RCC_CRS_FLAG_ESYNC Expected SYNC + * @arg @ref RCC_CRS_FLAG_TRIMOVF Trimming overflow or underflow + * @arg @ref RCC_CRS_FLAG_SYNCERR SYNC error + * @arg @ref RCC_CRS_FLAG_SYNCMISS SYNC missed + * @note RCC_CRS_FLAG_ERR clears RCC_CRS_FLAG_TRIMOVF, RCC_CRS_FLAG_SYNCERR, + * RCC_CRS_FLAG_SYNCMISS and consequently RCC_CRS_FLAG_ERR + * @retval None + */ +#define __HAL_RCC_CRS_CLEAR_FLAG(__FLAG__) \ + do \ + { \ + if (((__FLAG__)&RCC_CRS_FLAG_ERROR_MASK) != RESET) \ + { \ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC | ((__FLAG__) & ~RCC_CRS_FLAG_ERROR_MASK)); \ + } \ + else \ + { \ + WRITE_REG(CRS->ICR, (__FLAG__)); \ + } \ + } while (0U) + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Extended_Features RCCEx CRS Extended Features + * @{ + */ +/** + * @brief Enable the oscillator clock for frequency error counter. + * @note when the CEN bit is set the CRS_CFGR register becomes write-protected. + * @retval None + */ +#define __HAL_RCC_CRS_FREQ_ERROR_COUNTER_ENABLE() SET_BIT(CRS->CR, CRS_CR_CEN) + +/** + * @brief Disable the oscillator clock for frequency error counter. + * @retval None + */ +#define __HAL_RCC_CRS_FREQ_ERROR_COUNTER_DISABLE() CLEAR_BIT(CRS->CR, CRS_CR_CEN) + +/** + * @brief Enable the automatic hardware adjustment of TRIM bits. + * @note When the AUTOTRIMEN bit is set the CRS_CFGR register becomes write-protected. + * @retval None + */ +#define __HAL_RCC_CRS_AUTOMATIC_CALIB_ENABLE() SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) + +/** + * @brief Disable the automatic hardware adjustment of TRIM bits. + * @retval None + */ +#define __HAL_RCC_CRS_AUTOMATIC_CALIB_DISABLE() CLEAR_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) + +/** + * @brief Macro to calculate reload value to be set in CRS register according to target + * and sync frequencies + * @note The RELOAD value should be selected according to the ratio between the target + * frequency and the frequency of the synchronization source after prescaling. It is then + * decreased by one in order to reach the expected synchronization on the zero value. The + * formula is the following: RELOAD = (fTARGET / fSYNC) -1 + * @param __FTARGET__ Target frequency (value in Hz) + * @param __FSYNC__ Synchronization signal frequency (value in Hz) + * @retval None + */ +#define __HAL_RCC_CRS_RELOADVALUE_CALCULATE(__FTARGET__, __FSYNC__) \ + (((__FTARGET__) / (__FSYNC__)) - 1U) + + /** + * @} + */ + +#endif /* CRS */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup RCCEx_Exported_Functions + * @{ + */ + + /** @addtogroup RCCEx_Exported_Functions_Group1 + * @{ + */ + + HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); + void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); + uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk); + + /** + * @} + */ + +#if defined(CRS) + + /** @addtogroup RCCEx_Exported_Functions_Group3 + * @{ + */ + + void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit); + void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void); + void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo); + uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout); + void HAL_RCCEx_CRS_IRQHandler(void); + void HAL_RCCEx_CRS_SyncOkCallback(void); + void HAL_RCCEx_CRS_SyncWarnCallback(void); + void HAL_RCCEx_CRS_ExpectedSyncCallback(void); + void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error); + + /** + * @} + */ + +#endif /* CRS */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_RCC_EX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi.c b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi.c new file mode 100644 index 0000000000..fc5994faeb --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi.c @@ -0,0 +1,4649 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_spi.c + * @author MCD Application Team + * @brief SPI HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Serial Peripheral Interface (SPI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The SPI HAL driver can be used as follows: + + (#) Declare a SPI_HandleTypeDef handle structure, for example: + SPI_HandleTypeDef hspi; + + (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API: + (##) Enable the SPIx interface clock + (##) SPI pins configuration + (+++) Enable the clock for the SPI GPIOs + (+++) Configure these SPI pins as alternate function push-pull + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the SPIx interrupt priority + (+++) Enable the NVIC SPI IRQ handle + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or + receive Stream/Channel + (+++) Enable the DMAx clock + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx Stream/Channel + (+++) Associate the initialized hdma_tx(or _rx) handle to the hspi DMA Tx + or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the DMA Tx or Rx Stream/Channel + + (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS + management, Clock polarity and phase, FirstBit and CRC configuration in the hspi + Init structure. + + (#) Initialize the SPI registers by calling the HAL_SPI_Init() API: + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_SPI_MspInit() API. + [..] + Circular mode restriction: + (#) The DMA circular mode cannot be used when the SPI is configured in these modes: + (##) Master 2Lines RxOnly + (##) Master 1Line Rx + (#) The CRC feature is not managed when the DMA circular mode is enabled + (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs + the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks + [..] + Master Receive mode restriction: + (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=1) or + bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the + SPI does not initiate a new transfer the following procedure has to be respected: + (##) HAL_SPI_DeInit() + (##) HAL_SPI_Init() + [..] + Callback registration: + + (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1U + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback. + + Function HAL_SPI_RegisterCallback() allows to register following callbacks: + (++) TxCpltCallback : SPI Tx Completed callback + (++) RxCpltCallback : SPI Rx Completed callback + (++) TxRxCpltCallback : SPI TxRx Completed callback + (++) TxHalfCpltCallback : SPI Tx Half Completed callback + (++) RxHalfCpltCallback : SPI Rx Half Completed callback + (++) TxRxHalfCpltCallback : SPI TxRx Half Completed callback + (++) ErrorCallback : SPI Error callback + (++) AbortCpltCallback : SPI Abort callback + (++) MspInitCallback : SPI Msp Init callback + (++) MspDeInitCallback : SPI Msp DeInit callback + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + + + (#) Use function HAL_SPI_UnRegisterCallback to reset a callback to the default + weak function. + HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (++) TxCpltCallback : SPI Tx Completed callback + (++) RxCpltCallback : SPI Rx Completed callback + (++) TxRxCpltCallback : SPI TxRx Completed callback + (++) TxHalfCpltCallback : SPI Tx Half Completed callback + (++) RxHalfCpltCallback : SPI Rx Half Completed callback + (++) TxRxHalfCpltCallback : SPI TxRx Half Completed callback + (++) ErrorCallback : SPI Error callback + (++) AbortCpltCallback : SPI Abort callback + (++) MspInitCallback : SPI Msp Init callback + (++) MspDeInitCallback : SPI Msp DeInit callback + + [..] + By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only + when these callbacks are null (not registered beforehand). If MspInit or MspDeInit are + not null, the HAL_SPI_Init()/ HAL_SPI_DeInit() keep and use the user MspInit/MspDeInit + callbacks (registered beforehand) whatever the state. + + [..] + Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_SPI_STATE_READY or HAL_SPI_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + Then, the user first registers the MspInit/MspDeInit user callbacks + using HAL_SPI_RegisterCallback() before calling HAL_SPI_DeInit() + or HAL_SPI_Init() function. + + [..] + When the compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registering feature is not available + and weak (surcharged) callbacks are used. + + [..] + Using the HAL it is not possible to reach all supported SPI frequency with the + different SPI Modes, the following table resume the max SPI frequency reached with data + size 8bits/16bits, according to frequency of the APBx Peripheral Clock (fPCLK) used by + the SPI instance. + + @endverbatim + + Additional table : + + DataSize = SPI_DATASIZE_8BIT: + +----------------------------------------------------------------------------------------------+ + | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line | + | Process | Transfer mode + |---------------------|----------------------|----------------------| | | | + Master | Slave | Master | Slave | Master | Slave | + |==============================================================================================| + | T | Polling | Fpclk/4 | Fpclk/8 | NA | NA | NA | + NA | | X + |----------------|----------|----------|-----------|----------|-----------|----------| + | / | Interrupt | Fpclk/4 | Fpclk/16 | NA | NA | NA | + NA | | R + |----------------|----------|----------|-----------|----------|-----------|----------| + | X | DMA | Fpclk/2 | Fpclk/2 | NA | NA | NA | + NA | + |=========|================|==========|==========|===========|==========|===========|==========| + | | Polling | Fpclk/4 | Fpclk/8 | Fpclk/16 | Fpclk/8 | Fpclk/8 + | Fpclk/8 | | + |----------------|----------|----------|-----------|----------|-----------|----------| + | R | Interrupt | Fpclk/8 | Fpclk/16 | Fpclk/8 | Fpclk/8 | Fpclk/8 + | Fpclk/4 | | X + |----------------|----------|----------|-----------|----------|-----------|----------| + | | DMA | Fpclk/4 | Fpclk/2 | Fpclk/2 | Fpclk/16 | Fpclk/2 + | Fpclk/16 | + |=========|================|==========|==========|===========|==========|===========|==========| + | | Polling | Fpclk/8 | Fpclk/2 | NA | NA | Fpclk/8 + | Fpclk/8 | | + |----------------|----------|----------|-----------|----------|-----------|----------| + | T | Interrupt | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/16 + | Fpclk/8 | | X + |----------------|----------|----------|-----------|----------|-----------|----------| + | | DMA | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/8 + | Fpclk/16 | + +----------------------------------------------------------------------------------------------+ + + DataSize = SPI_DATASIZE_16BIT: + +----------------------------------------------------------------------------------------------+ + | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line | + | Process | Transfer mode + |---------------------|----------------------|----------------------| | | | + Master | Slave | Master | Slave | Master | Slave | + |==============================================================================================| + | T | Polling | Fpclk/4 | Fpclk/8 | NA | NA | NA | + NA | | X + |----------------|----------|----------|-----------|----------|-----------|----------| + | / | Interrupt | Fpclk/4 | Fpclk/16 | NA | NA | NA | + NA | | R + |----------------|----------|----------|-----------|----------|-----------|----------| + | X | DMA | Fpclk/2 | Fpclk/2 | NA | NA | NA | + NA | + |=========|================|==========|==========|===========|==========|===========|==========| + | | Polling | Fpclk/4 | Fpclk/8 | Fpclk/16 | Fpclk/8 | Fpclk/8 + | Fpclk/8 | | + |----------------|----------|----------|-----------|----------|-----------|----------| + | R | Interrupt | Fpclk/8 | Fpclk/16 | Fpclk/8 | Fpclk/8 | Fpclk/8 + | Fpclk/4 | | X + |----------------|----------|----------|-----------|----------|-----------|----------| + | | DMA | Fpclk/4 | Fpclk/2 | Fpclk/2 | Fpclk/16 | Fpclk/2 + | Fpclk/16 | + |=========|================|==========|==========|===========|==========|===========|==========| + | | Polling | Fpclk/8 | Fpclk/2 | NA | NA | Fpclk/8 + | Fpclk/8 | | + |----------------|----------|----------|-----------|----------|-----------|----------| + | T | Interrupt | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/16 + | Fpclk/8 | | X + |----------------|----------|----------|-----------|----------|-----------|----------| + | | DMA | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/8 + | Fpclk/16 | + +----------------------------------------------------------------------------------------------+ + @note The max SPI frequency depend on SPI data size (4bits, 5bits,..., + 8bits,...15bits, 16bits), SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and + Process mode (Polling, IT, DMA). + @note + (#) TX/RX processes are HAL_SPI_TransmitReceive(), + HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA() + (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and + HAL_SPI_Receive_DMA() + (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and + HAL_SPI_Transmit_DMA() + + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup SPI SPI + * @brief SPI HAL module driver + * @{ + */ +#ifdef HAL_SPI_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup SPI_Private_Constants SPI Private Constants + * @{ + */ +#define SPI_DEFAULT_TIMEOUT 100U +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup SPI_Private_Functions SPI Private Functions + * @{ + */ +static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAError(DMA_HandleTypeDef *hdma); +static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma); +static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma); +static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, + uint32_t Flag, FlagStatus State, + uint32_t Timeout, + uint32_t Tickstart); +static HAL_StatusTypeDef SPI_WaitFifoStateUntilTimeout(SPI_HandleTypeDef *hspi, + uint32_t Fifo, uint32_t State, + uint32_t Timeout, + uint32_t Tickstart); +static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi); +#if (USE_SPI_CRC != 0U) +static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi); +static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi); +static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi); +static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi); +#endif /* USE_SPI_CRC */ +static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi); +static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi); +static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi); +static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi); +static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi); +static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, + uint32_t Tickstart); +static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, + uint32_t Tickstart); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SPI_Exported_Functions SPI Exported Functions + * @{ + */ + +/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the SPIx peripheral: + + (+) User must implement HAL_SPI_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_SPI_Init() to configure the selected device with + the selected configuration: + (++) Mode + (++) Direction + (++) Data Size + (++) Clock Polarity and Phase + (++) NSS Management + (++) BaudRate Prescaler + (++) FirstBit + (++) TIMode + (++) CRC Calculation + (++) CRC Polynomial if CRC enabled + (++) CRC Length, used only with Data8 and Data16 + (++) FIFO reception threshold + + (+) Call the function HAL_SPI_DeInit() to restore the default configuration + of the selected SPIx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the SPI according to the specified parameters + * in the SPI_InitTypeDef and initialize the associated handle. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) +{ + uint32_t frxth; + + /* Check the SPI handle allocation */ + if (hspi == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); + assert_param(IS_SPI_MODE(hspi->Init.Mode)); + assert_param(IS_SPI_DIRECTION(hspi->Init.Direction)); + assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize)); + assert_param(IS_SPI_NSS(hspi->Init.NSS)); + assert_param(IS_SPI_NSSP(hspi->Init.NSSPMode)); + assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); + assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit)); + assert_param(IS_SPI_TIMODE(hspi->Init.TIMode)); + if (hspi->Init.TIMode == SPI_TIMODE_DISABLE) + { + assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity)); + assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase)); + + if (hspi->Init.Mode == SPI_MODE_MASTER) + { + assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); + } + else + { + /* Baudrate prescaler not use in Motoraola Slave mode. force to default value + */ + hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + } + } + else + { + assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); + + /* Force polarity and phase to TI protocaol requirements */ + hspi->Init.CLKPolarity = SPI_POLARITY_LOW; + hspi->Init.CLKPhase = SPI_PHASE_1EDGE; + } +#if (USE_SPI_CRC != 0U) + assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation)); + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial)); + assert_param(IS_SPI_CRC_LENGTH(hspi->Init.CRCLength)); + } +#else + hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; +#endif /* USE_SPI_CRC */ + + if (hspi->State == HAL_SPI_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hspi->Lock = HAL_UNLOCKED; + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + /* Init the SPI Callback settings */ + hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */ + hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */ + hspi->TxRxCpltCallback = + HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ + hspi->TxHalfCpltCallback = + HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + hspi->RxHalfCpltCallback = + HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + hspi->TxRxHalfCpltCallback = + HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ + hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */ + hspi->AbortCpltCallback = + HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + + if (hspi->MspInitCallback == NULL) + { + hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + hspi->MspInitCallback(hspi); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_SPI_MspInit(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + + hspi->State = HAL_SPI_STATE_BUSY; + + /* Disable the selected SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Align by default the rs fifo threshold on the data size */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + frxth = SPI_RXFIFO_THRESHOLD_HF; + } + else + { + frxth = SPI_RXFIFO_THRESHOLD_QF; + } + + /* CRC calculation is valid only for 16Bit and 8 Bit */ + if ((hspi->Init.DataSize != SPI_DATASIZE_16BIT) && + (hspi->Init.DataSize != SPI_DATASIZE_8BIT)) + { + /* CRC must be disabled */ + hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + } + + /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/ + /* Configure : SPI Mode, Communication Mode, Clock polarity and phase, NSS management, + Communication speed, First bit and CRC calculation state */ + WRITE_REG(hspi->Instance->CR1, + ((hspi->Init.Mode & (SPI_CR1_MSTR | SPI_CR1_SSI)) | + (hspi->Init.Direction & (SPI_CR1_RXONLY | SPI_CR1_BIDIMODE)) | + (hspi->Init.CLKPolarity & SPI_CR1_CPOL) | + (hspi->Init.CLKPhase & SPI_CR1_CPHA) | (hspi->Init.NSS & SPI_CR1_SSM) | + (hspi->Init.BaudRatePrescaler & SPI_CR1_BR_Msk) | + (hspi->Init.FirstBit & SPI_CR1_LSBFIRST) | + (hspi->Init.CRCCalculation & SPI_CR1_CRCEN))); +#if (USE_SPI_CRC != 0U) + /*---------------------------- SPIx CRCL Configuration -------------------*/ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Align the CRC Length on the data size */ + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE) + { + /* CRC Length aligned on the data size : value set by default */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + hspi->Init.CRCLength = SPI_CRC_LENGTH_16BIT; + } + else + { + hspi->Init.CRCLength = SPI_CRC_LENGTH_8BIT; + } + } + + /* Configure : CRC Length */ + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCL); + } + } +#endif /* USE_SPI_CRC */ + + /* Configure : NSS management, TI Mode, NSS Pulse, Data size and Rx Fifo threshold */ + WRITE_REG(hspi->Instance->CR2, + (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | + (hspi->Init.TIMode & SPI_CR2_FRF) | (hspi->Init.NSSPMode & SPI_CR2_NSSP) | + (hspi->Init.DataSize & SPI_CR2_DS_Msk) | (frxth & SPI_CR2_FRXTH))); + +#if (USE_SPI_CRC != 0U) + /*---------------------------- SPIx CRCPOLY Configuration ------------------*/ + /* Configure : CRC Polynomial */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + WRITE_REG(hspi->Instance->CRCPR, + (hspi->Init.CRCPolynomial & SPI_CRCPR_CRCPOLY_Msk)); + } +#endif /* USE_SPI_CRC */ + +#if defined(SPI_I2SCFGR_I2SMOD) + /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */ + CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD); +#endif /* SPI_I2SCFGR_I2SMOD */ + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->State = HAL_SPI_STATE_READY; + + return HAL_OK; +} + +/** + * @brief De-Initialize the SPI peripheral. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi) +{ + /* Check the SPI handle allocation */ + if (hspi == NULL) + { + return HAL_ERROR; + } + + /* Check SPI Instance parameter */ + assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); + + hspi->State = HAL_SPI_STATE_BUSY; + + /* Disable the SPI Peripheral Clock */ + __HAL_SPI_DISABLE(hspi); + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + if (hspi->MspDeInitCallback == NULL) + { + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + hspi->MspDeInitCallback(hspi); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + HAL_SPI_MspDeInit(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->State = HAL_SPI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hspi); + + return HAL_OK; +} + +/** + * @brief Initialize the SPI MSP. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_MspInit should be implemented in the user file + */ +} + +/** + * @brief De-Initialize the SPI MSP. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_MspDeInit should be implemented in the user file + */ +} + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User SPI Callback + * To be used instead of the weak predefined callback + * @param hspi Pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI. + * @param CallbackID ID of the callback to be registered + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, + HAL_SPI_CallbackIDTypeDef CallbackID, + pSPI_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hspi); + + if (HAL_SPI_STATE_READY == hspi->State) + { + switch (CallbackID) + { + case HAL_SPI_TX_COMPLETE_CB_ID: + hspi->TxCpltCallback = pCallback; + break; + + case HAL_SPI_RX_COMPLETE_CB_ID: + hspi->RxCpltCallback = pCallback; + break; + + case HAL_SPI_TX_RX_COMPLETE_CB_ID: + hspi->TxRxCpltCallback = pCallback; + break; + + case HAL_SPI_TX_HALF_COMPLETE_CB_ID: + hspi->TxHalfCpltCallback = pCallback; + break; + + case HAL_SPI_RX_HALF_COMPLETE_CB_ID: + hspi->RxHalfCpltCallback = pCallback; + break; + + case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID: + hspi->TxRxHalfCpltCallback = pCallback; + break; + + case HAL_SPI_ERROR_CB_ID: + hspi->ErrorCallback = pCallback; + break; + + case HAL_SPI_ABORT_CB_ID: + hspi->AbortCpltCallback = pCallback; + break; + + case HAL_SPI_MSPINIT_CB_ID: + hspi->MspInitCallback = pCallback; + break; + + case HAL_SPI_MSPDEINIT_CB_ID: + hspi->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SPI_STATE_RESET == hspi->State) + { + switch (CallbackID) + { + case HAL_SPI_MSPINIT_CB_ID: + hspi->MspInitCallback = pCallback; + break; + + case HAL_SPI_MSPDEINIT_CB_ID: + hspi->MspDeInitCallback = pCallback; + break; + + default: + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hspi); + return status; +} + +/** + * @brief Unregister an SPI Callback + * SPI callback is redirected to the weak predefined callback + * @param hspi Pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI. + * @param CallbackID ID of the callback to be unregistered + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, + HAL_SPI_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hspi); + + if (HAL_SPI_STATE_READY == hspi->State) + { + switch (CallbackID) + { + case HAL_SPI_TX_COMPLETE_CB_ID: + hspi->TxCpltCallback = + HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */ + break; + + case HAL_SPI_RX_COMPLETE_CB_ID: + hspi->RxCpltCallback = + HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */ + break; + + case HAL_SPI_TX_RX_COMPLETE_CB_ID: + hspi->TxRxCpltCallback = + HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ + break; + + case HAL_SPI_TX_HALF_COMPLETE_CB_ID: + hspi->TxHalfCpltCallback = + HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ + break; + + case HAL_SPI_RX_HALF_COMPLETE_CB_ID: + hspi->RxHalfCpltCallback = + HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ + break; + + case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID: + hspi->TxRxHalfCpltCallback = + HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ + break; + + case HAL_SPI_ERROR_CB_ID: + hspi->ErrorCallback = + HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_SPI_ABORT_CB_ID: + hspi->AbortCpltCallback = + HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_SPI_MSPINIT_CB_ID: + hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_SPI_MSPDEINIT_CB_ID: + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default: + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_SPI_STATE_RESET == hspi->State) + { + switch (CallbackID) + { + case HAL_SPI_MSPINIT_CB_ID: + hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_SPI_MSPDEINIT_CB_ID: + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default: + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hspi); + return status; +} +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup SPI_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SPI + data transfers. + + [..] The SPI supports master and slave mode : + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and +HAL_SPI_TxRxCpltCallback() user callbacks will be executed respectively at the end of the +transmit or Receive process The HAL_SPI_ErrorCallback()user callback will be executed when +a communication error is detected + + (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using +either Interrupt or DMA) exist for 1Line (simplex) and 2Lines (full duplex) modes. + +@endverbatim + * @{ + */ + +/** + * @brief Transmit an amount of data in blocking mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData pointer to data buffer + * @param Size amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, + uint32_t Timeout) +{ + uint32_t tickstart; + HAL_StatusTypeDef errorcode = HAL_OK; + uint16_t initial_TxXferCount; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + initial_TxXferCount = Size; + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + goto error; + } + + if ((pData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->pRxBuffPtr = (uint8_t *)NULL; + hspi->RxXferSize = 0U; + hspi->RxXferCount = 0U; + hspi->TxISR = NULL; + hspi->RxISR = NULL; + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ + __HAL_SPI_DISABLE(hspi); + SPI_1LINE_TX(hspi); + } + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } +#endif /* USE_SPI_CRC */ + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Transmit data in 16 Bit mode */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U)) + { + hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + } + /* Transmit data in 16 Bit mode */ + while (hspi->TxXferCount > 0U) + { + /* Wait until TXE flag is set to send data */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) + { + hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && + (Timeout != HAL_MAX_DELAY)) || + (Timeout == 0U)) + { + errorcode = HAL_TIMEOUT; + hspi->State = HAL_SPI_STATE_READY; + goto error; + } + } + } + } + /* Transmit data in 8 Bit mode */ + else + { + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U)) + { + *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint8_t); + hspi->TxXferCount--; + } + while (hspi->TxXferCount > 0U) + { + /* Wait until TXE flag is set to send data */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) + { + *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint8_t); + hspi->TxXferCount--; + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && + (Timeout != HAL_MAX_DELAY)) || + (Timeout == 0U)) + { + errorcode = HAL_TIMEOUT; + hspi->State = HAL_SPI_STATE_READY; + goto error; + } + } + } + } +#if (USE_SPI_CRC != 0U) + /* Enable CRC Transmission */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + + /* Check the end of the transaction */ + if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_FLAG; + } + + /* Clear overrun flag in 2 Lines communication mode because received is not read */ + if (hspi->Init.Direction == SPI_DIRECTION_2LINES) + { + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + errorcode = HAL_ERROR; + } + else + { + hspi->State = HAL_SPI_STATE_READY; + } + +error: + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Receive an amount of data in blocking mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData pointer to data buffer + * @param Size amount of data to be received + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, + uint32_t Timeout) +{ +#if (USE_SPI_CRC != 0U) + __IO uint32_t tmpreg = 0U; + __IO uint8_t *ptmpreg8; + __IO uint8_t tmpreg8 = 0; +#endif /* USE_SPI_CRC */ + uint32_t tickstart; + HAL_StatusTypeDef errorcode = HAL_OK; + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + goto error; + } + + if ((hspi->Init.Mode == SPI_MODE_MASTER) && + (hspi->Init.Direction == SPI_DIRECTION_2LINES)) + { + hspi->State = HAL_SPI_STATE_BUSY_RX; + /* Call transmit-receive function to send Dummy data on Tx line and generate clock + * on CLK line */ + return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout); + } + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if ((pData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->pTxBuffPtr = (uint8_t *)NULL; + hspi->TxXferSize = 0U; + hspi->TxXferCount = 0U; + hspi->RxISR = NULL; + hspi->TxISR = NULL; + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + /* this is done to handle the CRCNEXT before the latest data */ + hspi->RxXferCount--; + } +#endif /* USE_SPI_CRC */ + + /* Set the Rx Fifo threshold */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + /* Set RX Fifo threshold according the reception data length: 16bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + else + { + /* Set RX Fifo threshold according the reception data length: 8bit */ + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + + /* Configure communication direction: 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ + __HAL_SPI_DISABLE(hspi); + SPI_1LINE_RX(hspi); + } + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Receive data in 8 Bit mode */ + if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) + { + /* Transfer loop */ + while (hspi->RxXferCount > 0U) + { + /* Check the RXNE flag */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) + { + /* read the received data */ + (*(uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR; + hspi->pRxBuffPtr += sizeof(uint8_t); + hspi->RxXferCount--; + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && + (Timeout != HAL_MAX_DELAY)) || + (Timeout == 0U)) + { + errorcode = HAL_TIMEOUT; + hspi->State = HAL_SPI_STATE_READY; + goto error; + } + } + } + } + else + { + /* Transfer loop */ + while (hspi->RxXferCount > 0U) + { + /* Check the RXNE flag */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) + { + *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR; + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount--; + } + else + { + /* Timeout management */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && + (Timeout != HAL_MAX_DELAY)) || + (Timeout == 0U)) + { + errorcode = HAL_TIMEOUT; + hspi->State = HAL_SPI_STATE_READY; + goto error; + } + } + } + } + +#if (USE_SPI_CRC != 0U) + /* Handle the CRC Transmission */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* freeze the CRC before the latest data */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + + /* Read the latest data */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != + HAL_OK) + { + /* the latest data has not been received */ + errorcode = HAL_TIMEOUT; + goto error; + } + + /* Receive last data in 16 Bit mode */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR; + } + /* Receive last data in 8 Bit mode */ + else + { + (*(uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR; + } + + /* Wait the CRC data */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != + HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + errorcode = HAL_TIMEOUT; + goto error; + } + + /* Read CRC to Flush DR and RXNE flag */ + if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) + { + /* Read 16bit CRC */ + tmpreg = READ_REG(hspi->Instance->DR); + /* To avoid GCC warning */ + UNUSED(tmpreg); + } + else + { + /* Initialize the 8bit temporary pointer */ + ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; + /* Read 8bit CRC */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + + if ((hspi->Init.DataSize == SPI_DATASIZE_8BIT) && + (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT)) + { + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, + tickstart) != HAL_OK) + { + /* Error on the CRC reception */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + errorcode = HAL_TIMEOUT; + goto error; + } + /* Read 8bit CRC again in case of 16bit CRC in 8bit Data mode */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + } + } + } +#endif /* USE_SPI_CRC */ + + /* Check the end of the transaction */ + if (SPI_EndRxTransaction(hspi, Timeout, tickstart) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_FLAG; + } + +#if (USE_SPI_CRC != 0U) + /* Check if CRC error occurred */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + } +#endif /* USE_SPI_CRC */ + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + errorcode = HAL_ERROR; + } + else + { + hspi->State = HAL_SPI_STATE_READY; + } + +error: + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Transmit and Receive an amount of data in blocking mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData pointer to transmission data buffer + * @param pRxData pointer to reception data buffer + * @param Size amount of data to be sent and received + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, + uint8_t *pRxData, uint16_t Size, + uint32_t Timeout) +{ + uint16_t initial_TxXferCount; + uint32_t tmp_mode; + HAL_SPI_StateTypeDef tmp_state; + uint32_t tickstart; +#if (USE_SPI_CRC != 0U) + __IO uint32_t tmpreg = 0U; + uint32_t spi_cr1; + uint32_t spi_cr2; + __IO uint8_t *ptmpreg8; + __IO uint8_t tmpreg8 = 0; +#endif /* USE_SPI_CRC */ + + /* Variable used to alternate Rx and Tx during transfer */ + uint32_t txallowed = 1U; + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Init temporary variables */ + tmp_state = hspi->State; + tmp_mode = hspi->Init.Mode; + initial_TxXferCount = Size; +#if (USE_SPI_CRC != 0U) + spi_cr1 = READ_REG(hspi->Instance->CR1); + spi_cr2 = READ_REG(hspi->Instance->CR2); +#endif /* USE_SPI_CRC */ + + if (!((tmp_state == HAL_SPI_STATE_READY) || + ((tmp_mode == SPI_MODE_MASTER) && + (hspi->Init.Direction == SPI_DIRECTION_2LINES) && + (tmp_state == HAL_SPI_STATE_BUSY_RX)))) + { + errorcode = HAL_BUSY; + goto error; + } + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ + if (hspi->State != HAL_SPI_STATE_BUSY_RX) + { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + + /* Set the transaction information */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferCount = Size; + hspi->RxXferSize = Size; + hspi->pTxBuffPtr = (uint8_t *)pTxData; + hspi->TxXferCount = Size; + hspi->TxXferSize = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = NULL; + hspi->TxISR = NULL; + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } +#endif /* USE_SPI_CRC */ + + /* Set the Rx Fifo threshold */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + /* Set fiforxthreshold according the reception data length: 16bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + else + { + /* Set fiforxthreshold according the reception data length: 8bit */ + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Transmit and Receive data in 16 Bit mode */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U)) + { + hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + +#if (USE_SPI_CRC != 0U) + /* Enable CRC Transmission */ + if ((hspi->TxXferCount == 0U) && + (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + /* Set NSS Soft to received correctly the CRC on slave mode with NSS pulse + * activated */ + if ((READ_BIT(spi_cr1, SPI_CR1_MSTR) == 0U) && + (READ_BIT(spi_cr2, SPI_CR2_NSSP) == SPI_CR2_NSSP)) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_SSM); + } + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + } + while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)) + { + /* Check TXE flag */ + if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && + (txallowed == 1U)) + { + hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + /* Next Data is a reception (Rx). Tx not allowed */ + txallowed = 0U; + +#if (USE_SPI_CRC != 0U) + /* Enable CRC Transmission */ + if ((hspi->TxXferCount == 0U) && + (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + /* Set NSS Soft to received correctly the CRC on slave mode with NSS + * pulse activated */ + if ((READ_BIT(spi_cr1, SPI_CR1_MSTR) == 0U) && + (READ_BIT(spi_cr2, SPI_CR2_NSSP) == SPI_CR2_NSSP)) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_SSM); + } + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + } + + /* Check RXNE flag */ + if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U)) + { + *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR; + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount--; + /* Next Data is a Transmission (Tx). Tx is allowed */ + txallowed = 1U; + } + if (((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) + { + errorcode = HAL_TIMEOUT; + hspi->State = HAL_SPI_STATE_READY; + goto error; + } + } + } + /* Transmit and Receive data in 8 Bit mode */ + else + { + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U)) + { + *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint8_t); + hspi->TxXferCount--; + +#if (USE_SPI_CRC != 0U) + /* Enable CRC Transmission */ + if ((hspi->TxXferCount == 0U) && + (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + /* Set NSS Soft to received correctly the CRC on slave mode with NSS pulse + * activated */ + if ((READ_BIT(spi_cr1, SPI_CR1_MSTR) == 0U) && + (READ_BIT(spi_cr2, SPI_CR2_NSSP) == SPI_CR2_NSSP)) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_SSM); + } + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + } + while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)) + { + /* Check TXE flag */ + if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && + (txallowed == 1U)) + { + *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr); + hspi->pTxBuffPtr++; + hspi->TxXferCount--; + /* Next Data is a reception (Rx). Tx not allowed */ + txallowed = 0U; + +#if (USE_SPI_CRC != 0U) + /* Enable CRC Transmission */ + if ((hspi->TxXferCount == 0U) && + (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + /* Set NSS Soft to received correctly the CRC on slave mode with NSS + * pulse activated */ + if ((READ_BIT(spi_cr1, SPI_CR1_MSTR) == 0U) && + (READ_BIT(spi_cr2, SPI_CR2_NSSP) == SPI_CR2_NSSP)) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_SSM); + } + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + } + + /* Wait until RXNE flag is reset */ + if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U)) + { + (*(uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR; + hspi->pRxBuffPtr++; + hspi->RxXferCount--; + /* Next Data is a Transmission (Tx). Tx is allowed */ + txallowed = 1U; + } + if ((((HAL_GetTick() - tickstart) >= Timeout) && + ((Timeout != HAL_MAX_DELAY))) || + (Timeout == 0U)) + { + errorcode = HAL_TIMEOUT; + hspi->State = HAL_SPI_STATE_READY; + goto error; + } + } + } + +#if (USE_SPI_CRC != 0U) + /* Read CRC from DR to close CRC calculation process */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Wait until TXE flag */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != + HAL_OK) + { + /* Error on the CRC reception */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + errorcode = HAL_TIMEOUT; + goto error; + } + /* Read CRC */ + if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) + { + /* Read 16bit CRC */ + tmpreg = READ_REG(hspi->Instance->DR); + /* To avoid GCC warning */ + UNUSED(tmpreg); + } + else + { + /* Initialize the 8bit temporary pointer */ + ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; + /* Read 8bit CRC */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT) + { + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, + tickstart) != HAL_OK) + { + /* Error on the CRC reception */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + errorcode = HAL_TIMEOUT; + goto error; + } + /* Read 8bit CRC again in case of 16bit CRC in 8bit Data mode */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + } + } + } + + /* Check if CRC error occurred */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + /* Clear CRC Flag */ + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + + errorcode = HAL_ERROR; + } +#endif /* USE_SPI_CRC */ + + /* Check the end of the transaction */ + if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK) + { + errorcode = HAL_ERROR; + hspi->ErrorCode = HAL_SPI_ERROR_FLAG; + } + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + errorcode = HAL_ERROR; + } + else + { + hspi->State = HAL_SPI_STATE_READY; + } + +error: + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Transmit an amount of data in non-blocking mode with Interrupt. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData pointer to data buffer + * @param Size amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); + + + if ((pData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + goto error; + } + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /* Init field not used in handle to zero */ + hspi->pRxBuffPtr = (uint8_t *)NULL; + hspi->RxXferSize = 0U; + hspi->RxXferCount = 0U; + hspi->RxISR = NULL; + + /* Set the function for IT treatment */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + hspi->TxISR = SPI_TxISR_16BIT; + } + else + { + hspi->TxISR = SPI_TxISR_8BIT; + } + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ + __HAL_SPI_DISABLE(hspi); + SPI_1LINE_TX(hspi); + } + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } +#endif /* USE_SPI_CRC */ + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + /* Enable TXE and ERR interrupt */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR)); + +error: + return errorcode; +} + +/** + * @brief Receive an amount of data in non-blocking mode with Interrupt. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData pointer to data buffer + * @param Size amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + goto error; + } + + if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && + (hspi->Init.Mode == SPI_MODE_MASTER)) + { + hspi->State = HAL_SPI_STATE_BUSY_RX; + /* Call transmit-receive function to send Dummy data on Tx line and generate clock + * on CLK line */ + return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size); + } + + + if ((pData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /* Init field not used in handle to zero */ + hspi->pTxBuffPtr = (uint8_t *)NULL; + hspi->TxXferSize = 0U; + hspi->TxXferCount = 0U; + hspi->TxISR = NULL; + + /* Check the data size to adapt Rx threshold and the set the function for IT treatment + */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + /* Set RX Fifo threshold according the reception data length: 16 bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + hspi->RxISR = SPI_RxISR_16BIT; + } + else + { + /* Set RX Fifo threshold according the reception data length: 8 bit */ + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + hspi->RxISR = SPI_RxISR_8BIT; + } + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ + __HAL_SPI_DISABLE(hspi); + SPI_1LINE_RX(hspi); + } + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->CRCSize = 1U; + if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && + (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT)) + { + hspi->CRCSize = 2U; + } + SPI_RESET_CRC(hspi); + } + else + { + hspi->CRCSize = 0U; + } +#endif /* USE_SPI_CRC */ + + /* Note : The SPI must be enabled after unlocking current process + to avoid the risk of SPI interrupt handle execution before current + process unlock */ + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + /* Enable RXNE and ERR interrupt */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); + +error: + return errorcode; +} + +/** + * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData pointer to transmission data buffer + * @param pRxData pointer to reception data buffer + * @param Size amount of data to be sent and received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, + uint8_t *pRxData, uint16_t Size) +{ + uint32_t tmp_mode; + HAL_SPI_StateTypeDef tmp_state; + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Init temporary variables */ + tmp_state = hspi->State; + tmp_mode = hspi->Init.Mode; + + if (!((tmp_state == HAL_SPI_STATE_READY) || + ((tmp_mode == SPI_MODE_MASTER) && + (hspi->Init.Direction == SPI_DIRECTION_2LINES) && + (tmp_state == HAL_SPI_STATE_BUSY_RX)))) + { + errorcode = HAL_BUSY; + goto error; + } + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + /* Process locked */ + __HAL_LOCK(hspi); + + /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ + if (hspi->State != HAL_SPI_STATE_BUSY_RX) + { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + + /* Set the transaction information */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /* Set the function for IT treatment */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + hspi->RxISR = SPI_2linesRxISR_16BIT; + hspi->TxISR = SPI_2linesTxISR_16BIT; + } + else + { + hspi->RxISR = SPI_2linesRxISR_8BIT; + hspi->TxISR = SPI_2linesTxISR_8BIT; + } + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->CRCSize = 1U; + if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && + (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT)) + { + hspi->CRCSize = 2U; + } + SPI_RESET_CRC(hspi); + } + else + { + hspi->CRCSize = 0U; + } +#endif /* USE_SPI_CRC */ + + /* Check if packing mode is enabled and if there is more than 2 data to receive */ + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (Size >= 2U)) + { + /* Set RX Fifo threshold according the reception data length: 16 bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + else + { + /* Set RX Fifo threshold according the reception data length: 8 bit */ + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + /* Enable TXE, RXNE and ERR interrupt */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); + +error: + return errorcode; +} + +/** + * @brief Transmit an amount of data in non-blocking mode with DMA. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData pointer to data buffer + * @param Size amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check tx dma handle */ + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + goto error; + } + + if ((pData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /* Init field not used in handle to zero */ + hspi->pRxBuffPtr = (uint8_t *)NULL; + hspi->TxISR = NULL; + hspi->RxISR = NULL; + hspi->RxXferSize = 0U; + hspi->RxXferCount = 0U; + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ + __HAL_SPI_DISABLE(hspi); + SPI_1LINE_TX(hspi); + } + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } +#endif /* USE_SPI_CRC */ + + /* Set the SPI TxDMA Half transfer complete callback */ + hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt; + + /* Set the SPI TxDMA transfer complete callback */ + hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt; + + /* Set the DMA error callback */ + hspi->hdmatx->XferErrorCallback = SPI_DMAError; + + /* Set the DMA AbortCpltCallback */ + hspi->hdmatx->XferAbortCallback = NULL; + + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX); + /* Packing mode is enabled only if the DMA setting is HALWORD */ + if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && + (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)) + { + /* Check the even/odd of the data size + crc if enabled */ + if ((hspi->TxXferCount & 0x1U) == 0U) + { + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX); + hspi->TxXferCount = (hspi->TxXferCount >> 1U); + } + else + { + SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX); + hspi->TxXferCount = (hspi->TxXferCount >> 1U) + 1U; + } + } + + /* Enable the Tx DMA Stream/Channel */ + if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, + (uint32_t)&hspi->Instance->DR, hspi->TxXferCount)) + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + errorcode = HAL_ERROR; + + goto error; + } + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Enable the SPI Error Interrupt Bit */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR)); + + /* Enable Tx DMA Request */ + SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); + +error: + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Receive an amount of data in non-blocking mode with DMA. + * @note In case of MASTER mode and SPI_DIRECTION_2LINES direction, hdmatx shall be + * defined. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData pointer to data buffer + * @note When the CRC feature is enabled the pData Length must be Size + 1. + * @param Size amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check rx dma handle */ + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx)); + + if (hspi->State != HAL_SPI_STATE_READY) + { + errorcode = HAL_BUSY; + goto error; + } + + if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && + (hspi->Init.Mode == SPI_MODE_MASTER)) + { + hspi->State = HAL_SPI_STATE_BUSY_RX; + + /* Check tx dma handle */ + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); + + /* Call transmit-receive function to send Dummy data on Tx line and generate clock + * on CLK line */ + return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size); + } + + /* Process Locked */ + __HAL_LOCK(hspi); + + if ((pData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + /* Set the transaction information */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = NULL; + hspi->TxISR = NULL; + hspi->TxXferSize = 0U; + hspi->TxXferCount = 0U; + + /* Configure communication direction : 1Line */ + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ + __HAL_SPI_DISABLE(hspi); + SPI_1LINE_RX(hspi); + } + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } +#endif /* USE_SPI_CRC */ + +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || \ + defined(STM32F038xx) || defined(STM32F051x8) || defined(STM32F058xx) + /* Packing mode management is enabled by the DMA settings */ + if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && + (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)) + { + /* Restriction the DMA data received is not allowed in this mode */ + errorcode = HAL_ERROR; + goto error; + } +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F038xx || STM32F051x8 || \ + STM32F058xx */ + + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX); + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + /* Set RX Fifo threshold according the reception data length: 16bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + else + { + /* Set RX Fifo threshold according the reception data length: 8bit */ + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + + if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) + { + /* Set RX Fifo threshold according the reception data length: 16bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + + if ((hspi->RxXferCount & 0x1U) == 0x0U) + { + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX); + hspi->RxXferCount = hspi->RxXferCount >> 1U; + } + else + { + SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX); + hspi->RxXferCount = (hspi->RxXferCount >> 1U) + 1U; + } + } + } + + /* Set the SPI RxDMA Half transfer complete callback */ + hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; + + /* Set the SPI Rx DMA transfer complete callback */ + hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; + + /* Set the DMA error callback */ + hspi->hdmarx->XferErrorCallback = SPI_DMAError; + + /* Set the DMA AbortCpltCallback */ + hspi->hdmarx->XferAbortCallback = NULL; + + /* Enable the Rx DMA Stream/Channel */ + if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, + (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount)) + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + errorcode = HAL_ERROR; + + goto error; + } + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Enable the SPI Error Interrupt Bit */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR)); + + /* Enable Rx DMA Request */ + SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); + +error: + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Transmit and Receive an amount of data in non-blocking mode with DMA. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData pointer to transmission data buffer + * @param pRxData pointer to reception data buffer + * @note When the CRC feature is enabled the pRxData Length must be Size + 1 + * @param Size amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, + uint8_t *pRxData, uint16_t Size) +{ + uint32_t tmp_mode; + HAL_SPI_StateTypeDef tmp_state; + HAL_StatusTypeDef errorcode = HAL_OK; + + /* Check rx & tx dma handles */ + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx)); + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Process locked */ + __HAL_LOCK(hspi); + + /* Init temporary variables */ + tmp_state = hspi->State; + tmp_mode = hspi->Init.Mode; + + if (!((tmp_state == HAL_SPI_STATE_READY) || + ((tmp_mode == SPI_MODE_MASTER) && + (hspi->Init.Direction == SPI_DIRECTION_2LINES) && + (tmp_state == HAL_SPI_STATE_BUSY_RX)))) + { + errorcode = HAL_BUSY; + goto error; + } + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + { + errorcode = HAL_ERROR; + goto error; + } + + /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ + if (hspi->State != HAL_SPI_STATE_BUSY_RX) + { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + + /* Set the transaction information */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /* Init field not used in handle to zero */ + hspi->RxISR = NULL; + hspi->TxISR = NULL; + +#if (USE_SPI_CRC != 0U) + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } +#endif /* USE_SPI_CRC */ + +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || \ + defined(STM32F038xx) || defined(STM32F051x8) || defined(STM32F058xx) + /* Packing mode management is enabled by the DMA settings */ + if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && + (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)) + { + /* Restriction the DMA data received is not allowed in this mode */ + errorcode = HAL_ERROR; + goto error; + } +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F038xx || STM32F051x8 || \ + STM32F058xx */ + + /* Reset the threshold bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX | SPI_CR2_LDMARX); + + /* The packing mode management is enabled by the DMA settings according the spi data + * size */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + /* Set fiforxthreshold according the reception data length: 16bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + else + { + /* Set RX Fifo threshold according the reception data length: 8bit */ + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + + if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) + { + if ((hspi->TxXferSize & 0x1U) == 0x0U) + { + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX); + hspi->TxXferCount = hspi->TxXferCount >> 1U; + } + else + { + SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX); + hspi->TxXferCount = (hspi->TxXferCount >> 1U) + 1U; + } + } + + if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) + { + /* Set RX Fifo threshold according the reception data length: 16bit */ + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + + if ((hspi->RxXferCount & 0x1U) == 0x0U) + { + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX); + hspi->RxXferCount = hspi->RxXferCount >> 1U; + } + else + { + SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX); + hspi->RxXferCount = (hspi->RxXferCount >> 1U) + 1U; + } + } + } + + /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete + * callback */ + if (hspi->State == HAL_SPI_STATE_BUSY_RX) + { + /* Set the SPI Rx DMA Half transfer complete callback */ + hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; + hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; + } + else + { + /* Set the SPI Tx/Rx DMA Half transfer complete callback */ + hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt; + hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt; + } + + /* Set the DMA error callback */ + hspi->hdmarx->XferErrorCallback = SPI_DMAError; + + /* Set the DMA AbortCpltCallback */ + hspi->hdmarx->XferAbortCallback = NULL; + + /* Enable the Rx DMA Stream/Channel */ + if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, + (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount)) + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + errorcode = HAL_ERROR; + + goto error; + } + + /* Enable Rx DMA Request */ + SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); + + /* Set the SPI Tx DMA transfer complete callback as NULL because the communication + closing is performed in DMA reception complete callback */ + hspi->hdmatx->XferHalfCpltCallback = NULL; + hspi->hdmatx->XferCpltCallback = NULL; + hspi->hdmatx->XferErrorCallback = NULL; + hspi->hdmatx->XferAbortCallback = NULL; + + /* Enable the Tx DMA Stream/Channel */ + if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, + (uint32_t)&hspi->Instance->DR, hspi->TxXferCount)) + { + /* Update SPI error code */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + errorcode = HAL_ERROR; + + goto error; + } + + /* Check if the SPI is already enabled */ + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + /* Enable the SPI Error Interrupt Bit */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR)); + + /* Enable Tx DMA Request */ + SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); + +error: + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + return errorcode; +} + +/** + * @brief Abort ongoing transfer (blocking mode). + * @param hspi SPI handle. + * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), + * started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SPI Interrupts (depending of transfer direction) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA + * mode) + * - Set handle State to READY + * @note This procedure is executed in blocking mode : when exiting function, Abort is + * considered as completed. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi) +{ + HAL_StatusTypeDef errorcode; + __IO uint32_t count; + __IO uint32_t resetcount; + + /* Initialized local variable */ + errorcode = HAL_OK; + resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); + count = resetcount; + + /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure + */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); + + /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) + * interrupts */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) + { + hspi->TxISR = SPI_AbortTx_ISR; + /* Wait HAL_SPI_STATE_ABORT state */ + do + { + if (count == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + count--; + } while (hspi->State != HAL_SPI_STATE_ABORT); + /* Reset Timeout Counter */ + count = resetcount; + } + + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) + { + hspi->RxISR = SPI_AbortRx_ISR; + /* Wait HAL_SPI_STATE_ABORT state */ + do + { + if (count == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + count--; + } while (hspi->State != HAL_SPI_STATE_ABORT); + /* Reset Timeout Counter */ + count = resetcount; + } + + /* Disable the SPI DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) + { + /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) + */ + if (hspi->hdmatx != NULL) + { + /* Set the SPI DMA Abort callback : + will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */ + hspi->hdmatx->XferAbortCallback = NULL; + + /* Abort DMA Tx Handle linked to SPI Peripheral */ + if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Disable Tx DMA Request */ + CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN)); + + if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != + HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Disable SPI Peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Empty the FRLVL fifo */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, + SPI_DEFAULT_TIMEOUT, + HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + } + } + + /* Disable the SPI DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)) + { + /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) + */ + if (hspi->hdmarx != NULL) + { + /* Set the SPI DMA Abort callback : + will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */ + hspi->hdmarx->XferAbortCallback = NULL; + + /* Abort DMA Rx Handle linked to SPI Peripheral */ + if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Disable peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Control the BSY flag */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, + SPI_DEFAULT_TIMEOUT, + HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Empty the FRLVL fifo */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, + SPI_DEFAULT_TIMEOUT, + HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Disable Rx DMA Request */ + CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN)); + } + } + /* Reset Tx and Rx transfer counters */ + hspi->RxXferCount = 0U; + hspi->TxXferCount = 0U; + + /* Check error during Abort procedure */ + if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT) + { + /* return HAL_Error in case of error during Abort procedure */ + errorcode = HAL_ERROR; + } + else + { + /* Reset errorCode */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + } + + /* Clear the Error flags in the SR register */ + __HAL_SPI_CLEAR_OVRFLAG(hspi); + __HAL_SPI_CLEAR_FREFLAG(hspi); + + /* Restore hspi->state to ready */ + hspi->State = HAL_SPI_STATE_READY; + + return errorcode; +} + +/** + * @brief Abort ongoing transfer (Interrupt mode). + * @param hspi SPI handle. + * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), + * started in Interrupt or DMA mode. + * This procedure performs following operations : + * - Disable SPI Interrupts (depending of transfer direction) + * - Disable the DMA transfer in the peripheral register (if enabled) + * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA + * mode) + * - Set handle State to READY + * - At abort completion, call user abort complete callback + * @note This procedure is executed in Interrupt mode, meaning that abort procedure + * could be considered as completed only when user abort complete callback is executed + * (not when exiting function). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi) +{ + HAL_StatusTypeDef errorcode; + uint32_t abortcplt; + __IO uint32_t count; + __IO uint32_t resetcount; + + /* Initialized local variable */ + errorcode = HAL_OK; + abortcplt = 1U; + resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); + count = resetcount; + + /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure + */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); + + /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) + { + hspi->TxISR = SPI_AbortTx_ISR; + /* Wait HAL_SPI_STATE_ABORT state */ + do + { + if (count == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + count--; + } while (hspi->State != HAL_SPI_STATE_ABORT); + /* Reset Timeout Counter */ + count = resetcount; + } + + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) + { + hspi->RxISR = SPI_AbortRx_ISR; + /* Wait HAL_SPI_STATE_ABORT state */ + do + { + if (count == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + count--; + } while (hspi->State != HAL_SPI_STATE_ABORT); + /* Reset Timeout Counter */ + count = resetcount; + } + + /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete + callbacks should be initialised before any call to DMA Abort functions */ + /* DMA Tx Handle is valid */ + if (hspi->hdmatx != NULL) + { + /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) + { + hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback; + } + else + { + hspi->hdmatx->XferAbortCallback = NULL; + } + } + /* DMA Rx Handle is valid */ + if (hspi->hdmarx != NULL) + { + /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. + Otherwise, set it to NULL */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)) + { + hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback; + } + else + { + hspi->hdmarx->XferAbortCallback = NULL; + } + } + + /* Disable the SPI DMA Tx request if enabled */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) + { + /* Abort the SPI DMA Tx Stream/Channel */ + if (hspi->hdmatx != NULL) + { + /* Abort DMA Tx Handle linked to SPI Peripheral */ + if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK) + { + hspi->hdmatx->XferAbortCallback = NULL; + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + else + { + abortcplt = 0U; + } + } + } + /* Disable the SPI DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)) + { + /* Abort the SPI DMA Rx Stream/Channel */ + if (hspi->hdmarx != NULL) + { + /* Abort DMA Rx Handle linked to SPI Peripheral */ + if (HAL_DMA_Abort_IT(hspi->hdmarx) != HAL_OK) + { + hspi->hdmarx->XferAbortCallback = NULL; + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + else + { + abortcplt = 0U; + } + } + } + + if (abortcplt == 1U) + { + /* Reset Tx and Rx transfer counters */ + hspi->RxXferCount = 0U; + hspi->TxXferCount = 0U; + + /* Check error during Abort procedure */ + if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT) + { + /* return HAL_Error in case of error during Abort procedure */ + errorcode = HAL_ERROR; + } + else + { + /* Reset errorCode */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + } + + /* Clear the Error flags in the SR register */ + __HAL_SPI_CLEAR_OVRFLAG(hspi); + __HAL_SPI_CLEAR_FREFLAG(hspi); + + /* Restore hspi->State to Ready */ + hspi->State = HAL_SPI_STATE_READY; + + /* As no DMA to be aborted, call directly user Abort complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->AbortCpltCallback(hspi); +#else + HAL_SPI_AbortCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + + return errorcode; +} + +/** + * @brief Pause the DMA Transfer. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi) +{ + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Disable the SPI DMA Tx & Rx requests */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_OK; +} + +/** + * @brief Resume the DMA Transfer. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi) +{ + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Enable the SPI DMA Tx & Rx requests */ + SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_OK; +} + +/** + * @brief Stop the DMA Transfer. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + /* The Lock is not implemented on this API to allow the user application + to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or + HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback(): when calling + HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated and the + correspond call back is executed HAL_SPI_TxCpltCallback() or + HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback() + */ + + /* Abort the SPI DMA tx Stream/Channel */ + if (hspi->hdmatx != NULL) + { + if (HAL_OK != HAL_DMA_Abort(hspi->hdmatx)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + errorcode = HAL_ERROR; + } + } + /* Abort the SPI DMA rx Stream/Channel */ + if (hspi->hdmarx != NULL) + { + if (HAL_OK != HAL_DMA_Abort(hspi->hdmarx)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + errorcode = HAL_ERROR; + } + } + + /* Disable the SPI DMA Tx & Rx requests */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); + hspi->State = HAL_SPI_STATE_READY; + return errorcode; +} + +/** + * @brief Handle SPI interrupt request. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval None + */ +void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi) +{ + uint32_t itsource = hspi->Instance->CR2; + uint32_t itflag = hspi->Instance->SR; + + /* SPI in mode Receiver ----------------------------------------------------*/ + if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) == RESET) && + (SPI_CHECK_FLAG(itflag, SPI_FLAG_RXNE) != RESET) && + (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_RXNE) != RESET)) + { + hspi->RxISR(hspi); + return; + } + + /* SPI in mode Transmitter -------------------------------------------------*/ + if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_TXE) != RESET) && + (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_TXE) != RESET)) + { + hspi->TxISR(hspi); + return; + } + + /* SPI in Error Treatment --------------------------------------------------*/ + if (((SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET) || + (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET) || + (SPI_CHECK_FLAG(itflag, SPI_FLAG_FRE) != RESET)) && + (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_ERR) != RESET)) + { + /* SPI Overrun error interrupt occurred ----------------------------------*/ + if (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET) + { + if (hspi->State != HAL_SPI_STATE_BUSY_TX) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR); + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + else + { + __HAL_SPI_CLEAR_OVRFLAG(hspi); + return; + } + } + + /* SPI Mode Fault error interrupt occurred -------------------------------*/ + if (SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF); + __HAL_SPI_CLEAR_MODFFLAG(hspi); + } + + /* SPI Frame error interrupt occurred ------------------------------------*/ + if (SPI_CHECK_FLAG(itflag, SPI_FLAG_FRE) != RESET) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE); + __HAL_SPI_CLEAR_FREFLAG(hspi); + } + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + /* Disable all interrupts */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR); + + hspi->State = HAL_SPI_STATE_READY; + /* Disable the SPI DMA requests if enabled */ + if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN)) || + (HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN))) + { + CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN)); + + /* Abort the SPI DMA Rx channel */ + if (hspi->hdmarx != NULL) + { + /* Set the SPI DMA Abort callback : + will lead to call HAL_SPI_ErrorCallback() at end of DMA abort + procedure */ + hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError; + if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + } + } + /* Abort the SPI DMA Tx channel */ + if (hspi->hdmatx != NULL) + { + /* Set the SPI DMA Abort callback : + will lead to call HAL_SPI_ErrorCallback() at end of DMA abort + procedure */ + hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError; + if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + } + } + } + else + { + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + } + return; + } +} + +/** + * @brief Tx Transfer completed callback. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_TxCpltCallback should be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callback. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_RxCpltCallback should be implemented in the user file + */ +} + +/** + * @brief Tx and Rx Transfer completed callback. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_TxRxCpltCallback should be implemented in the user file + */ +} + +/** + * @brief Tx Half Transfer completed callback. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_TxHalfCpltCallback should be implemented in the user file + */ +} + +/** + * @brief Rx Half Transfer completed callback. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file + */ +} + +/** + * @brief Tx and Rx Half Transfer callback. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file + */ +} + +/** + * @brief SPI error callback. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_ErrorCallback should be implemented in the user file + */ + /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes + and user can use HAL_SPI_GetError() API to check the latest error occurred + */ +} + +/** + * @brief SPI Abort Complete callback. + * @param hspi SPI handle. + * @retval None + */ +__weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hspi); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_SPI_AbortCpltCallback can be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief SPI control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SPI. + (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI +peripheral + (+) HAL_SPI_GetError() check in run-time Errors occurring during communication +@endverbatim + * @{ + */ + +/** + * @brief Return the SPI handle state. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval SPI state + */ +HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi) +{ + /* Return SPI handle state */ + return hspi->State; +} + +/** + * @brief Return the SPI error code. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval SPI error code in bitmap format + */ +uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi) +{ + /* Return SPI ErrorCode */ + return hspi->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup SPI_Private_Functions + * @brief Private functions + * @{ + */ + +/** + * @brief DMA SPI transmit process complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + uint32_t tickstart; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* DMA Normal Mode */ + if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC) + { + /* Disable ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); + + /* Disable Tx DMA Request */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); + + /* Check the end of the transaction */ + if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + } + + /* Clear overrun flag in 2 Lines communication mode because received data is not + * read */ + if (hspi->Init.Direction == SPI_DIRECTION_2LINES) + { + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + + hspi->TxXferCount = 0U; + hspi->State = HAL_SPI_STATE_READY; + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + return; + } + } + /* Call user Tx complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxCpltCallback(hspi); +#else + HAL_SPI_TxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI receive process complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + uint32_t tickstart; +#if (USE_SPI_CRC != 0U) + __IO uint32_t tmpreg = 0U; + __IO uint8_t *ptmpreg8; + __IO uint8_t tmpreg8 = 0; +#endif /* USE_SPI_CRC */ + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* DMA Normal Mode */ + if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC) + { + /* Disable ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); + +#if (USE_SPI_CRC != 0U) + /* CRC handling */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Wait until RXNE flag */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, + SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) + { + /* Error on the CRC reception */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + } + /* Read CRC */ + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + { + /* Read 16bit CRC */ + tmpreg = READ_REG(hspi->Instance->DR); + /* To avoid GCC warning */ + UNUSED(tmpreg); + } + else + { + /* Initialize the 8bit temporary pointer */ + ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; + /* Read 8bit CRC */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT) + { + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, + SPI_DEFAULT_TIMEOUT, + tickstart) != HAL_OK) + { + /* Error on the CRC reception */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + } + /* Read 8bit CRC again in case of 16bit CRC in 8bit Data mode */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + } + } + } +#endif /* USE_SPI_CRC */ + + /* Check if we are in Master RX 2 line mode */ + if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && + (hspi->Init.Mode == SPI_MODE_MASTER)) + { + /* Disable Rx/Tx DMA Request (done by default to handle the case master rx + * direction 2 lines) */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); + } + else + { + /* Normal case */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); + } + + /* Check the end of the transaction */ + if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_FLAG; + } + + hspi->RxXferCount = 0U; + hspi->State = HAL_SPI_STATE_READY; + +#if (USE_SPI_CRC != 0U) + /* Check if CRC error occurred */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + } +#endif /* USE_SPI_CRC */ + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + return; + } + } + /* Call user Rx complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->RxCpltCallback(hspi); +#else + HAL_SPI_RxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI transmit receive process complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + uint32_t tickstart; +#if (USE_SPI_CRC != 0U) + __IO uint32_t tmpreg = 0U; + __IO uint8_t *ptmpreg8; + __IO uint8_t tmpreg8 = 0; +#endif /* USE_SPI_CRC */ + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* DMA Normal Mode */ + if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC) + { + /* Disable ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); + +#if (USE_SPI_CRC != 0U) + /* CRC handling */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + if ((hspi->Init.DataSize == SPI_DATASIZE_8BIT) && + (hspi->Init.CRCLength == SPI_CRC_LENGTH_8BIT)) + { + if (SPI_WaitFifoStateUntilTimeout( + hspi, SPI_FLAG_FRLVL, SPI_FRLVL_QUARTER_FULL, SPI_DEFAULT_TIMEOUT, + tickstart) != HAL_OK) + { + /* Error on the CRC reception */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + } + /* Initialize the 8bit temporary pointer */ + ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; + /* Read 8bit CRC */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + } + else + { + if (SPI_WaitFifoStateUntilTimeout( + hspi, SPI_FLAG_FRLVL, SPI_FRLVL_HALF_FULL, SPI_DEFAULT_TIMEOUT, + tickstart) != HAL_OK) + { + /* Error on the CRC reception */ + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + } + /* Read CRC to Flush DR and RXNE flag */ + tmpreg = READ_REG(hspi->Instance->DR); + /* To avoid GCC warning */ + UNUSED(tmpreg); + } + } +#endif /* USE_SPI_CRC */ + + /* Check the end of the transaction */ + if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + } + + /* Disable Rx/Tx DMA Request */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); + + hspi->TxXferCount = 0U; + hspi->RxXferCount = 0U; + hspi->State = HAL_SPI_STATE_READY; + +#if (USE_SPI_CRC != 0U) + /* Check if CRC error occurred */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + } +#endif /* USE_SPI_CRC */ + + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + return; + } + } + /* Call user TxRx complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxRxCpltCallback(hspi); +#else + HAL_SPI_TxRxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI half transmit process complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Call user Tx half complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxHalfCpltCallback(hspi); +#else + HAL_SPI_TxHalfCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI half receive process complete callback + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Call user Rx half complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->RxHalfCpltCallback(hspi); +#else + HAL_SPI_RxHalfCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI half transmit receive process complete callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Call user TxRx half complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxRxHalfCpltCallback(hspi); +#else + HAL_SPI_TxRxHalfCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI communication error callback. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAError(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Stop the disable DMA transfer on SPI side */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); + + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); + hspi->State = HAL_SPI_STATE_READY; + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI communication abort callback, when initiated by HAL services on Error + * (To be called at end of DMA Abort procedure following error occurrence). + * @param hdma DMA handle. + * @retval None + */ +static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + hspi->RxXferCount = 0U; + hspi->TxXferCount = 0U; + + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI Tx communication abort callback, when initiated by user + * (To be called at end of DMA Tx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if + * no Abort still ongoing for Rx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + hspi->hdmatx->XferAbortCallback = NULL; + + /* Disable Tx DMA Request */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); + + if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Disable SPI Peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Empty the FRLVL fifo */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, + SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Check if an Abort process is still ongoing */ + if (hspi->hdmarx != NULL) + { + if (hspi->hdmarx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user + * Abort Complete callback */ + hspi->RxXferCount = 0U; + hspi->TxXferCount = 0U; + + /* Check no error during Abort procedure */ + if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT) + { + /* Reset errorCode */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + } + + /* Clear the Error flags in the SR register */ + __HAL_SPI_CLEAR_OVRFLAG(hspi); + __HAL_SPI_CLEAR_FREFLAG(hspi); + + /* Restore hspi->State to Ready */ + hspi->State = HAL_SPI_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->AbortCpltCallback(hspi); +#else + HAL_SPI_AbortCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA SPI Rx communication abort callback, when initiated by user + * (To be called at end of DMA Rx Abort procedure following user abort request). + * @note When this callback is executed, User Abort complete call back is called only if + * no Abort still ongoing for Tx DMA Handle. + * @param hdma DMA handle. + * @retval None + */ +static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef *hspi = + (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma) + ->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Disable SPI Peripheral */ + __HAL_SPI_DISABLE(hspi); + + hspi->hdmarx->XferAbortCallback = NULL; + + /* Disable Rx DMA Request */ + CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); + + /* Control the BSY flag */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, SPI_DEFAULT_TIMEOUT, + HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Empty the FRLVL fifo */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, + SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Check if an Abort process is still ongoing */ + if (hspi->hdmatx != NULL) + { + if (hspi->hdmatx->XferAbortCallback != NULL) + { + return; + } + } + + /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user + * Abort Complete callback */ + hspi->RxXferCount = 0U; + hspi->TxXferCount = 0U; + + /* Check no error during Abort procedure */ + if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT) + { + /* Reset errorCode */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + } + + /* Clear the Error flags in the SR register */ + __HAL_SPI_CLEAR_OVRFLAG(hspi); + __HAL_SPI_CLEAR_FREFLAG(hspi); + + /* Restore hspi->State to Ready */ + hspi->State = HAL_SPI_STATE_READY; + + /* Call user Abort complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->AbortCpltCallback(hspi); +#else + HAL_SPI_AbortCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +} + +/** + * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi) +{ + /* Receive data in packing mode */ + if (hspi->RxXferCount > 1U) + { + *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR); + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount -= 2U; + if (hspi->RxXferCount == 1U) + { + /* Set RX Fifo threshold according the reception data length: 8bit */ + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + } + } + /* Receive data in 8 Bit mode */ + else + { + *hspi->pRxBuffPtr = *((__IO uint8_t *)&hspi->Instance->DR); + hspi->pRxBuffPtr++; + hspi->RxXferCount--; + } + + /* Check end of the reception */ + if (hspi->RxXferCount == 0U) + { +#if (USE_SPI_CRC != 0U) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + hspi->RxISR = SPI_2linesRxISR_8BITCRC; + return; + } +#endif /* USE_SPI_CRC */ + + /* Disable RXNE and ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); + + if (hspi->TxXferCount == 0U) + { + SPI_CloseRxTx_ISR(hspi); + } + } +} + +#if (USE_SPI_CRC != 0U) +/** + * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi) +{ + __IO uint8_t *ptmpreg8; + __IO uint8_t tmpreg8 = 0; + + /* Initialize the 8bit temporary pointer */ + ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; + /* Read 8bit CRC to flush Data Register */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + + hspi->CRCSize--; + + /* Check end of the reception */ + if (hspi->CRCSize == 0U) + { + /* Disable RXNE and ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); + + if (hspi->TxXferCount == 0U) + { + SPI_CloseRxTx_ISR(hspi); + } + } +} +#endif /* USE_SPI_CRC */ + +/** + * @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi) +{ + /* Transmit data in packing Bit mode */ + if (hspi->TxXferCount >= 2U) + { + hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount -= 2U; + } + /* Transmit data in 8 Bit mode */ + else + { + *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr); + hspi->pTxBuffPtr++; + hspi->TxXferCount--; + } + + /* Check the end of the transmission */ + if (hspi->TxXferCount == 0U) + { +#if (USE_SPI_CRC != 0U) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Set CRC Next Bit to send CRC */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + /* Disable TXE interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); + return; + } +#endif /* USE_SPI_CRC */ + + /* Disable TXE interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); + + if (hspi->RxXferCount == 0U) + { + SPI_CloseRxTx_ISR(hspi); + } + } +} + +/** + * @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi) +{ + /* Receive data in 16 Bit mode */ + *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR); + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount--; + + if (hspi->RxXferCount == 0U) + { +#if (USE_SPI_CRC != 0U) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->RxISR = SPI_2linesRxISR_16BITCRC; + return; + } +#endif /* USE_SPI_CRC */ + + /* Disable RXNE interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE); + + if (hspi->TxXferCount == 0U) + { + SPI_CloseRxTx_ISR(hspi); + } + } +} + +#if (USE_SPI_CRC != 0U) +/** + * @brief Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi) +{ + __IO uint32_t tmpreg = 0U; + + /* Read 16bit CRC to flush Data Register */ + tmpreg = READ_REG(hspi->Instance->DR); + /* To avoid GCC warning */ + UNUSED(tmpreg); + + /* Disable RXNE interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE); + + SPI_CloseRxTx_ISR(hspi); +} +#endif /* USE_SPI_CRC */ + +/** + * @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi) +{ + /* Transmit data in 16 Bit mode */ + hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + + /* Enable CRC Transmission */ + if (hspi->TxXferCount == 0U) + { +#if (USE_SPI_CRC != 0U) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Set CRC Next Bit to send CRC */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + /* Disable TXE interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); + return; + } +#endif /* USE_SPI_CRC */ + + /* Disable TXE interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); + + if (hspi->RxXferCount == 0U) + { + SPI_CloseRxTx_ISR(hspi); + } + } +} + +#if (USE_SPI_CRC != 0U) +/** + * @brief Manage the CRC 8-bit receive in Interrupt context. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi) +{ + __IO uint8_t *ptmpreg8; + __IO uint8_t tmpreg8 = 0; + + /* Initialize the 8bit temporary pointer */ + ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; + /* Read 8bit CRC to flush Data Register */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + + hspi->CRCSize--; + + if (hspi->CRCSize == 0U) + { + SPI_CloseRx_ISR(hspi); + } +} +#endif /* USE_SPI_CRC */ + +/** + * @brief Manage the receive 8-bit in Interrupt context. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi) +{ + *hspi->pRxBuffPtr = (*(__IO uint8_t *)&hspi->Instance->DR); + hspi->pRxBuffPtr++; + hspi->RxXferCount--; + +#if (USE_SPI_CRC != 0U) + /* Enable CRC Transmission */ + if ((hspi->RxXferCount == 1U) && + (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + + if (hspi->RxXferCount == 0U) + { +#if (USE_SPI_CRC != 0U) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->RxISR = SPI_RxISR_8BITCRC; + return; + } +#endif /* USE_SPI_CRC */ + SPI_CloseRx_ISR(hspi); + } +} + +#if (USE_SPI_CRC != 0U) +/** + * @brief Manage the CRC 16-bit receive in Interrupt context. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi) +{ + __IO uint32_t tmpreg = 0U; + + /* Read 16bit CRC to flush Data Register */ + tmpreg = READ_REG(hspi->Instance->DR); + /* To avoid GCC warning */ + UNUSED(tmpreg); + + /* Disable RXNE and ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); + + SPI_CloseRx_ISR(hspi); +} +#endif /* USE_SPI_CRC */ + +/** + * @brief Manage the 16-bit receive in Interrupt context. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi) +{ + *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR); + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount--; + +#if (USE_SPI_CRC != 0U) + /* Enable CRC Transmission */ + if ((hspi->RxXferCount == 1U) && + (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + + if (hspi->RxXferCount == 0U) + { +#if (USE_SPI_CRC != 0U) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->RxISR = SPI_RxISR_16BITCRC; + return; + } +#endif /* USE_SPI_CRC */ + SPI_CloseRx_ISR(hspi); + } +} + +/** + * @brief Handle the data 8-bit transmit in Interrupt mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi) +{ + *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr); + hspi->pTxBuffPtr++; + hspi->TxXferCount--; + + if (hspi->TxXferCount == 0U) + { +#if (USE_SPI_CRC != 0U) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Enable CRC Transmission */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + SPI_CloseTx_ISR(hspi); + } +} + +/** + * @brief Handle the data 16-bit transmit in Interrupt mode. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi) +{ + /* Transmit data in 16 Bit mode */ + hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; + + if (hspi->TxXferCount == 0U) + { +#if (USE_SPI_CRC != 0U) + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Enable CRC Transmission */ + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + } +#endif /* USE_SPI_CRC */ + SPI_CloseTx_ISR(hspi); + } +} + +/** + * @brief Handle SPI Communication Timeout. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param Flag SPI flag to check + * @param State flag state to check + * @param Timeout Timeout duration + * @param Tickstart tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, + uint32_t Flag, FlagStatus State, + uint32_t Timeout, + uint32_t Tickstart) +{ + __IO uint32_t count; + uint32_t tmp_timeout; + uint32_t tmp_tickstart; + + /* Adjust Timeout value in case of end of transfer */ + tmp_timeout = Timeout - (HAL_GetTick() - Tickstart); + tmp_tickstart = HAL_GetTick(); + + /* Calculate Timeout based on a software loop to avoid blocking issue if Systick is + * disabled */ + count = tmp_timeout * ((SystemCoreClock * 32U) >> 20U); + + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tmp_tickstart) >= tmp_timeout) || (tmp_timeout == 0U)) + { + /* Disable the SPI and reset the CRC: the CRC value should be cleared + on both master and slave sides in order to resynchronize the master + and slave for their respective CRC calculation */ + + /* Disable TXE, RXNE and ERR interrupts for the interrupt process */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); + + if ((hspi->Init.Mode == SPI_MODE_MASTER) && + ((hspi->Init.Direction == SPI_DIRECTION_1LINE) || + (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + } + + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + hspi->State = HAL_SPI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_TIMEOUT; + } + /* If Systick is disabled or not incremented, deactivate timeout to go in + * disable loop procedure */ + if (count == 0U) + { + tmp_timeout = 0U; + } + count--; + } + } + + return HAL_OK; +} + +/** + * @brief Handle SPI FIFO Communication Timeout. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param Fifo Fifo to check + * @param State Fifo state to check + * @param Timeout Timeout duration + * @param Tickstart tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_WaitFifoStateUntilTimeout(SPI_HandleTypeDef *hspi, + uint32_t Fifo, uint32_t State, + uint32_t Timeout, + uint32_t Tickstart) +{ + __IO uint32_t count; + uint32_t tmp_timeout; + uint32_t tmp_tickstart; + __IO uint8_t *ptmpreg8; + __IO uint8_t tmpreg8 = 0; + + /* Adjust Timeout value in case of end of transfer */ + tmp_timeout = Timeout - (HAL_GetTick() - Tickstart); + tmp_tickstart = HAL_GetTick(); + + /* Initialize the 8bit temporary pointer */ + ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; + + /* Calculate Timeout based on a software loop to avoid blocking issue if Systick is + * disabled */ + count = tmp_timeout * ((SystemCoreClock * 35U) >> 20U); + + while ((hspi->Instance->SR & Fifo) != State) + { + if ((Fifo == SPI_SR_FRLVL) && (State == SPI_FRLVL_EMPTY)) + { + /* Flush Data Register by a blank read */ + tmpreg8 = *ptmpreg8; + /* To avoid GCC warning */ + UNUSED(tmpreg8); + } + + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tmp_tickstart) >= tmp_timeout) || (tmp_timeout == 0U)) + { + /* Disable the SPI and reset the CRC: the CRC value should be cleared + on both master and slave sides in order to resynchronize the master + and slave for their respective CRC calculation */ + + /* Disable TXE, RXNE and ERR interrupts for the interrupt process */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); + + if ((hspi->Init.Mode == SPI_MODE_MASTER) && + ((hspi->Init.Direction == SPI_DIRECTION_1LINE) || + (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + } + + /* Reset CRC Calculation */ + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + hspi->State = HAL_SPI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_TIMEOUT; + } + /* If Systick is disabled or not incremented, deactivate timeout to go in + * disable loop procedure */ + if (count == 0U) + { + tmp_timeout = 0U; + } + count--; + } + } + + return HAL_OK; +} + +/** + * @brief Handle the check of the RX transaction complete. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param Timeout Timeout duration + * @param Tickstart tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, + uint32_t Tickstart) +{ + if ((hspi->Init.Mode == SPI_MODE_MASTER) && + ((hspi->Init.Direction == SPI_DIRECTION_1LINE) || + (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + } + + /* Control the BSY flag */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != + HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + return HAL_TIMEOUT; + } + + if ((hspi->Init.Mode == SPI_MODE_MASTER) && + ((hspi->Init.Direction == SPI_DIRECTION_1LINE) || + (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + { + /* Empty the FRLVL fifo */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, Timeout, + Tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief Handle the check of the RXTX or TX transaction complete. + * @param hspi SPI handle + * @param Timeout Timeout duration + * @param Tickstart tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, + uint32_t Tickstart) +{ + /* Control if the TX fifo is empty */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FTLVL, SPI_FTLVL_EMPTY, Timeout, + Tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + return HAL_TIMEOUT; + } + + /* Control the BSY flag */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != + HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + return HAL_TIMEOUT; + } + + /* Control if the RX fifo is empty */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, Timeout, + Tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + return HAL_TIMEOUT; + } + + return HAL_OK; +} + +/** + * @brief Handle the end of the RXTX transaction. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi) +{ + uint32_t tickstart; + + /* Init tickstart for timeout management */ + tickstart = HAL_GetTick(); + + /* Disable ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); + + /* Check the end of the transaction */ + if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + } + +#if (USE_SPI_CRC != 0U) + /* Check if CRC error occurred */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) + { + hspi->State = HAL_SPI_STATE_READY; + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + else + { +#endif /* USE_SPI_CRC */ + if (hspi->ErrorCode == HAL_SPI_ERROR_NONE) + { + if (hspi->State == HAL_SPI_STATE_BUSY_RX) + { + hspi->State = HAL_SPI_STATE_READY; + /* Call user Rx complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->RxCpltCallback(hspi); +#else + HAL_SPI_RxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + else + { + hspi->State = HAL_SPI_STATE_READY; + /* Call user TxRx complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxRxCpltCallback(hspi); +#else + HAL_SPI_TxRxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + } + else + { + hspi->State = HAL_SPI_STATE_READY; + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } +#if (USE_SPI_CRC != 0U) + } +#endif /* USE_SPI_CRC */ +} + +/** + * @brief Handle the end of the RX transaction. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi) +{ + /* Disable RXNE and ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); + + /* Check the end of the transaction */ + if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + } + hspi->State = HAL_SPI_STATE_READY; + +#if (USE_SPI_CRC != 0U) + /* Check if CRC error occurred */ + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + else + { +#endif /* USE_SPI_CRC */ + if (hspi->ErrorCode == HAL_SPI_ERROR_NONE) + { + /* Call user Rx complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->RxCpltCallback(hspi); +#else + HAL_SPI_RxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + else + { + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } +#if (USE_SPI_CRC != 0U) + } +#endif /* USE_SPI_CRC */ +} + +/** + * @brief Handle the end of the TX transaction. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi) +{ + uint32_t tickstart; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Disable TXE and ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR)); + + /* Check the end of the transaction */ + if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + } + + /* Clear overrun flag in 2 Lines communication mode because received is not read */ + if (hspi->Init.Direction == SPI_DIRECTION_2LINES) + { + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + + hspi->State = HAL_SPI_STATE_READY; + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + /* Call user error callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->ErrorCallback(hspi); +#else + HAL_SPI_ErrorCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } + else + { + /* Call user Rx complete callback */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxCpltCallback(hspi); +#else + HAL_SPI_TxCpltCallback(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Handle abort a Rx transaction. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi) +{ + __IO uint32_t count; + + /* Disable SPI Peripheral */ + __HAL_SPI_DISABLE(hspi); + + count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); + + /* Disable RXNEIE interrupt */ + CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXNEIE)); + + /* Check RXNEIE is disabled */ + do + { + if (count == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + count--; + } while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)); + + /* Control the BSY flag */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, SPI_DEFAULT_TIMEOUT, + HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Empty the FRLVL fifo */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, + SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + hspi->State = HAL_SPI_STATE_ABORT; +} + +/** + * @brief Handle abort a Tx or Rx/Tx transaction. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi) +{ + __IO uint32_t count; + + count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); + + /* Disable TXEIE interrupt */ + CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE)); + + /* Check TXEIE is disabled */ + do + { + if (count == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + count--; + } while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)); + + if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Disable SPI Peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Empty the FRLVL fifo */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, + SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Check case of Full-Duplex Mode and disable directly RXNEIE interrupt */ + if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) + { + /* Disable RXNEIE interrupt */ + CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXNEIE)); + + /* Check RXNEIE is disabled */ + do + { + if (count == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } + count--; + } while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)); + + /* Control the BSY flag */ + if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, SPI_DEFAULT_TIMEOUT, + HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + + /* Empty the FRLVL fifo */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, + SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) + { + hspi->ErrorCode = HAL_SPI_ERROR_ABORT; + } + } + hspi->State = HAL_SPI_STATE_ABORT; +} + +/** + * @} + */ + +#endif /* HAL_SPI_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi.h new file mode 100644 index 0000000000..3777ea0045 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi.h @@ -0,0 +1,902 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_spi.h + * @author MCD Application Team + * @brief Header file of SPI HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_SPI_H +#define STM32F0xx_HAL_SPI_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/stm32f0xx/stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup SPI + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /** @defgroup SPI_Exported_Types SPI Exported Types + * @{ + */ + + /** + * @brief SPI Configuration Structure definition + */ + typedef struct + { + uint32_t Mode; /*!< Specifies the SPI operating mode. + This parameter can be a value of @ref SPI_Mode */ + + uint32_t Direction; /*!< Specifies the SPI bidirectional mode state. + This parameter can be a value of @ref SPI_Direction */ + + uint32_t DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of @ref SPI_Data_Size */ + + uint32_t + CLKPolarity; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint32_t CLKPhase; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint32_t + NSS; /*!< Specifies whether the NSS signal is managed by + hardware (NSS pin) or by software using the SSI bit. + This parameter can be a value of @ref SPI_Slave_Select_management */ + + uint32_t BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which + will be used to configure the transmit and receive + SCK clock. This parameter can be a value of @ref + SPI_BaudRate_Prescaler + @note The communication clock is derived from the + master clock. The slave clock does not need to be + set. */ + + uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB + bit. This parameter can be a value of @ref + SPI_MSB_LSB_transmission */ + + uint32_t TIMode; /*!< Specifies if the TI mode is enabled or not. + This parameter can be a value of @ref SPI_TI_mode */ + + uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not. + This parameter can be a value of @ref + SPI_CRC_Calculation */ + + uint32_t CRCPolynomial; /*!< Specifies the polynomial used for the CRC + calculation. This parameter must be an odd number + between Min_Data = 1 and Max_Data = 65535 */ + + uint32_t + CRCLength; /*!< Specifies the CRC Length used for the CRC calculation. + CRC Length is only used with Data8 and Data16, not other data + size This parameter can be a value of @ref SPI_CRC_length */ + + uint32_t + NSSPMode; /*!< Specifies whether the NSSP signal is enabled or not . + This parameter can be a value of @ref SPI_NSSP_Mode + This mode is activated by the NSSP bit in the SPIx_CR2 register + and it takes effect only if the SPI interface is configured as + Motorola SPI master (FRF=0) with capture on the first edge + (SPIx_CR1 CPHA = 0, CPOL setting is ignored).. */ + } SPI_InitTypeDef; + + /** + * @brief HAL SPI State structure definition + */ + typedef enum + { + HAL_SPI_STATE_RESET = 0x00U, /*!< Peripheral not Initialized */ + HAL_SPI_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_SPI_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */ + HAL_SPI_STATE_BUSY_TX = 0x03U, /*!< Data Transmission process is ongoing */ + HAL_SPI_STATE_BUSY_RX = 0x04U, /*!< Data Reception process is ongoing */ + HAL_SPI_STATE_BUSY_TX_RX = + 0x05U, /*!< Data Transmission and Reception process is ongoing */ + HAL_SPI_STATE_ERROR = 0x06U, /*!< SPI error state */ + HAL_SPI_STATE_ABORT = 0x07U /*!< SPI abort is ongoing */ + } HAL_SPI_StateTypeDef; + + /** + * @brief SPI handle Structure definition + */ + typedef struct __SPI_HandleTypeDef + { + SPI_TypeDef *Instance; /*!< SPI registers base address */ + + SPI_InitTypeDef Init; /*!< SPI communication parameters */ + + uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< SPI Tx Transfer size */ + + __IO uint16_t TxXferCount; /*!< SPI Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to SPI Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< SPI Rx Transfer size */ + + __IO uint16_t RxXferCount; /*!< SPI Rx Transfer Counter */ + + uint32_t CRCSize; /*!< SPI CRC size used for the transfer */ + + void (*RxISR)( + struct __SPI_HandleTypeDef *hspi); /*!< function pointer on Rx ISR */ + + void (*TxISR)( + struct __SPI_HandleTypeDef *hspi); /*!< function pointer on Tx ISR */ + + DMA_HandleTypeDef *hdmatx; /*!< SPI Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< SPI Rx DMA Handle parameters */ + + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_SPI_StateTypeDef State; /*!< SPI communication state */ + + __IO uint32_t ErrorCode; /*!< SPI Error code */ + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + void (*TxCpltCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx Completed callback */ + void (*RxCpltCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx Completed callback */ + void (*TxRxCpltCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Completed callback */ + void (*TxHalfCpltCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx Half Completed callback */ + void (*RxHalfCpltCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx Half Completed callback */ + void (*TxRxHalfCpltCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Half Completed callback */ + void (*ErrorCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI Error callback */ + void (*AbortCpltCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI Abort callback */ + void (*MspInitCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp Init callback */ + void (*MspDeInitCallback)( + struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp DeInit callback */ + +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + } SPI_HandleTypeDef; + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + /** + * @brief HAL SPI Callback ID enumeration definition + */ + typedef enum + { + HAL_SPI_TX_COMPLETE_CB_ID = 0x00U, /*!< SPI Tx Completed callback ID */ + HAL_SPI_RX_COMPLETE_CB_ID = 0x01U, /*!< SPI Rx Completed callback ID */ + HAL_SPI_TX_RX_COMPLETE_CB_ID = 0x02U, /*!< SPI TxRx Completed callback ID */ + HAL_SPI_TX_HALF_COMPLETE_CB_ID = 0x03U, /*!< SPI Tx Half Completed callback ID */ + HAL_SPI_RX_HALF_COMPLETE_CB_ID = 0x04U, /*!< SPI Rx Half Completed callback ID */ + HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID = + 0x05U, /*!< SPI TxRx Half Completed callback ID */ + HAL_SPI_ERROR_CB_ID = 0x06U, /*!< SPI Error callback ID */ + HAL_SPI_ABORT_CB_ID = 0x07U, /*!< SPI Abort callback ID */ + HAL_SPI_MSPINIT_CB_ID = 0x08U, /*!< SPI Msp Init callback ID */ + HAL_SPI_MSPDEINIT_CB_ID = 0x09U /*!< SPI Msp DeInit callback ID */ + + } HAL_SPI_CallbackIDTypeDef; + + /** + * @brief HAL SPI Callback pointer definition + */ + typedef void (*pSPI_CallbackTypeDef)( + SPI_HandleTypeDef *hspi); /*!< pointer to an SPI callback function */ + +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPI_Exported_Constants SPI Exported Constants + * @{ + */ + +/** @defgroup SPI_Error_Code SPI Error Code + * @{ + */ +#define HAL_SPI_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_SPI_ERROR_MODF (0x00000001U) /*!< MODF error */ +#define HAL_SPI_ERROR_CRC (0x00000002U) /*!< CRC error */ +#define HAL_SPI_ERROR_OVR (0x00000004U) /*!< OVR error */ +#define HAL_SPI_ERROR_FRE (0x00000008U) /*!< FRE error */ +#define HAL_SPI_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ +#define HAL_SPI_ERROR_FLAG (0x00000020U) /*!< Error on RXNE/TXE/BSY/FTLVL/FRLVL Flag */ +#define HAL_SPI_ERROR_ABORT (0x00000040U) /*!< Error during SPI Abort procedure */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) +#define HAL_SPI_ERROR_INVALID_CALLBACK \ + (0x00000080U) /*!< Invalid Callback error */ +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @defgroup SPI_Mode SPI Mode + * @{ + */ +#define SPI_MODE_SLAVE (0x00000000U) +#define SPI_MODE_MASTER (SPI_CR1_MSTR | SPI_CR1_SSI) +/** + * @} + */ + +/** @defgroup SPI_Direction SPI Direction Mode + * @{ + */ +#define SPI_DIRECTION_2LINES (0x00000000U) +#define SPI_DIRECTION_2LINES_RXONLY SPI_CR1_RXONLY +#define SPI_DIRECTION_1LINE SPI_CR1_BIDIMODE +/** + * @} + */ + +/** @defgroup SPI_Data_Size SPI Data Size + * @{ + */ +#define SPI_DATASIZE_4BIT (0x00000300U) +#define SPI_DATASIZE_5BIT (0x00000400U) +#define SPI_DATASIZE_6BIT (0x00000500U) +#define SPI_DATASIZE_7BIT (0x00000600U) +#define SPI_DATASIZE_8BIT (0x00000700U) +#define SPI_DATASIZE_9BIT (0x00000800U) +#define SPI_DATASIZE_10BIT (0x00000900U) +#define SPI_DATASIZE_11BIT (0x00000A00U) +#define SPI_DATASIZE_12BIT (0x00000B00U) +#define SPI_DATASIZE_13BIT (0x00000C00U) +#define SPI_DATASIZE_14BIT (0x00000D00U) +#define SPI_DATASIZE_15BIT (0x00000E00U) +#define SPI_DATASIZE_16BIT (0x00000F00U) +/** + * @} + */ + +/** @defgroup SPI_Clock_Polarity SPI Clock Polarity + * @{ + */ +#define SPI_POLARITY_LOW (0x00000000U) +#define SPI_POLARITY_HIGH SPI_CR1_CPOL +/** + * @} + */ + +/** @defgroup SPI_Clock_Phase SPI Clock Phase + * @{ + */ +#define SPI_PHASE_1EDGE (0x00000000U) +#define SPI_PHASE_2EDGE SPI_CR1_CPHA +/** + * @} + */ + +/** @defgroup SPI_Slave_Select_management SPI Slave Select Management + * @{ + */ +#define SPI_NSS_SOFT SPI_CR1_SSM +#define SPI_NSS_HARD_INPUT (0x00000000U) +#define SPI_NSS_HARD_OUTPUT (SPI_CR2_SSOE << 16U) +/** + * @} + */ + +/** @defgroup SPI_NSSP_Mode SPI NSS Pulse Mode + * @{ + */ +#define SPI_NSS_PULSE_ENABLE SPI_CR2_NSSP +#define SPI_NSS_PULSE_DISABLE (0x00000000U) +/** + * @} + */ + +/** @defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler + * @{ + */ +#define SPI_BAUDRATEPRESCALER_2 (0x00000000U) +#define SPI_BAUDRATEPRESCALER_4 (SPI_CR1_BR_0) +#define SPI_BAUDRATEPRESCALER_8 (SPI_CR1_BR_1) +#define SPI_BAUDRATEPRESCALER_16 (SPI_CR1_BR_1 | SPI_CR1_BR_0) +#define SPI_BAUDRATEPRESCALER_32 (SPI_CR1_BR_2) +#define SPI_BAUDRATEPRESCALER_64 (SPI_CR1_BR_2 | SPI_CR1_BR_0) +#define SPI_BAUDRATEPRESCALER_128 (SPI_CR1_BR_2 | SPI_CR1_BR_1) +#define SPI_BAUDRATEPRESCALER_256 (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0) +/** + * @} + */ + +/** @defgroup SPI_MSB_LSB_transmission SPI MSB LSB Transmission + * @{ + */ +#define SPI_FIRSTBIT_MSB (0x00000000U) +#define SPI_FIRSTBIT_LSB SPI_CR1_LSBFIRST +/** + * @} + */ + +/** @defgroup SPI_TI_mode SPI TI Mode + * @{ + */ +#define SPI_TIMODE_DISABLE (0x00000000U) +#define SPI_TIMODE_ENABLE SPI_CR2_FRF +/** + * @} + */ + +/** @defgroup SPI_CRC_Calculation SPI CRC Calculation + * @{ + */ +#define SPI_CRCCALCULATION_DISABLE (0x00000000U) +#define SPI_CRCCALCULATION_ENABLE SPI_CR1_CRCEN +/** + * @} + */ + +/** @defgroup SPI_CRC_length SPI CRC Length + * @{ + * This parameter can be one of the following values: + * SPI_CRC_LENGTH_DATASIZE: aligned with the data size + * SPI_CRC_LENGTH_8BIT : CRC 8bit + * SPI_CRC_LENGTH_16BIT : CRC 16bit + */ +#define SPI_CRC_LENGTH_DATASIZE (0x00000000U) +#define SPI_CRC_LENGTH_8BIT (0x00000001U) +#define SPI_CRC_LENGTH_16BIT (0x00000002U) +/** + * @} + */ + +/** @defgroup SPI_FIFO_reception_threshold SPI FIFO Reception Threshold + * @{ + * This parameter can be one of the following values: + * SPI_RXFIFO_THRESHOLD or SPI_RXFIFO_THRESHOLD_QF : + * RXNE event is generated if the FIFO + * level is greater or equal to 1/4(8-bits). + * SPI_RXFIFO_THRESHOLD_HF: RXNE event is generated if the FIFO + * level is greater or equal to 1/2(16 bits). */ +#define SPI_RXFIFO_THRESHOLD SPI_CR2_FRXTH +#define SPI_RXFIFO_THRESHOLD_QF SPI_CR2_FRXTH +#define SPI_RXFIFO_THRESHOLD_HF (0x00000000U) +/** + * @} + */ + +/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition + * @{ + */ +#define SPI_IT_TXE SPI_CR2_TXEIE +#define SPI_IT_RXNE SPI_CR2_RXNEIE +#define SPI_IT_ERR SPI_CR2_ERRIE +/** + * @} + */ + +/** @defgroup SPI_Flags_definition SPI Flags Definition + * @{ + */ +#define SPI_FLAG_RXNE SPI_SR_RXNE /* SPI status flag: Rx buffer not empty flag */ +#define SPI_FLAG_TXE SPI_SR_TXE /* SPI status flag: Tx buffer empty flag */ +#define SPI_FLAG_BSY SPI_SR_BSY /* SPI status flag: Busy flag */ +#define SPI_FLAG_CRCERR \ + SPI_SR_CRCERR /* SPI Error flag: CRC error flag */ +#define SPI_FLAG_MODF SPI_SR_MODF /* SPI Error flag: Mode fault flag */ +#define SPI_FLAG_OVR SPI_SR_OVR /* SPI Error flag: Overrun flag */ +#define SPI_FLAG_FRE SPI_SR_FRE /* SPI Error flag: TI mode frame format error flag */ +#define SPI_FLAG_FTLVL SPI_SR_FTLVL /* SPI fifo transmission level */ +#define SPI_FLAG_FRLVL SPI_SR_FRLVL /* SPI fifo reception level */ +#define SPI_FLAG_MASK \ + (SPI_SR_RXNE | SPI_SR_TXE | SPI_SR_BSY | SPI_SR_CRCERR | SPI_SR_MODF | SPI_SR_OVR | \ + SPI_SR_FRE | SPI_SR_FTLVL | SPI_SR_FRLVL) +/** + * @} + */ + +/** @defgroup SPI_transmission_fifo_status_level SPI Transmission FIFO Status Level + * @{ + */ +#define SPI_FTLVL_EMPTY (0x00000000U) +#define SPI_FTLVL_QUARTER_FULL (0x00000800U) +#define SPI_FTLVL_HALF_FULL (0x00001000U) +#define SPI_FTLVL_FULL (0x00001800U) + +/** + * @} + */ + +/** @defgroup SPI_reception_fifo_status_level SPI Reception FIFO Status Level + * @{ + */ +#define SPI_FRLVL_EMPTY (0x00000000U) +#define SPI_FRLVL_QUARTER_FULL (0x00000200U) +#define SPI_FRLVL_HALF_FULL (0x00000400U) +#define SPI_FRLVL_FULL (0x00000600U) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup SPI_Exported_Macros SPI Exported Macros + * @{ + */ + +/** @brief Reset SPI handle state. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) +#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) \ + do \ + { \ + (__HANDLE__)->State = HAL_SPI_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while (0) +#else +#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) \ + ((__HANDLE__)->State = HAL_SPI_STATE_RESET) +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + +/** @brief Enable the specified SPI interrupts. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @param __INTERRUPT__ specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg SPI_IT_TXE: Tx buffer empty interrupt enable + * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable + * @arg SPI_IT_ERR: Error interrupt enable + * @retval None + */ +#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + SET_BIT((__HANDLE__)->Instance->CR2, (__INTERRUPT__)) + +/** @brief Disable the specified SPI interrupts. + * @param __HANDLE__ specifies the SPI handle. + * This parameter can be SPIx where x: 1, 2, or 3 to select the SPI peripheral. + * @param __INTERRUPT__ specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg SPI_IT_TXE: Tx buffer empty interrupt enable + * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable + * @arg SPI_IT_ERR: Error interrupt enable + * @retval None + */ +#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + CLEAR_BIT((__HANDLE__)->Instance->CR2, (__INTERRUPT__)) + +/** @brief Check whether the specified SPI interrupt source is enabled or not. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @param __INTERRUPT__ specifies the SPI interrupt source to check. + * This parameter can be one of the following values: + * @arg SPI_IT_TXE: Tx buffer empty interrupt enable + * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable + * @arg SPI_IT_ERR: Error interrupt enable + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified SPI flag is set or not. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg SPI_FLAG_RXNE: Receive buffer not empty flag + * @arg SPI_FLAG_TXE: Transmit buffer empty flag + * @arg SPI_FLAG_CRCERR: CRC error flag + * @arg SPI_FLAG_MODF: Mode fault flag + * @arg SPI_FLAG_OVR: Overrun flag + * @arg SPI_FLAG_BSY: Busy flag + * @arg SPI_FLAG_FRE: Frame format error flag + * @arg SPI_FLAG_FTLVL: SPI fifo transmission level + * @arg SPI_FLAG_FRLVL: SPI fifo reception level + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) \ + ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the SPI CRCERR pending flag. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__) \ + ((__HANDLE__)->Instance->SR = (uint16_t)(~SPI_FLAG_CRCERR)) + +/** @brief Clear the SPI MODF pending flag. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__) \ + do \ + { \ + __IO uint32_t tmpreg_modf = 0x00U; \ + tmpreg_modf = (__HANDLE__)->Instance->SR; \ + CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_SPE); \ + UNUSED(tmpreg_modf); \ + } while (0U) + +/** @brief Clear the SPI OVR pending flag. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) \ + do \ + { \ + __IO uint32_t tmpreg_ovr = 0x00U; \ + tmpreg_ovr = (__HANDLE__)->Instance->DR; \ + tmpreg_ovr = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg_ovr); \ + } while (0U) + +/** @brief Clear the SPI FRE pending flag. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_CLEAR_FREFLAG(__HANDLE__) \ + do \ + { \ + __IO uint32_t tmpreg_fre = 0x00U; \ + tmpreg_fre = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg_fre); \ + } while (0U) + +/** @brief Enable the SPI peripheral. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_SPE) + +/** @brief Disable the SPI peripheral. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_SPE) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SPI_Private_Macros SPI Private Macros + * @{ + */ + +/** @brief Set the SPI transmit-only mode. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define SPI_1LINE_TX(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_BIDIOE) + +/** @brief Set the SPI receive-only mode. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define SPI_1LINE_RX(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_BIDIOE) + +/** @brief Reset the CRC calculation of the SPI. + * @param __HANDLE__ specifies the SPI Handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define SPI_RESET_CRC(__HANDLE__) \ + do \ + { \ + CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_CRCEN); \ + SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_CRCEN); \ + } while (0U) + +/** @brief Check whether the specified SPI flag is set or not. + * @param __SR__ copy of SPI SR register. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg SPI_FLAG_RXNE: Receive buffer not empty flag + * @arg SPI_FLAG_TXE: Transmit buffer empty flag + * @arg SPI_FLAG_CRCERR: CRC error flag + * @arg SPI_FLAG_MODF: Mode fault flag + * @arg SPI_FLAG_OVR: Overrun flag + * @arg SPI_FLAG_BSY: Busy flag + * @arg SPI_FLAG_FRE: Frame format error flag + * @arg SPI_FLAG_FTLVL: SPI fifo transmission level + * @arg SPI_FLAG_FRLVL: SPI fifo reception level + * @retval SET or RESET. + */ +#define SPI_CHECK_FLAG(__SR__, __FLAG__) \ + ((((__SR__) & ((__FLAG__)&SPI_FLAG_MASK)) == ((__FLAG__)&SPI_FLAG_MASK)) ? SET \ + : RESET) + +/** @brief Check whether the specified SPI Interrupt is set or not. + * @param __CR2__ copy of SPI CR2 register. + * @param __INTERRUPT__ specifies the SPI interrupt source to check. + * This parameter can be one of the following values: + * @arg SPI_IT_TXE: Tx buffer empty interrupt enable + * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable + * @arg SPI_IT_ERR: Error interrupt enable + * @retval SET or RESET. + */ +#define SPI_CHECK_IT_SOURCE(__CR2__, __INTERRUPT__) \ + ((((__CR2__) & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks if SPI Mode parameter is in allowed range. + * @param __MODE__ specifies the SPI Mode. + * This parameter can be a value of @ref SPI_Mode + * @retval None + */ +#define IS_SPI_MODE(__MODE__) \ + (((__MODE__) == SPI_MODE_SLAVE) || ((__MODE__) == SPI_MODE_MASTER)) + +/** @brief Checks if SPI Direction Mode parameter is in allowed range. + * @param __MODE__ specifies the SPI Direction Mode. + * This parameter can be a value of @ref SPI_Direction + * @retval None + */ +#define IS_SPI_DIRECTION(__MODE__) \ + (((__MODE__) == SPI_DIRECTION_2LINES) || \ + ((__MODE__) == SPI_DIRECTION_2LINES_RXONLY) || ((__MODE__) == SPI_DIRECTION_1LINE)) + +/** @brief Checks if SPI Direction Mode parameter is 2 lines. + * @param __MODE__ specifies the SPI Direction Mode. + * @retval None + */ +#define IS_SPI_DIRECTION_2LINES(__MODE__) ((__MODE__) == SPI_DIRECTION_2LINES) + +/** @brief Checks if SPI Direction Mode parameter is 1 or 2 lines. + * @param __MODE__ specifies the SPI Direction Mode. + * @retval None + */ +#define IS_SPI_DIRECTION_2LINES_OR_1LINE(__MODE__) \ + (((__MODE__) == SPI_DIRECTION_2LINES) || ((__MODE__) == SPI_DIRECTION_1LINE)) + +/** @brief Checks if SPI Data Size parameter is in allowed range. + * @param __DATASIZE__ specifies the SPI Data Size. + * This parameter can be a value of @ref SPI_Data_Size + * @retval None + */ +#define IS_SPI_DATASIZE(__DATASIZE__) \ + (((__DATASIZE__) == SPI_DATASIZE_16BIT) || ((__DATASIZE__) == SPI_DATASIZE_15BIT) || \ + ((__DATASIZE__) == SPI_DATASIZE_14BIT) || ((__DATASIZE__) == SPI_DATASIZE_13BIT) || \ + ((__DATASIZE__) == SPI_DATASIZE_12BIT) || ((__DATASIZE__) == SPI_DATASIZE_11BIT) || \ + ((__DATASIZE__) == SPI_DATASIZE_10BIT) || ((__DATASIZE__) == SPI_DATASIZE_9BIT) || \ + ((__DATASIZE__) == SPI_DATASIZE_8BIT) || ((__DATASIZE__) == SPI_DATASIZE_7BIT) || \ + ((__DATASIZE__) == SPI_DATASIZE_6BIT) || ((__DATASIZE__) == SPI_DATASIZE_5BIT) || \ + ((__DATASIZE__) == SPI_DATASIZE_4BIT)) + +/** @brief Checks if SPI Serial clock steady state parameter is in allowed range. + * @param __CPOL__ specifies the SPI serial clock steady state. + * This parameter can be a value of @ref SPI_Clock_Polarity + * @retval None + */ +#define IS_SPI_CPOL(__CPOL__) \ + (((__CPOL__) == SPI_POLARITY_LOW) || ((__CPOL__) == SPI_POLARITY_HIGH)) + +/** @brief Checks if SPI Clock Phase parameter is in allowed range. + * @param __CPHA__ specifies the SPI Clock Phase. + * This parameter can be a value of @ref SPI_Clock_Phase + * @retval None + */ +#define IS_SPI_CPHA(__CPHA__) \ + (((__CPHA__) == SPI_PHASE_1EDGE) || ((__CPHA__) == SPI_PHASE_2EDGE)) + +/** @brief Checks if SPI Slave Select parameter is in allowed range. + * @param __NSS__ specifies the SPI Slave Select management parameter. + * This parameter can be a value of @ref SPI_Slave_Select_management + * @retval None + */ +#define IS_SPI_NSS(__NSS__) \ + (((__NSS__) == SPI_NSS_SOFT) || ((__NSS__) == SPI_NSS_HARD_INPUT) || \ + ((__NSS__) == SPI_NSS_HARD_OUTPUT)) + +/** @brief Checks if SPI NSS Pulse parameter is in allowed range. + * @param __NSSP__ specifies the SPI NSS Pulse Mode parameter. + * This parameter can be a value of @ref SPI_NSSP_Mode + * @retval None + */ +#define IS_SPI_NSSP(__NSSP__) \ + (((__NSSP__) == SPI_NSS_PULSE_ENABLE) || ((__NSSP__) == SPI_NSS_PULSE_DISABLE)) + +/** @brief Checks if SPI Baudrate prescaler parameter is in allowed range. + * @param __PRESCALER__ specifies the SPI Baudrate prescaler. + * This parameter can be a value of @ref SPI_BaudRate_Prescaler + * @retval None + */ +#define IS_SPI_BAUDRATE_PRESCALER(__PRESCALER__) \ + (((__PRESCALER__) == SPI_BAUDRATEPRESCALER_2) || \ + ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_4) || \ + ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_8) || \ + ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_16) || \ + ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_32) || \ + ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_64) || \ + ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_128) || \ + ((__PRESCALER__) == SPI_BAUDRATEPRESCALER_256)) + +/** @brief Checks if SPI MSB LSB transmission parameter is in allowed range. + * @param __BIT__ specifies the SPI MSB LSB transmission (whether data transfer starts + * from MSB or LSB bit). This parameter can be a value of @ref SPI_MSB_LSB_transmission + * @retval None + */ +#define IS_SPI_FIRST_BIT(__BIT__) \ + (((__BIT__) == SPI_FIRSTBIT_MSB) || ((__BIT__) == SPI_FIRSTBIT_LSB)) + +/** @brief Checks if SPI TI mode parameter is in allowed range. + * @param __MODE__ specifies the SPI TI mode. + * This parameter can be a value of @ref SPI_TI_mode + * @retval None + */ +#define IS_SPI_TIMODE(__MODE__) \ + (((__MODE__) == SPI_TIMODE_DISABLE) || ((__MODE__) == SPI_TIMODE_ENABLE)) + +/** @brief Checks if SPI CRC calculation enabled state is in allowed range. + * @param __CALCULATION__ specifies the SPI CRC calculation enable state. + * This parameter can be a value of @ref SPI_CRC_Calculation + * @retval None + */ +#define IS_SPI_CRC_CALCULATION(__CALCULATION__) \ + (((__CALCULATION__) == SPI_CRCCALCULATION_DISABLE) || \ + ((__CALCULATION__) == SPI_CRCCALCULATION_ENABLE)) + +/** @brief Checks if SPI CRC length is in allowed range. + * @param __LENGTH__ specifies the SPI CRC length. + * This parameter can be a value of @ref SPI_CRC_length + * @retval None + */ +#define IS_SPI_CRC_LENGTH(__LENGTH__) \ + (((__LENGTH__) == SPI_CRC_LENGTH_DATASIZE) || \ + ((__LENGTH__) == SPI_CRC_LENGTH_8BIT) || ((__LENGTH__) == SPI_CRC_LENGTH_16BIT)) + +/** @brief Checks if SPI polynomial value to be used for the CRC calculation, is in + * allowed range. + * @param __POLYNOMIAL__ specifies the SPI polynomial value to be used for the CRC + * calculation. This parameter must be a number between Min_Data = 0 and Max_Data = 65535 + * @retval None + */ +#define IS_SPI_CRC_POLYNOMIAL(__POLYNOMIAL__) \ + (((__POLYNOMIAL__) >= 0x1U) && ((__POLYNOMIAL__) <= 0xFFFFU) && \ + (((__POLYNOMIAL__)&0x1U) != 0U)) + +/** @brief Checks if DMA handle is valid. + * @param __HANDLE__ specifies a DMA Handle. + * @retval None + */ +#define IS_SPI_DMA_HANDLE(__HANDLE__) ((__HANDLE__) != NULL) + +/** + * @} + */ + +/* Include SPI HAL Extended module */ +#include "firmware/motor/stm32f0xx/stm32f0xx_hal_spi_ex.h" + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup SPI_Exported_Functions + * @{ + */ + + /** @addtogroup SPI_Exported_Functions_Group1 + * @{ + */ + /* Initialization/de-initialization functions ********************************/ + HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi); + HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi); + void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi); + void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, + HAL_SPI_CallbackIDTypeDef CallbackID, + pSPI_CallbackTypeDef pCallback); + HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, + HAL_SPI_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + /** + * @} + */ + + /** @addtogroup SPI_Exported_Functions_Group2 + * @{ + */ + /* I/O operation functions ***************************************************/ + HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size, uint32_t Timeout); + HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size, uint32_t Timeout); + HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, + uint8_t *pRxData, uint16_t Size, + uint32_t Timeout); + HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, + uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size); + HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, + uint16_t Size); + HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, + uint8_t *pTxData, uint8_t *pRxData, + uint16_t Size); + HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi); + HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi); + HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi); + /* Transfer Abort functions */ + HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi); + HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi); + + void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi); + void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi); + void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi); + void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi); + void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi); + void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi); + void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi); + void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi); + void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi); + /** + * @} + */ + + /** @addtogroup SPI_Exported_Functions_Group3 + * @{ + */ + /* Peripheral State and Error functions ***************************************/ + HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi); + uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi); + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_SPI_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi_ex.h new file mode 100644 index 0000000000..65960f0f83 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_spi_ex.h @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_spi_ex.h + * @author MCD Application Team + * @brief Header file of SPI HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_SPI_EX_H +#define STM32F0xx_HAL_SPI_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup SPIEx + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /* Exported constants --------------------------------------------------------*/ + /* Exported macros -----------------------------------------------------------*/ + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup SPIEx_Exported_Functions + * @{ + */ + + /* Initialization and de-initialization functions ****************************/ + /* IO operation functions *****************************************************/ + /** @addtogroup SPIEx_Exported_Functions_Group1 + * @{ + */ + HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi); + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_SPI_EX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_tim.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_tim.h new file mode 100644 index 0000000000..a336eed7b3 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_tim.h @@ -0,0 +1,2571 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_tim.h + * @author MCD Application Team + * @brief Header file of TIM HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_TIM_H +#define STM32F0xx_HAL_TIM_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup TIM + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /** @defgroup TIM_Exported_Types TIM Exported Types + * @{ + */ + + /** + * @brief TIM Time base Configuration Structure definition + */ + typedef struct + { + uint32_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM + clock. This parameter can be a number between Min_Data = + 0x0000 and Max_Data = 0xFFFF */ + + uint32_t + CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter can be a number between Min_Data = 0x0000 and + Max_Data = 0xFFFF. */ + + uint32_t + ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_ClockDivision */ + + uint32_t + RepetitionCounter; /*!< Specifies the repetition counter value. Each time the + RCR downcounter reaches zero, an update event is + generated and counting restarts from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned + mode GP timers: this parameter must be a number between + Min_Data = 0x00 and Max_Data = 0xFF. Advanced timers: + this parameter must be a number between Min_Data = + 0x0000 and Max_Data = 0xFFFF. */ + + uint32_t AutoReloadPreload; /*!< Specifies the auto-reload preload. + This parameter can be a value of @ref + TIM_AutoReloadPreload */ + } TIM_Base_InitTypeDef; + + /** + * @brief TIM Output Compare Configuration Structure definition + */ + typedef struct + { + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref + TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture + Compare Register. This parameter can be a number between + Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref + TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref + TIM_Output_Compare_N_Polarity + @note This parameter is valid only for timer instances + supporting break feature. */ + + uint32_t + OCFastMode; /*!< Specifies the Fast mode state. + This parameter can be a value of @ref TIM_Output_Fast_State + @note This parameter is valid only in PWM1 and PWM2 mode. */ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle + state. This parameter can be a value of @ref + TIM_Output_Compare_Idle_State + @note This parameter is valid only for timer instances + supporting break feature. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle + state. This parameter can be a value of @ref + TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for timer instances + supporting break feature. */ + } TIM_OC_InitTypeDef; + + /** + * @brief TIM One Pulse Mode Configuration Structure definition + */ + typedef struct + { + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref + TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture + Compare Register. This parameter can be a number between + Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref + TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref + TIM_Output_Compare_N_Polarity + @note This parameter is valid only for timer instances + supporting break feature. */ + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle + state. This parameter can be a value of @ref + TIM_Output_Compare_Idle_State + @note This parameter is valid only for timer instances + supporting break feature. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle + state. This parameter can be a value of @ref + TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for timer instances + supporting break feature. */ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref + TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref + TIM_Input_Capture_Selection */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and + Max_Data = 0xF */ + } TIM_OnePulse_InitTypeDef; + + /** + * @brief TIM Input Capture Configuration Structure definition + */ + typedef struct + { + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref + TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref + TIM_Input_Capture_Selection */ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref + TIM_Input_Capture_Prescaler */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and + Max_Data = 0xF */ + } TIM_IC_InitTypeDef; + + /** + * @brief TIM Encoder Configuration Structure definition + */ + typedef struct + { + uint32_t + EncoderMode; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Mode */ + + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref + TIM_Encoder_Input_Polarity */ + + uint32_t IC1Selection; /*!< Specifies the input. + This parameter can be a value of @ref + TIM_Input_Capture_Selection */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref + TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and + Max_Data = 0xF */ + + uint32_t IC2Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref + TIM_Encoder_Input_Polarity */ + + uint32_t IC2Selection; /*!< Specifies the input. + This parameter can be a value of @ref + TIM_Input_Capture_Selection */ + + uint32_t IC2Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref + TIM_Input_Capture_Prescaler */ + + uint32_t IC2Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and + Max_Data = 0xF */ + } TIM_Encoder_InitTypeDef; + + /** + * @brief Clock Configuration Handle Structure definition + */ + typedef struct + { + uint32_t + ClockSource; /*!< TIM clock sources + This parameter can be a value of @ref TIM_Clock_Source */ + uint32_t ClockPolarity; /*!< TIM clock polarity + This parameter can be a value of @ref + TIM_Clock_Polarity */ + uint32_t ClockPrescaler; /*!< TIM clock prescaler + This parameter can be a value of @ref + TIM_Clock_Prescaler */ + uint32_t ClockFilter; /*!< TIM clock filter + This parameter can be a number between Min_Data = 0x0 + and Max_Data = 0xF */ + } TIM_ClockConfigTypeDef; + + /** + * @brief TIM Clear Input Configuration Handle Structure definition + */ + typedef struct + { + uint32_t ClearInputState; /*!< TIM clear Input state + This parameter can be ENABLE or DISABLE */ + uint32_t ClearInputSource; /*!< TIM clear Input sources + This parameter can be a value of @ref + TIM_ClearInput_Source */ + uint32_t ClearInputPolarity; /*!< TIM Clear Input polarity + This parameter can be a value of @ref + TIM_ClearInput_Polarity */ + uint32_t ClearInputPrescaler; /*!< TIM Clear Input prescaler + This parameter must be 0: When OCRef clear + feature is used with ETR source, ETR prescaler + must be off */ + uint32_t ClearInputFilter; /*!< TIM Clear Input filter + This parameter can be a number between Min_Data = + 0x0 and Max_Data = 0xF */ + } TIM_ClearInputConfigTypeDef; + + /** + * @brief TIM Master configuration Structure definition + */ + typedef struct + { + uint32_t MasterOutputTrigger; /*!< Trigger output (TRGO) selection + This parameter can be a value of @ref + TIM_Master_Mode_Selection */ + uint32_t + MasterSlaveMode; /*!< Master/slave mode selection + This parameter can be a value of @ref + TIM_Master_Slave_Mode + @note When the Master/slave mode is enabled, the effect + of an event on the trigger input (TRGI) is delayed to + allow a perfect synchronization between the current timer + and its slaves (through TRGO). It is not mandatory in case + of timer synchronization mode. */ + } TIM_MasterConfigTypeDef; + + /** + * @brief TIM Slave configuration Structure definition + */ + typedef struct + { + uint32_t SlaveMode; /*!< Slave mode selection + This parameter can be a value of @ref TIM_Slave_Mode */ + uint32_t InputTrigger; /*!< Input Trigger source + This parameter can be a value of @ref + TIM_Trigger_Selection */ + uint32_t TriggerPolarity; /*!< Input Trigger polarity + This parameter can be a value of @ref + TIM_Trigger_Polarity */ + uint32_t TriggerPrescaler; /*!< Input trigger prescaler + This parameter can be a value of @ref + TIM_Trigger_Prescaler */ + uint32_t TriggerFilter; /*!< Input trigger filter + This parameter can be a number between Min_Data = 0x0 + and Max_Data = 0xF */ + + } TIM_SlaveConfigTypeDef; + + /** + * @brief TIM Break input(s) and Dead time configuration Structure definition + * @note 2 break inputs can be configured (BKIN and BKIN2) with configurable + * filter and polarity. + */ + typedef struct + { + uint32_t + OffStateRunMode; /*!< TIM off state in run mode, This parameter can be a value + of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ + + uint32_t OffStateIDLEMode; /*!< TIM off state in IDLE mode, This parameter can be + a value of @ref + TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ + + uint32_t LockLevel; /*!< TIM Lock level, This parameter can be a value of @ref + TIM_Lock_level */ + + uint32_t DeadTime; /*!< TIM dead Time, This parameter can be a number between + Min_Data = 0x00 and Max_Data = 0xFF */ + + uint32_t BreakState; /*!< TIM Break State, This parameter can be a value of @ref + TIM_Break_Input_enable_disable */ + + uint32_t BreakPolarity; /*!< TIM Break input polarity, This parameter can be a + value of @ref TIM_Break_Polarity */ + + uint32_t BreakFilter; /*!< Specifies the break input filter.This parameter can be + a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t AutomaticOutput; /*!< TIM Automatic Output Enable state, This parameter + can be a value of @ref TIM_AOE_Bit_Set_Reset */ + + } TIM_BreakDeadTimeConfigTypeDef; + + /** + * @brief HAL State structures definition + */ + typedef enum + { + HAL_TIM_STATE_RESET = 0x00U, /*!< Peripheral not yet initialized or disabled */ + HAL_TIM_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_TIM_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ + HAL_TIM_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_TIM_STATE_ERROR = 0x04U /*!< Reception process is ongoing */ + } HAL_TIM_StateTypeDef; + + /** + * @brief TIM Channel States definition + */ + typedef enum + { + HAL_TIM_CHANNEL_STATE_RESET = 0x00U, /*!< TIM Channel initial state */ + HAL_TIM_CHANNEL_STATE_READY = 0x01U, /*!< TIM Channel ready for use */ + HAL_TIM_CHANNEL_STATE_BUSY = + 0x02U, /*!< An internal process is ongoing on the TIM channel */ + } HAL_TIM_ChannelStateTypeDef; + + /** + * @brief DMA Burst States definition + */ + typedef enum + { + HAL_DMA_BURST_STATE_RESET = 0x00U, /*!< DMA Burst initial state */ + HAL_DMA_BURST_STATE_READY = 0x01U, /*!< DMA Burst ready for use */ + HAL_DMA_BURST_STATE_BUSY = 0x02U, /*!< Ongoing DMA Burst */ + } HAL_TIM_DMABurstStateTypeDef; + + /** + * @brief HAL Active channel structures definition + */ + typedef enum + { + HAL_TIM_ACTIVE_CHANNEL_1 = 0x01U, /*!< The active channel is 1 */ + HAL_TIM_ACTIVE_CHANNEL_2 = 0x02U, /*!< The active channel is 2 */ + HAL_TIM_ACTIVE_CHANNEL_3 = 0x04U, /*!< The active channel is 3 */ + HAL_TIM_ACTIVE_CHANNEL_4 = 0x08U, /*!< The active channel is 4 */ + HAL_TIM_ACTIVE_CHANNEL_CLEARED = 0x00U /*!< All active channels cleared */ + } HAL_TIM_ActiveChannel; + +/** + * @brief TIM Time Base Handle Structure definition + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + typedef struct __TIM_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + { + TIM_TypeDef *Instance; /*!< Register base address */ + TIM_Base_InitTypeDef Init; /*!< TIM Time Base required parameters */ + HAL_TIM_ActiveChannel Channel; /*!< Active channel */ + DMA_HandleTypeDef + *hdma[7]; /*!< DMA Handlers array + This array is accessed by a @ref DMA_Handle_index */ + HAL_LockTypeDef Lock; /*!< Locking object */ + __IO HAL_TIM_StateTypeDef State; /*!< TIM operation state */ + __IO HAL_TIM_ChannelStateTypeDef + ChannelState[4]; /*!< TIM channel operation state */ + __IO HAL_TIM_ChannelStateTypeDef + ChannelNState[4]; /*!< TIM complementary channel operation state */ + __IO HAL_TIM_DMABurstStateTypeDef DMABurstState; /*!< DMA burst operation state */ + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + void (*Base_MspInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Base Msp Init Callback */ + void (*Base_MspDeInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Base Msp DeInit Callback */ + void (*IC_MspInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM IC Msp Init Callback */ + void (*IC_MspDeInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM IC Msp DeInit Callback */ + void (*OC_MspInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM OC Msp Init Callback */ + void (*OC_MspDeInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM OC Msp DeInit Callback */ + void (*PWM_MspInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Msp Init Callback */ + void (*PWM_MspDeInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Msp DeInit Callback */ + void (*OnePulse_MspInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM One Pulse Msp Init Callback */ + void (*OnePulse_MspDeInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM One Pulse Msp DeInit Callback */ + void (*Encoder_MspInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Msp Init Callback */ + void (*Encoder_MspDeInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Msp DeInit Callback */ + void (*HallSensor_MspInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Hall Sensor Msp Init Callback */ + void (*HallSensor_MspDeInitCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Hall Sensor Msp DeInit Callback */ + void (*PeriodElapsedCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Period Elapsed Callback */ + void (*PeriodElapsedHalfCpltCallback)( + struct __TIM_HandleTypeDef + *htim); /*!< TIM Period Elapsed half complete Callback */ + void (*TriggerCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Trigger Callback */ + void (*TriggerHalfCpltCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Trigger half complete Callback */ + void (*IC_CaptureCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Input Capture Callback */ + void (*IC_CaptureHalfCpltCallback)( + struct __TIM_HandleTypeDef + *htim); /*!< TIM Input Capture half complete Callback */ + void (*OC_DelayElapsedCallback)( + struct __TIM_HandleTypeDef + *htim); /*!< TIM Output Compare Delay Elapsed Callback */ + void (*PWM_PulseFinishedCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished Callback */ + void (*PWM_PulseFinishedHalfCpltCallback)( + struct __TIM_HandleTypeDef + *htim); /*!< TIM PWM Pulse Finished half complete Callback */ + void (*ErrorCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Error Callback */ + void (*CommutationCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Commutation Callback */ + void (*CommutationHalfCpltCallback)( + struct __TIM_HandleTypeDef + *htim); /*!< TIM Commutation half complete Callback */ + void (*BreakCallback)( + struct __TIM_HandleTypeDef *htim); /*!< TIM Break Callback */ +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } TIM_HandleTypeDef; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /** + * @brief HAL TIM Callback ID enumeration definition + */ + typedef enum + { + HAL_TIM_BASE_MSPINIT_CB_ID = 0x00U /*!< TIM Base MspInit Callback ID */ + , + HAL_TIM_BASE_MSPDEINIT_CB_ID = 0x01U /*!< TIM Base MspDeInit Callback ID */ + , + HAL_TIM_IC_MSPINIT_CB_ID = 0x02U /*!< TIM IC MspInit Callback ID */ + , + HAL_TIM_IC_MSPDEINIT_CB_ID = 0x03U /*!< TIM IC MspDeInit Callback ID */ + , + HAL_TIM_OC_MSPINIT_CB_ID = 0x04U /*!< TIM OC MspInit Callback ID */ + , + HAL_TIM_OC_MSPDEINIT_CB_ID = 0x05U /*!< TIM OC MspDeInit Callback ID */ + , + HAL_TIM_PWM_MSPINIT_CB_ID = 0x06U /*!< TIM PWM MspInit Callback ID */ + , + HAL_TIM_PWM_MSPDEINIT_CB_ID = 0x07U /*!< TIM PWM MspDeInit Callback ID */ + , + HAL_TIM_ONE_PULSE_MSPINIT_CB_ID = 0x08U /*!< TIM One Pulse MspInit Callback ID */ + , + HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID = + 0x09U /*!< TIM One Pulse MspDeInit Callback ID */ + , + HAL_TIM_ENCODER_MSPINIT_CB_ID = 0x0AU /*!< TIM Encoder MspInit Callback ID */ + , + HAL_TIM_ENCODER_MSPDEINIT_CB_ID = 0x0BU /*!< TIM Encoder MspDeInit Callback ID */ + , + HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID = + 0x0CU /*!< TIM Hall Sensor MspDeInit Callback ID */ + , + HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID = + 0x0DU /*!< TIM Hall Sensor MspDeInit Callback ID */ + , + HAL_TIM_PERIOD_ELAPSED_CB_ID = 0x0EU /*!< TIM Period Elapsed Callback ID */ + , + HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID = + 0x0FU /*!< TIM Period Elapsed half complete Callback ID */ + , + HAL_TIM_TRIGGER_CB_ID = 0x10U /*!< TIM Trigger Callback ID */ + , + HAL_TIM_TRIGGER_HALF_CB_ID = 0x11U /*!< TIM Trigger half complete Callback ID */ + + , + HAL_TIM_IC_CAPTURE_CB_ID = 0x12U /*!< TIM Input Capture Callback ID */ + , + HAL_TIM_IC_CAPTURE_HALF_CB_ID = + 0x13U /*!< TIM Input Capture half complete Callback ID */ + , + HAL_TIM_OC_DELAY_ELAPSED_CB_ID = + 0x14U /*!< TIM Output Compare Delay Elapsed Callback ID */ + , + HAL_TIM_PWM_PULSE_FINISHED_CB_ID = + 0x15U /*!< TIM PWM Pulse Finished Callback ID */ + , + HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID = + 0x16U /*!< TIM PWM Pulse Finished half complete Callback ID */ + , + HAL_TIM_ERROR_CB_ID = 0x17U /*!< TIM Error Callback ID */ + , + HAL_TIM_COMMUTATION_CB_ID = 0x18U /*!< TIM Commutation Callback ID */ + , + HAL_TIM_COMMUTATION_HALF_CB_ID = + 0x19U /*!< TIM Commutation half complete Callback ID */ + , + HAL_TIM_BREAK_CB_ID = 0x1AU /*!< TIM Break Callback ID */ + } HAL_TIM_CallbackIDTypeDef; + + /** + * @brief HAL TIM Callback pointer definition + */ + typedef void (*pTIM_CallbackTypeDef)( + TIM_HandleTypeDef *htim); /*!< pointer to the TIM callback function */ + +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ +/* End of exported types -----------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_ClearInput_Source TIM Clear Input Source + * @{ + */ +#define TIM_CLEARINPUTSOURCE_NONE 0x00000000U /*!< OCREF_CLR is disabled */ +#define TIM_CLEARINPUTSOURCE_ETR \ + 0x00000001U /*!< OCREF_CLR is connected to ETRF input \ + */ +#define TIM_CLEARINPUTSOURCE_OCREFCLR \ + 0x00000002U /*!< OCREF_CLR is connected to OCREF_CLR_INT */ +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address TIM DMA Base Address + * @{ + */ +#define TIM_DMABASE_CR1 0x00000000U +#define TIM_DMABASE_CR2 0x00000001U +#define TIM_DMABASE_SMCR 0x00000002U +#define TIM_DMABASE_DIER 0x00000003U +#define TIM_DMABASE_SR 0x00000004U +#define TIM_DMABASE_EGR 0x00000005U +#define TIM_DMABASE_CCMR1 0x00000006U +#define TIM_DMABASE_CCMR2 0x00000007U +#define TIM_DMABASE_CCER 0x00000008U +#define TIM_DMABASE_CNT 0x00000009U +#define TIM_DMABASE_PSC 0x0000000AU +#define TIM_DMABASE_ARR 0x0000000BU +#define TIM_DMABASE_RCR 0x0000000CU +#define TIM_DMABASE_CCR1 0x0000000DU +#define TIM_DMABASE_CCR2 0x0000000EU +#define TIM_DMABASE_CCR3 0x0000000FU +#define TIM_DMABASE_CCR4 0x00000010U +#define TIM_DMABASE_BDTR 0x00000011U +#define TIM_DMABASE_DCR 0x00000012U +#define TIM_DMABASE_DMAR 0x00000013U +/** + * @} + */ + +/** @defgroup TIM_Event_Source TIM Event Source + * @{ + */ +#define TIM_EVENTSOURCE_UPDATE \ + TIM_EGR_UG /*!< Reinitialize the counter and generates an update of the registers */ +#define TIM_EVENTSOURCE_CC1 \ + TIM_EGR_CC1G /*!< A capture/compare event is generated on channel 1 */ +#define TIM_EVENTSOURCE_CC2 \ + TIM_EGR_CC2G /*!< A capture/compare event is generated on channel 2 */ +#define TIM_EVENTSOURCE_CC3 \ + TIM_EGR_CC3G /*!< A capture/compare event is generated on channel 3 */ +#define TIM_EVENTSOURCE_CC4 \ + TIM_EGR_CC4G /*!< A capture/compare event is generated on channel 4 */ +#define TIM_EVENTSOURCE_COM TIM_EGR_COMG /*!< A commutation event is generated */ +#define TIM_EVENTSOURCE_TRIGGER TIM_EGR_TG /*!< A trigger event is generated */ +#define TIM_EVENTSOURCE_BREAK TIM_EGR_BG /*!< A break event is generated */ +/** + * @} + */ + +/** @defgroup TIM_Input_Channel_Polarity TIM Input Channel polarity + * @{ + */ +#define TIM_INPUTCHANNELPOLARITY_RISING 0x00000000U /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_FALLING TIM_CCER_CC1P /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_BOTHEDGE \ + (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< Polarity for TIx source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Polarity TIM ETR Polarity + * @{ + */ +#define TIM_ETRPOLARITY_INVERTED TIM_SMCR_ETP /*!< Polarity for ETR source */ +#define TIM_ETRPOLARITY_NONINVERTED 0x00000000U /*!< Polarity for ETR source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Prescaler TIM ETR Prescaler + * @{ + */ +#define TIM_ETRPRESCALER_DIV1 0x00000000U /*!< No prescaler is used */ +#define TIM_ETRPRESCALER_DIV2 TIM_SMCR_ETPS_0 /*!< ETR input source is divided by 2 */ +#define TIM_ETRPRESCALER_DIV4 TIM_SMCR_ETPS_1 /*!< ETR input source is divided by 4 */ +#define TIM_ETRPRESCALER_DIV8 TIM_SMCR_ETPS /*!< ETR input source is divided by 8 */ +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode TIM Counter Mode + * @{ + */ +#define TIM_COUNTERMODE_UP 0x00000000U /*!< Counter used as up-counter */ +#define TIM_COUNTERMODE_DOWN TIM_CR1_DIR /*!< Counter used as down-counter */ +#define TIM_COUNTERMODE_CENTERALIGNED1 TIM_CR1_CMS_0 /*!< Center-aligned mode 1 */ +#define TIM_COUNTERMODE_CENTERALIGNED2 TIM_CR1_CMS_1 /*!< Center-aligned mode 2 */ +#define TIM_COUNTERMODE_CENTERALIGNED3 TIM_CR1_CMS /*!< Center-aligned mode 3 */ +/** + * @} + */ + +/** @defgroup TIM_ClockDivision TIM Clock Division + * @{ + */ +#define TIM_CLOCKDIVISION_DIV1 0x00000000U /*!< Clock division: tDTS=tCK_INT */ +#define TIM_CLOCKDIVISION_DIV2 TIM_CR1_CKD_0 /*!< Clock division: tDTS=2*tCK_INT */ +#define TIM_CLOCKDIVISION_DIV4 TIM_CR1_CKD_1 /*!< Clock division: tDTS=4*tCK_INT */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_State TIM Output Compare State + * @{ + */ +#define TIM_OUTPUTSTATE_DISABLE 0x00000000U /*!< Capture/Compare 1 output disabled */ +#define TIM_OUTPUTSTATE_ENABLE TIM_CCER_CC1E /*!< Capture/Compare 1 output enabled */ +/** + * @} + */ + +/** @defgroup TIM_AutoReloadPreload TIM Auto-Reload Preload + * @{ + */ +#define TIM_AUTORELOAD_PRELOAD_DISABLE \ + 0x00000000U /*!< TIMx_ARR register is not buffered */ +#define TIM_AUTORELOAD_PRELOAD_ENABLE TIM_CR1_ARPE /*!< TIMx_ARR register is buffered */ + +/** + * @} + */ + +/** @defgroup TIM_Output_Fast_State TIM Output Fast State + * @{ + */ +#define TIM_OCFAST_DISABLE 0x00000000U /*!< Output Compare fast disable */ +#define TIM_OCFAST_ENABLE TIM_CCMR1_OC1FE /*!< Output Compare fast enable */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_State TIM Complementary Output Compare State + * @{ + */ +#define TIM_OUTPUTNSTATE_DISABLE 0x00000000U /*!< OCxN is disabled */ +#define TIM_OUTPUTNSTATE_ENABLE TIM_CCER_CC1NE /*!< OCxN is enabled */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity TIM Output Compare Polarity + * @{ + */ +#define TIM_OCPOLARITY_HIGH 0x00000000U /*!< Capture/Compare output polarity */ +#define TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< Capture/Compare output polarity */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity TIM Complementary Output Compare Polarity + * @{ + */ +#define TIM_OCNPOLARITY_HIGH \ + 0x00000000U /*!< Capture/Compare complementary output polarity */ +#define TIM_OCNPOLARITY_LOW \ + TIM_CCER_CC1NP /*!< Capture/Compare complementary output polarity */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Idle_State TIM Output Compare Idle State + * @{ + */ +#define TIM_OCIDLESTATE_SET TIM_CR2_OIS1 /*!< Output Idle state: OCx=1 when MOE=0 */ +#define TIM_OCIDLESTATE_RESET 0x00000000U /*!< Output Idle state: OCx=0 when MOE=0 */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Idle_State TIM Complementary Output Compare Idle State + * @{ + */ +#define TIM_OCNIDLESTATE_SET \ + TIM_CR2_OIS1N /*!< Complementary output Idle state: OCxN=1 when MOE=0 */ +#define TIM_OCNIDLESTATE_RESET \ + 0x00000000U /*!< Complementary output Idle state: OCxN=0 when MOE=0 */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity TIM Input Capture Polarity + * @{ + */ +#define TIM_ICPOLARITY_RISING \ + TIM_INPUTCHANNELPOLARITY_RISING /*!< Capture triggered by rising edge on timer input \ + */ +#define TIM_ICPOLARITY_FALLING \ + TIM_INPUTCHANNELPOLARITY_FALLING /*!< Capture triggered by falling edge on timer \ + input */ +#define TIM_ICPOLARITY_BOTHEDGE \ + TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Capture triggered by both rising and falling \ + edges on timer input*/ +/** + * @} + */ + +/** @defgroup TIM_Encoder_Input_Polarity TIM Encoder Input Polarity + * @{ + */ +#define TIM_ENCODERINPUTPOLARITY_RISING \ + TIM_INPUTCHANNELPOLARITY_RISING /*!< Encoder input with rising edge polarity */ +#define TIM_ENCODERINPUTPOLARITY_FALLING \ + TIM_INPUTCHANNELPOLARITY_FALLING /*!< Encoder input with falling edge polarity */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection TIM Input Capture Selection + * @{ + */ +#define TIM_ICSELECTION_DIRECTTI \ + TIM_CCMR1_CC1S_0 /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, \ + IC2, IC3 or IC4, respectively */ +#define TIM_ICSELECTION_INDIRECTTI \ + TIM_CCMR1_CC1S_1 /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC2, \ + IC1, IC4 or IC3, respectively */ +#define TIM_ICSELECTION_TRC \ + TIM_CCMR1_CC1S /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler TIM Input Capture Prescaler + * @{ + */ +#define TIM_ICPSC_DIV1 \ + 0x00000000U /*!< Capture performed each time an edge is detected on the capture \ + input */ +#define TIM_ICPSC_DIV2 TIM_CCMR1_IC1PSC_0 /*!< Capture performed once every 2 events */ +#define TIM_ICPSC_DIV4 TIM_CCMR1_IC1PSC_1 /*!< Capture performed once every 4 events */ +#define TIM_ICPSC_DIV8 TIM_CCMR1_IC1PSC /*!< Capture performed once every 8 events */ +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode TIM One Pulse Mode + * @{ + */ +#define TIM_OPMODE_SINGLE \ + TIM_CR1_OPM /*!< Counter stops counting at the next update event */ +#define TIM_OPMODE_REPETITIVE \ + 0x00000000U /*!< Counter is not stopped at update event */ +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode TIM Encoder Mode + * @{ + */ +#define TIM_ENCODERMODE_TI1 \ + TIM_SMCR_SMS_0 /*!< Quadrature encoder mode 1, x2 mode, counts up/down on TI1FP1 \ + edge depending on TI2FP2 level */ +#define TIM_ENCODERMODE_TI2 \ + TIM_SMCR_SMS_1 /*!< Quadrature encoder mode 2, x2 mode, counts up/down on TI2FP2 \ + edge depending on TI1FP1 level. */ +#define TIM_ENCODERMODE_TI12 \ + (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Quadrature encoder mode 3, x4 mode, counts \ + up/down on both TI1FP1 and TI2FP2 edges \ + depending on the level of the other input. */ +/** + * @} + */ + +/** @defgroup TIM_Interrupt_definition TIM interrupt Definition + * @{ + */ +#define TIM_IT_UPDATE TIM_DIER_UIE /*!< Update interrupt */ +#define TIM_IT_CC1 TIM_DIER_CC1IE /*!< Capture/Compare 1 interrupt */ +#define TIM_IT_CC2 TIM_DIER_CC2IE /*!< Capture/Compare 2 interrupt */ +#define TIM_IT_CC3 TIM_DIER_CC3IE /*!< Capture/Compare 3 interrupt */ +#define TIM_IT_CC4 TIM_DIER_CC4IE /*!< Capture/Compare 4 interrupt */ +#define TIM_IT_COM TIM_DIER_COMIE /*!< Commutation interrupt */ +#define TIM_IT_TRIGGER TIM_DIER_TIE /*!< Trigger interrupt */ +#define TIM_IT_BREAK TIM_DIER_BIE /*!< Break interrupt */ +/** + * @} + */ + +/** @defgroup TIM_Commutation_Source TIM Commutation Source + * @{ + */ +#define TIM_COMMUTATION_TRGI \ + TIM_CR2_CCUS /*!< When Capture/compare control bits are preloaded, they are updated \ + by setting the COMG bit or when an rising edge occurs on trigger \ + input */ +#define TIM_COMMUTATION_SOFTWARE \ + 0x00000000U /*!< When Capture/compare control bits are preloaded, they are updated \ + by setting the COMG bit */ +/** + * @} + */ + +/** @defgroup TIM_DMA_sources TIM DMA Sources + * @{ + */ +#define TIM_DMA_UPDATE TIM_DIER_UDE /*!< DMA request is triggered by the update event */ +#define TIM_DMA_CC1 \ + TIM_DIER_CC1DE /*!< DMA request is triggered by the capture/compare macth 1 event */ +#define TIM_DMA_CC2 \ + TIM_DIER_CC2DE /*!< DMA request is triggered by the capture/compare macth 2 event \ + event */ +#define TIM_DMA_CC3 \ + TIM_DIER_CC3DE /*!< DMA request is triggered by the capture/compare macth 3 event \ + event */ +#define TIM_DMA_CC4 \ + TIM_DIER_CC4DE /*!< DMA request is triggered by the capture/compare macth 4 event \ + event */ +#define TIM_DMA_COM \ + TIM_DIER_COMDE /*!< DMA request is triggered by the commutation event */ +#define TIM_DMA_TRIGGER \ + TIM_DIER_TDE /*!< DMA request is triggered by the trigger event \ + */ +/** + * @} + */ + +/** @defgroup TIM_CC_DMA_Request CCx DMA request selection + * @{ + */ +#define TIM_CCDMAREQUEST_CC \ + 0x00000000U /*!< CCx DMA request sent when capture or compare match event occurs */ +#define TIM_CCDMAREQUEST_UPDATE \ + TIM_CR2_CCDS /*!< CCx DMA requests sent when update event occurs */ +/** + * @} + */ + +/** @defgroup TIM_Flag_definition TIM Flag Definition + * @{ + */ +#define TIM_FLAG_UPDATE TIM_SR_UIF /*!< Update interrupt flag */ +#define TIM_FLAG_CC1 TIM_SR_CC1IF /*!< Capture/Compare 1 interrupt flag */ +#define TIM_FLAG_CC2 TIM_SR_CC2IF /*!< Capture/Compare 2 interrupt flag */ +#define TIM_FLAG_CC3 TIM_SR_CC3IF /*!< Capture/Compare 3 interrupt flag */ +#define TIM_FLAG_CC4 TIM_SR_CC4IF /*!< Capture/Compare 4 interrupt flag */ +#define TIM_FLAG_COM TIM_SR_COMIF /*!< Commutation interrupt flag */ +#define TIM_FLAG_TRIGGER TIM_SR_TIF /*!< Trigger interrupt flag */ +#define TIM_FLAG_BREAK TIM_SR_BIF /*!< Break interrupt flag */ +#define TIM_FLAG_CC1OF TIM_SR_CC1OF /*!< Capture 1 overcapture flag */ +#define TIM_FLAG_CC2OF TIM_SR_CC2OF /*!< Capture 2 overcapture flag */ +#define TIM_FLAG_CC3OF TIM_SR_CC3OF /*!< Capture 3 overcapture flag */ +#define TIM_FLAG_CC4OF TIM_SR_CC4OF /*!< Capture 4 overcapture flag */ +/** + * @} + */ + +/** @defgroup TIM_Channel TIM Channel + * @{ + */ +#define TIM_CHANNEL_1 0x00000000U /*!< Capture/compare channel 1 identifier */ +#define TIM_CHANNEL_2 0x00000004U /*!< Capture/compare channel 2 identifier */ +#define TIM_CHANNEL_3 0x00000008U /*!< Capture/compare channel 3 identifier */ +#define TIM_CHANNEL_4 0x0000000CU /*!< Capture/compare channel 4 identifier */ +#define TIM_CHANNEL_ALL 0x0000003CU /*!< Global Capture/compare channel identifier */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Source TIM Clock Source + * @{ + */ +#define TIM_CLOCKSOURCE_INTERNAL \ + TIM_SMCR_ETPS_0 /*!< Internal clock source */ +#define TIM_CLOCKSOURCE_ETRMODE1 \ + TIM_TS_ETRF /*!< External clock source mode 1 (ETRF) */ +#define TIM_CLOCKSOURCE_ETRMODE2 \ + TIM_SMCR_ETPS_1 /*!< External clock source mode 2 */ +#define TIM_CLOCKSOURCE_TI1ED \ + TIM_TS_TI1F_ED /*!< External clock source mode 1 (TTI1FP1 + edge detect.) */ +#define TIM_CLOCKSOURCE_TI1 \ + TIM_TS_TI1FP1 /*!< External clock source mode 1 (TTI1FP1) */ +#define TIM_CLOCKSOURCE_TI2 \ + TIM_TS_TI2FP2 /*!< External clock source mode 1 (TTI2FP2) */ +#define TIM_CLOCKSOURCE_ITR0 \ + TIM_TS_ITR0 /*!< External clock source mode 1 (ITR0) */ +#define TIM_CLOCKSOURCE_ITR1 \ + TIM_TS_ITR1 /*!< External clock source mode 1 (ITR1) */ +#define TIM_CLOCKSOURCE_ITR2 \ + TIM_TS_ITR2 /*!< External clock source mode 1 (ITR2) */ +#define TIM_CLOCKSOURCE_ITR3 \ + TIM_TS_ITR3 /*!< External clock source mode 1 (ITR3) */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Polarity TIM Clock Polarity + * @{ + */ +#define TIM_CLOCKPOLARITY_INVERTED \ + TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_NONINVERTED \ + TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_RISING \ + TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_FALLING \ + TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_BOTHEDGE \ + TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIx clock sources */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Prescaler TIM Clock Prescaler + * @{ + */ +#define TIM_CLOCKPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLOCKPRESCALER_DIV2 \ + TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Clock: Capture performed once \ + every 2 events. */ +#define TIM_CLOCKPRESCALER_DIV4 \ + TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Clock: Capture performed once \ + every 4 events. */ +#define TIM_CLOCKPRESCALER_DIV8 \ + TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Clock: Capture performed once \ + every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Polarity TIM Clear Input Polarity + * @{ + */ +#define TIM_CLEARINPUTPOLARITY_INVERTED \ + TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx pin */ +#define TIM_CLEARINPUTPOLARITY_NONINVERTED \ + TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx pin */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Prescaler TIM Clear Input Prescaler + * @{ + */ +#define TIM_CLEARINPUTPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLEARINPUTPRESCALER_DIV2 \ + TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR pin: Capture performed once \ + every 2 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV4 \ + TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR pin: Capture performed once \ + every 4 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV8 \ + TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR pin: Capture performed once \ + every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state TIM OSSR OffState Selection + * for Run mode state + * @{ + */ +#define TIM_OSSR_ENABLE \ + TIM_BDTR_OSSR /*!< When inactive, OC/OCN outputs are enabled (still controlled by \ + the timer) */ +#define TIM_OSSR_DISABLE \ + 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any \ + longer by the timer) */ +/** + * @} + */ + +/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state TIM OSSI OffState Selection + * for Idle mode state + * @{ + */ +#define TIM_OSSI_ENABLE \ + TIM_BDTR_OSSI /*!< When inactive, OC/OCN outputs are enabled (still controlled by \ + the timer) */ +#define TIM_OSSI_DISABLE \ + 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any \ + longer by the timer) */ +/** + * @} + */ +/** @defgroup TIM_Lock_level TIM Lock level + * @{ + */ +#define TIM_LOCKLEVEL_OFF 0x00000000U /*!< LOCK OFF */ +#define TIM_LOCKLEVEL_1 TIM_BDTR_LOCK_0 /*!< LOCK Level 1 */ +#define TIM_LOCKLEVEL_2 TIM_BDTR_LOCK_1 /*!< LOCK Level 2 */ +#define TIM_LOCKLEVEL_3 TIM_BDTR_LOCK /*!< LOCK Level 3 */ +/** + * @} + */ + +/** @defgroup TIM_Break_Input_enable_disable TIM Break Input Enable + * @{ + */ +#define TIM_BREAK_ENABLE TIM_BDTR_BKE /*!< Break input BRK is enabled */ +#define TIM_BREAK_DISABLE 0x00000000U /*!< Break input BRK is disabled */ +/** + * @} + */ + +/** @defgroup TIM_Break_Polarity TIM Break Input Polarity + * @{ + */ +#define TIM_BREAKPOLARITY_LOW 0x00000000U /*!< Break input BRK is active low */ +#define TIM_BREAKPOLARITY_HIGH TIM_BDTR_BKP /*!< Break input BRK is active high */ +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset TIM Automatic Output Enable + * @{ + */ +#define TIM_AUTOMATICOUTPUT_DISABLE 0x00000000U /*!< MOE can be set only by software */ +#define TIM_AUTOMATICOUTPUT_ENABLE \ + TIM_BDTR_AOE /*!< MOE can be set by software or automatically at the next update \ + event (if none of the break inputs BRK and BRK2 is active) */ +/** + * @} + */ + +/** @defgroup TIM_Master_Mode_Selection TIM Master Mode Selection + * @{ + */ +#define TIM_TRGO_RESET \ + 0x00000000U /*!< TIMx_EGR.UG bit is used as trigger output (TRGO) */ +#define TIM_TRGO_ENABLE \ + TIM_CR2_MMS_0 /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO) */ +#define TIM_TRGO_UPDATE \ + TIM_CR2_MMS_1 /*!< Update event is used as trigger output (TRGO) */ +#define TIM_TRGO_OC1 \ + (TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< Capture or a compare match 1 is used as trigger \ + output (TRGO) */ +#define TIM_TRGO_OC1REF \ + TIM_CR2_MMS_2 /*!< OC1REF signal is used as trigger output (TRGO) */ +#define TIM_TRGO_OC2REF \ + (TIM_CR2_MMS_2 | TIM_CR2_MMS_0) /*!< OC2REF signal is used as trigger output(TRGO) \ + */ +#define TIM_TRGO_OC3REF \ + (TIM_CR2_MMS_2 | TIM_CR2_MMS_1) /*!< OC3REF signal is used as trigger output(TRGO) \ + */ +#define TIM_TRGO_OC4REF \ + (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | \ + TIM_CR2_MMS_0) /*!< OC4REF signal is used as trigger output(TRGO) */ +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode TIM Master/Slave Mode + * @{ + */ +#define TIM_MASTERSLAVEMODE_ENABLE TIM_SMCR_MSM /*!< No action */ +#define TIM_MASTERSLAVEMODE_DISABLE 0x00000000U /*!< Master/slave mode is selected */ +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode TIM Slave mode + * @{ + */ +#define TIM_SLAVEMODE_DISABLE 0x00000000U /*!< Slave mode disabled */ +#define TIM_SLAVEMODE_RESET TIM_SMCR_SMS_2 /*!< Reset Mode */ +#define TIM_SLAVEMODE_GATED \ + (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0) /*!< Gated Mode */ +#define TIM_SLAVEMODE_TRIGGER \ + (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) /*!< Trigger Mode */ +#define TIM_SLAVEMODE_EXTERNAL1 \ + (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< External Clock Mode 1 */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_and_PWM_modes TIM Output Compare and PWM Modes + * @{ + */ +#define TIM_OCMODE_TIMING 0x00000000U /*!< Frozen */ +#define TIM_OCMODE_ACTIVE TIM_CCMR1_OC1M_0 /*!< Set channel to active level on match */ +#define TIM_OCMODE_INACTIVE \ + TIM_CCMR1_OC1M_1 /*!< Set channel to inactive level on match */ +#define TIM_OCMODE_TOGGLE \ + (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< Toggle */ +#define TIM_OCMODE_PWM1 \ + (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1) /*!< PWM mode 1 */ +#define TIM_OCMODE_PWM2 \ + (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< PWM mode 2 */ +#define TIM_OCMODE_FORCED_ACTIVE \ + (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0) /*!< Force active level */ +#define TIM_OCMODE_FORCED_INACTIVE \ + TIM_CCMR1_OC1M_2 /*!< Force inactive level */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Selection TIM Trigger Selection + * @{ + */ +#define TIM_TS_ITR0 0x00000000U /*!< Internal Trigger 0 (ITR0) */ +#define TIM_TS_ITR1 TIM_SMCR_TS_0 /*!< Internal Trigger 1 (ITR1) */ +#define TIM_TS_ITR2 TIM_SMCR_TS_1 /*!< Internal Trigger 2 (ITR2) */ +#define TIM_TS_ITR3 \ + (TIM_SMCR_TS_0 | TIM_SMCR_TS_1) /*!< Internal Trigger 3 (ITR3) */ +#define TIM_TS_TI1F_ED TIM_SMCR_TS_2 /*!< TI1 Edge Detector (TI1F_ED) */ +#define TIM_TS_TI1FP1 \ + (TIM_SMCR_TS_0 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 1 (TI1FP1) */ +#define TIM_TS_TI2FP2 \ + (TIM_SMCR_TS_1 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 2 (TI2FP2) */ +#define TIM_TS_ETRF \ + (TIM_SMCR_TS_0 | TIM_SMCR_TS_1 | \ + TIM_SMCR_TS_2) /*!< Filtered External Trigger input (ETRF) */ +#define TIM_TS_NONE 0x0000FFFFU /*!< No trigger selected */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Polarity TIM Trigger Polarity + * @{ + */ +#define TIM_TRIGGERPOLARITY_INVERTED \ + TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_NONINVERTED \ + TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_RISING \ + TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIxFPx or TI1_ED trigger sources \ + */ +#define TIM_TRIGGERPOLARITY_FALLING \ + TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIxFPx or TI1_ED trigger sources \ + */ +#define TIM_TRIGGERPOLARITY_BOTHEDGE \ + TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIxFPx or TI1_ED trigger sources \ + */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Prescaler TIM Trigger Prescaler + * @{ + */ +#define TIM_TRIGGERPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_TRIGGERPRESCALER_DIV2 \ + TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Trigger: Capture performed \ + once every 2 events. */ +#define TIM_TRIGGERPRESCALER_DIV4 \ + TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Trigger: Capture performed \ + once every 4 events. */ +#define TIM_TRIGGERPRESCALER_DIV8 \ + TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Trigger: Capture performed \ + once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_TI1_Selection TIM TI1 Input Selection + * @{ + */ +#define TIM_TI1SELECTION_CH1 \ + 0x00000000U /*!< The TIMx_CH1 pin is connected to TI1 input */ +#define TIM_TI1SELECTION_XORCOMBINATION \ + TIM_CR2_TI1S /*!< The TIMx_CH1, CH2 and CH3 pins are connected to the TI1 input (XOR \ + combination) */ +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length TIM DMA Burst Length + * @{ + */ +#define TIM_DMABURSTLENGTH_1TRANSFER \ + 0x00000000U /*!< The transfer is done to 1 register starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_2TRANSFERS \ + 0x00000100U /*!< The transfer is done to 2 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_3TRANSFERS \ + 0x00000200U /*!< The transfer is done to 3 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_4TRANSFERS \ + 0x00000300U /*!< The transfer is done to 4 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_5TRANSFERS \ + 0x00000400U /*!< The transfer is done to 5 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_6TRANSFERS \ + 0x00000500U /*!< The transfer is done to 6 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_7TRANSFERS \ + 0x00000600U /*!< The transfer is done to 7 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_8TRANSFERS \ + 0x00000700U /*!< The transfer is done to 8 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_9TRANSFERS \ + 0x00000800U /*!< The transfer is done to 9 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_10TRANSFERS \ + 0x00000900U /*!< The transfer is done to 10 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_11TRANSFERS \ + 0x00000A00U /*!< The transfer is done to 11 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_12TRANSFERS \ + 0x00000B00U /*!< The transfer is done to 12 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_13TRANSFERS \ + 0x00000C00U /*!< The transfer is done to 13 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_14TRANSFERS \ + 0x00000D00U /*!< The transfer is done to 14 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_15TRANSFERS \ + 0x00000E00U /*!< The transfer is done to 15 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_16TRANSFERS \ + 0x00000F00U /*!< The transfer is done to 16 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_17TRANSFERS \ + 0x00001000U /*!< The transfer is done to 17 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_18TRANSFERS \ + 0x00001100U /*!< The transfer is done to 18 registers starting from TIMx_CR1 + \ + TIMx_DCR.DBA */ +/** + * @} + */ + +/** @defgroup DMA_Handle_index TIM DMA Handle Index + * @{ + */ +#define TIM_DMA_ID_UPDATE \ + ((uint16_t)0x0000) /*!< Index of the DMA handle used for Update DMA requests */ +#define TIM_DMA_ID_CC1 \ + ((uint16_t)0x0001) /*!< Index of the DMA handle used for Capture/Compare 1 DMA \ + requests */ +#define TIM_DMA_ID_CC2 \ + ((uint16_t)0x0002) /*!< Index of the DMA handle used for Capture/Compare 2 DMA \ + requests */ +#define TIM_DMA_ID_CC3 \ + ((uint16_t)0x0003) /*!< Index of the DMA handle used for Capture/Compare 3 DMA \ + requests */ +#define TIM_DMA_ID_CC4 \ + ((uint16_t)0x0004) /*!< Index of the DMA handle used for Capture/Compare 4 DMA \ + requests */ +#define TIM_DMA_ID_COMMUTATION \ + ((uint16_t)0x0005) /*!< Index of the DMA handle used for Commutation DMA requests */ +#define TIM_DMA_ID_TRIGGER \ + ((uint16_t)0x0006) /*!< Index of the DMA handle used for Trigger DMA requests */ +/** + * @} + */ + +/** @defgroup Channel_CC_State TIM Capture/Compare Channel State + * @{ + */ +#define TIM_CCx_ENABLE 0x00000001U /*!< Input or output channel is enabled */ +#define TIM_CCx_DISABLE 0x00000000U /*!< Input or output channel is disabled */ +#define TIM_CCxN_ENABLE 0x00000004U /*!< Complementary output channel is enabled */ +#define TIM_CCxN_DISABLE 0x00000000U /*!< Complementary output channel is enabled */ +/** + * @} + */ + +/** + * @} + */ +/* End of exported constants -------------------------------------------------*/ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup TIM_Exported_Macros TIM Exported Macros + * @{ + */ + +/** @brief Reset TIM handle state. + * @param __HANDLE__ TIM handle. + * @retval None + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) \ + do \ + { \ + (__HANDLE__)->State = HAL_TIM_STATE_RESET; \ + (__HANDLE__)->ChannelState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->DMABurstState = HAL_DMA_BURST_STATE_RESET; \ + (__HANDLE__)->Base_MspInitCallback = NULL; \ + (__HANDLE__)->Base_MspDeInitCallback = NULL; \ + (__HANDLE__)->IC_MspInitCallback = NULL; \ + (__HANDLE__)->IC_MspDeInitCallback = NULL; \ + (__HANDLE__)->OC_MspInitCallback = NULL; \ + (__HANDLE__)->OC_MspDeInitCallback = NULL; \ + (__HANDLE__)->PWM_MspInitCallback = NULL; \ + (__HANDLE__)->PWM_MspDeInitCallback = NULL; \ + (__HANDLE__)->OnePulse_MspInitCallback = NULL; \ + (__HANDLE__)->OnePulse_MspDeInitCallback = NULL; \ + (__HANDLE__)->Encoder_MspInitCallback = NULL; \ + (__HANDLE__)->Encoder_MspDeInitCallback = NULL; \ + (__HANDLE__)->HallSensor_MspInitCallback = NULL; \ + (__HANDLE__)->HallSensor_MspDeInitCallback = NULL; \ + } while (0) +#else +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) \ + do \ + { \ + (__HANDLE__)->State = HAL_TIM_STATE_RESET; \ + (__HANDLE__)->ChannelState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->DMABurstState = HAL_DMA_BURST_STATE_RESET; \ + } while (0) +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @brief Enable the TIM peripheral. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= (TIM_CR1_CEN)) + +/** + * @brief Enable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_MOE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->BDTR |= (TIM_BDTR_MOE)) + +/** + * @brief Disable the TIM peripheral. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_DISABLE(__HANDLE__) \ + do \ + { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \ + { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \ + { \ + (__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \ + } \ + } \ + } while (0) + +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + * @note The Main Output Enable of a timer instance is disabled only if all the CCx and + * CCxN channels have been disabled + */ +#define __HAL_TIM_MOE_DISABLE(__HANDLE__) \ + do \ + { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \ + { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \ + { \ + (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE); \ + } \ + } \ + } while (0) + +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + * @note The Main Output Enable of a timer instance is disabled unconditionally + */ +#define __HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(__HANDLE__) \ + (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE) + +/** @brief Enable the specified TIM interrupt. + * @param __HANDLE__ specifies the TIM Handle. + * @param __INTERRUPT__ specifies the TIM interrupt source to enable. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__)) + +/** @brief Disable the specified TIM interrupt. + * @param __HANDLE__ specifies the TIM Handle. + * @param __INTERRUPT__ specifies the TIM interrupt source to disable. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->DIER &= ~(__INTERRUPT__)) + +/** @brief Enable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the TIM DMA request to enable. + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: Update DMA request + * @arg TIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg TIM_DMA_CC2: Capture/Compare 2 DMA request + * @arg TIM_DMA_CC3: Capture/Compare 3 DMA request + * @arg TIM_DMA_CC4: Capture/Compare 4 DMA request + * @arg TIM_DMA_COM: Commutation DMA request + * @arg TIM_DMA_TRIGGER: Trigger DMA request + * @retval None + */ +#define __HAL_TIM_ENABLE_DMA(__HANDLE__, __DMA__) \ + ((__HANDLE__)->Instance->DIER |= (__DMA__)) + +/** @brief Disable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the TIM DMA request to disable. + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: Update DMA request + * @arg TIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg TIM_DMA_CC2: Capture/Compare 2 DMA request + * @arg TIM_DMA_CC3: Capture/Compare 3 DMA request + * @arg TIM_DMA_CC4: Capture/Compare 4 DMA request + * @arg TIM_DMA_COM: Commutation DMA request + * @arg TIM_DMA_TRIGGER: Trigger DMA request + * @retval None + */ +#define __HAL_TIM_DISABLE_DMA(__HANDLE__, __DMA__) \ + ((__HANDLE__)->Instance->DIER &= ~(__DMA__)) + +/** @brief Check whether the specified TIM interrupt flag is set or not. + * @param __HANDLE__ specifies the TIM Handle. + * @param __FLAG__ specifies the TIM interrupt flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_UPDATE: Update interrupt flag + * @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag + * @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag + * @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag + * @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag + * @arg TIM_FLAG_COM: Commutation interrupt flag + * @arg TIM_FLAG_TRIGGER: Trigger interrupt flag + * @arg TIM_FLAG_BREAK: Break interrupt flag + * @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag + * @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag + * @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag + * @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__) \ + (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified TIM interrupt flag. + * @param __HANDLE__ specifies the TIM Handle. + * @param __FLAG__ specifies the TIM interrupt flag to clear. + * This parameter can be one of the following values: + * @arg TIM_FLAG_UPDATE: Update interrupt flag + * @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag + * @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag + * @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag + * @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag + * @arg TIM_FLAG_COM: Commutation interrupt flag + * @arg TIM_FLAG_TRIGGER: Trigger interrupt flag + * @arg TIM_FLAG_BREAK: Break interrupt flag + * @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag + * @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag + * @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag + * @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** + * @brief Check whether the specified TIM interrupt source is enabled or not. + * @param __HANDLE__ TIM handle + * @param __INTERRUPT__ specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval The state of TIM_IT (SET or RESET). + */ +#define __HAL_TIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + ((((__HANDLE__)->Instance->DIER & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Clear the TIM interrupt pending bits. + * @param __HANDLE__ TIM handle + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) \ + ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__)) + +/** + * @brief Indicates whether or not the TIM Counter is used as downcounter. + * @param __HANDLE__ TIM handle. + * @retval False (Counter used as upcounter) or True (Counter used as downcounter) + * @note This macro is particularly useful to get the counting mode when the timer + * operates in Center-aligned mode or Encoder mode. + */ +#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__) \ + (((__HANDLE__)->Instance->CR1 & (TIM_CR1_DIR)) == (TIM_CR1_DIR)) + +/** + * @brief Set the TIM Prescaler on runtime. + * @param __HANDLE__ TIM handle. + * @param __PRESC__ specifies the Prescaler new value. + * @retval None + */ +#define __HAL_TIM_SET_PRESCALER(__HANDLE__, __PRESC__) \ + ((__HANDLE__)->Instance->PSC = (__PRESC__)) + +/** + * @brief Set the TIM Counter Register value on runtime. + * @param __HANDLE__ TIM handle. + * @param __COUNTER__ specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__) \ + ((__HANDLE__)->Instance->CNT = (__COUNTER__)) + +/** + * @brief Get the TIM Counter Register value on runtime. + * @param __HANDLE__ TIM handle. + * @retval 16-bit or 32-bit value of the timer counter register (TIMx_CNT) + */ +#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT) + +/** + * @brief Set the TIM Autoreload Register value on runtime without calling another time + * any Init function. + * @param __HANDLE__ TIM handle. + * @param __AUTORELOAD__ specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__) \ + do \ + { \ + (__HANDLE__)->Instance->ARR = (__AUTORELOAD__); \ + (__HANDLE__)->Init.Period = (__AUTORELOAD__); \ + } while (0) + +/** + * @brief Get the TIM Autoreload Register value on runtime. + * @param __HANDLE__ TIM handle. + * @retval 16-bit or 32-bit value of the timer auto-reload register(TIMx_ARR) + */ +#define __HAL_TIM_GET_AUTORELOAD(__HANDLE__) ((__HANDLE__)->Instance->ARR) + +/** + * @brief Set the TIM Clock Division value on runtime without calling another time any + * Init function. + * @param __HANDLE__ TIM handle. + * @param __CKD__ specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT + * @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT + * @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT + * @retval None + */ +#define __HAL_TIM_SET_CLOCKDIVISION(__HANDLE__, __CKD__) \ + do \ + { \ + (__HANDLE__)->Instance->CR1 &= (~TIM_CR1_CKD); \ + (__HANDLE__)->Instance->CR1 |= (__CKD__); \ + (__HANDLE__)->Init.ClockDivision = (__CKD__); \ + } while (0) + +/** + * @brief Get the TIM Clock Division value on runtime. + * @param __HANDLE__ TIM handle. + * @retval The clock division can be one of the following values: + * @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT + * @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT + * @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT + */ +#define __HAL_TIM_GET_CLOCKDIVISION(__HANDLE__) \ + ((__HANDLE__)->Instance->CR1 & TIM_CR1_CKD) + +/** + * @brief Set the TIM Input Capture prescaler on runtime without calling another time + * HAL_TIM_IC_ConfigChannel() function. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __ICPSC__ specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +#define __HAL_TIM_SET_ICPRESCALER(__HANDLE__, __CHANNEL__, __ICPSC__) \ + do \ + { \ + TIM_RESET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__), (__ICPSC__)); \ + } while (0) + +/** + * @brief Get the TIM Input Capture prescaler on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get input capture 1 prescaler value + * @arg TIM_CHANNEL_2: get input capture 2 prescaler value + * @arg TIM_CHANNEL_3: get input capture 3 prescaler value + * @arg TIM_CHANNEL_4: get input capture 4 prescaler value + * @retval The input capture prescaler can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + */ +#define __HAL_TIM_GET_ICPRESCALER(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC1PSC) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? (((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC2PSC) >> 8U) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC3PSC) \ + : (((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8U) + +/** + * @brief Set the TIM Capture Compare Register value on runtime without calling another + * time ConfigChannel function. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __COMPARE__ specifies the Capture Compare register new value. + * @retval None + */ +#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) \ + : ((__HANDLE__)->Instance->CCR4 = (__COMPARE__))) + +/** + * @brief Get the TIM Capture Compare Register value on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channel associated with the capture compare register + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get capture/compare 1 register value + * @arg TIM_CHANNEL_2: get capture/compare 2 register value + * @arg TIM_CHANNEL_3: get capture/compare 3 register value + * @arg TIM_CHANNEL_4: get capture/compare 4 register value + * @retval 16-bit or 32-bit value of the capture/compare register (TIMx_CCRy) + */ +#define __HAL_TIM_GET_COMPARE(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3) \ + : ((__HANDLE__)->Instance->CCR4)) + +/** + * @brief Set the TIM Output compare preload. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval None + */ +#define __HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1PE) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2PE) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3PE) \ + : ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4PE)) + +/** + * @brief Reset the TIM Output compare preload. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval None + */ +#define __HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1PE) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2PE) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3PE) \ + : ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4PE)) + +/** + * @brief Enable fast mode for a given channel. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @note When fast mode is enabled an active edge on the trigger input acts + * like a compare match on CCx output. Delay to sample the trigger + * input and to activate CCx output is reduced to 3 clock cycles. + * @note Fast mode acts only if the channel is configured in PWM1 or PWM2 mode. + * @retval None + */ +#define __HAL_TIM_ENABLE_OCxFAST(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1FE) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2FE) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3FE) \ + : ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4FE)) + +/** + * @brief Disable fast mode for a given channel. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @note When fast mode is disabled CCx output behaves normally depending + * on counter and CCRx values even when the trigger is ON. The minimum + * delay to activate CCx output when an active edge occurs on the + * trigger input is 5 clock cycles. + * @retval None + */ +#define __HAL_TIM_DISABLE_OCxFAST(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE) \ + : ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE)) + +/** + * @brief Set the Update Request Source (URS) bit of the TIMx_CR1 register. + * @param __HANDLE__ TIM handle. + * @note When the URS bit of the TIMx_CR1 register is set, only counter + * overflow/underflow generates an update interrupt or DMA request (if + * enabled) + * @retval None + */ +#define __HAL_TIM_URS_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= TIM_CR1_URS) + +/** + * @brief Reset the Update Request Source (URS) bit of the TIMx_CR1 register. + * @param __HANDLE__ TIM handle. + * @note When the URS bit of the TIMx_CR1 register is reset, any of the + * following events generate an update interrupt or DMA request (if + * enabled): + * _ Counter overflow underflow + * _ Setting the UG bit + * _ Update generation through the slave mode controller + * @retval None + */ +#define __HAL_TIM_URS_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~TIM_CR1_URS) + +/** + * @brief Set the TIM Capture x input polarity on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __POLARITY__ Polarity for TIx source + * @arg TIM_INPUTCHANNELPOLARITY_RISING: Rising Edge + * @arg TIM_INPUTCHANNELPOLARITY_FALLING: Falling Edge + * @arg TIM_INPUTCHANNELPOLARITY_BOTHEDGE: Rising and Falling Edge + * @retval None + */ +#define __HAL_TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + do \ + { \ + TIM_RESET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__), (__POLARITY__)); \ + } while (0) + +/** @brief Select the Capture/compare DMA request source. + * @param __HANDLE__ specifies the TIM Handle. + * @param __CCDMA__ specifies Capture/compare DMA request source + * This parameter can be one of the following values: + * @arg TIM_CCDMAREQUEST_CC: CCx DMA request generated on Capture/Compare event + * @arg TIM_CCDMAREQUEST_UPDATE: CCx DMA request generated on Update event + * @retval None + */ +#define __HAL_TIM_SELECT_CCDMAREQUEST(__HANDLE__, __CCDMA__) \ + MODIFY_REG((__HANDLE__)->Instance->CR2, TIM_CR2_CCDS, (__CCDMA__)) + +/** + * @} + */ +/* End of exported macros ----------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIM_Private_Constants TIM Private Constants + * @{ + */ +/* The counter of a timer instance is disabled only if all the CCx and CCxN + channels have been disabled */ +#define TIM_CCER_CCxE_MASK \ + ((uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E)) +#define TIM_CCER_CCxNE_MASK ((uint32_t)(TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) +/** + * @} + */ +/* End of private constants --------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_Private_Macros TIM Private Macros + * @{ + */ +#define IS_TIM_CLEARINPUT_SOURCE(__MODE__) \ + (((__MODE__) == TIM_CLEARINPUTSOURCE_NONE) || \ + ((__MODE__) == TIM_CLEARINPUTSOURCE_ETR) || \ + ((__MODE__) == TIM_CLEARINPUTSOURCE_OCREFCLR)) + +#define IS_TIM_DMA_BASE(__BASE__) \ + (((__BASE__) == TIM_DMABASE_CR1) || ((__BASE__) == TIM_DMABASE_CR2) || \ + ((__BASE__) == TIM_DMABASE_SMCR) || ((__BASE__) == TIM_DMABASE_DIER) || \ + ((__BASE__) == TIM_DMABASE_SR) || ((__BASE__) == TIM_DMABASE_EGR) || \ + ((__BASE__) == TIM_DMABASE_CCMR1) || ((__BASE__) == TIM_DMABASE_CCMR2) || \ + ((__BASE__) == TIM_DMABASE_CCER) || ((__BASE__) == TIM_DMABASE_CNT) || \ + ((__BASE__) == TIM_DMABASE_PSC) || ((__BASE__) == TIM_DMABASE_ARR) || \ + ((__BASE__) == TIM_DMABASE_RCR) || ((__BASE__) == TIM_DMABASE_CCR1) || \ + ((__BASE__) == TIM_DMABASE_CCR2) || ((__BASE__) == TIM_DMABASE_CCR3) || \ + ((__BASE__) == TIM_DMABASE_CCR4) || ((__BASE__) == TIM_DMABASE_BDTR)) + +#define IS_TIM_EVENT_SOURCE(__SOURCE__) \ + ((((__SOURCE__)&0xFFFFFF00U) == 0x00000000U) && ((__SOURCE__) != 0x00000000U)) + +#define IS_TIM_COUNTER_MODE(__MODE__) \ + (((__MODE__) == TIM_COUNTERMODE_UP) || ((__MODE__) == TIM_COUNTERMODE_DOWN) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED1) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED2) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED3)) + +#define IS_TIM_CLOCKDIVISION_DIV(__DIV__) \ + (((__DIV__) == TIM_CLOCKDIVISION_DIV1) || ((__DIV__) == TIM_CLOCKDIVISION_DIV2) || \ + ((__DIV__) == TIM_CLOCKDIVISION_DIV4)) + +#define IS_TIM_AUTORELOAD_PRELOAD(PRELOAD) \ + (((PRELOAD) == TIM_AUTORELOAD_PRELOAD_DISABLE) || \ + ((PRELOAD) == TIM_AUTORELOAD_PRELOAD_ENABLE)) + +#define IS_TIM_FAST_STATE(__STATE__) \ + (((__STATE__) == TIM_OCFAST_DISABLE) || ((__STATE__) == TIM_OCFAST_ENABLE)) + +#define IS_TIM_OC_POLARITY(__POLARITY__) \ + (((__POLARITY__) == TIM_OCPOLARITY_HIGH) || ((__POLARITY__) == TIM_OCPOLARITY_LOW)) + +#define IS_TIM_OCN_POLARITY(__POLARITY__) \ + (((__POLARITY__) == TIM_OCNPOLARITY_HIGH) || ((__POLARITY__) == TIM_OCNPOLARITY_LOW)) + +#define IS_TIM_OCIDLE_STATE(__STATE__) \ + (((__STATE__) == TIM_OCIDLESTATE_SET) || ((__STATE__) == TIM_OCIDLESTATE_RESET)) + +#define IS_TIM_OCNIDLE_STATE(__STATE__) \ + (((__STATE__) == TIM_OCNIDLESTATE_SET) || ((__STATE__) == TIM_OCNIDLESTATE_RESET)) + +#define IS_TIM_ENCODERINPUT_POLARITY(__POLARITY__) \ + (((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_FALLING)) + +#define IS_TIM_IC_POLARITY(__POLARITY__) \ + (((__POLARITY__) == TIM_ICPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_ICPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_ICPOLARITY_BOTHEDGE)) + +#define IS_TIM_IC_SELECTION(__SELECTION__) \ + (((__SELECTION__) == TIM_ICSELECTION_DIRECTTI) || \ + ((__SELECTION__) == TIM_ICSELECTION_INDIRECTTI) || \ + ((__SELECTION__) == TIM_ICSELECTION_TRC)) + +#define IS_TIM_IC_PRESCALER(__PRESCALER__) \ + (((__PRESCALER__) == TIM_ICPSC_DIV1) || ((__PRESCALER__) == TIM_ICPSC_DIV2) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV4) || ((__PRESCALER__) == TIM_ICPSC_DIV8)) + +#define IS_TIM_OPM_MODE(__MODE__) \ + (((__MODE__) == TIM_OPMODE_SINGLE) || ((__MODE__) == TIM_OPMODE_REPETITIVE)) + +#define IS_TIM_ENCODER_MODE(__MODE__) \ + (((__MODE__) == TIM_ENCODERMODE_TI1) || ((__MODE__) == TIM_ENCODERMODE_TI2) || \ + ((__MODE__) == TIM_ENCODERMODE_TI12)) + +#define IS_TIM_DMA_SOURCE(__SOURCE__) \ + ((((__SOURCE__)&0xFFFF80FFU) == 0x00000000U) && ((__SOURCE__) != 0x00000000U)) + +#define IS_TIM_CHANNELS(__CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) || ((__CHANNEL__) == TIM_CHANNEL_2) || \ + ((__CHANNEL__) == TIM_CHANNEL_3) || ((__CHANNEL__) == TIM_CHANNEL_4) || \ + ((__CHANNEL__) == TIM_CHANNEL_ALL)) + +#define IS_TIM_OPM_CHANNELS(__CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) || ((__CHANNEL__) == TIM_CHANNEL_2)) + +#define IS_TIM_PERIOD(__HANDLE__, __PERIOD__) \ + ((IS_TIM_32B_COUNTER_INSTANCE(((__HANDLE__)->Instance)) == 0U) \ + ? (((__PERIOD__) > 0U) && ((__PERIOD__) <= 0x0000FFFFU)) \ + : ((__PERIOD__) > 0U)) + +#define IS_TIM_COMPLEMENTARY_CHANNELS(__CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) || ((__CHANNEL__) == TIM_CHANNEL_2) || \ + ((__CHANNEL__) == TIM_CHANNEL_3)) + +#define IS_TIM_CLOCKSOURCE(__CLOCK__) \ + (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3)) + +#define IS_TIM_CLOCKPOLARITY(__POLARITY__) \ + (((__POLARITY__) == TIM_CLOCKPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_NONINVERTED) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_BOTHEDGE)) + +#define IS_TIM_CLOCKPRESCALER(__PRESCALER__) \ + (((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV8)) + +#define IS_TIM_CLOCKFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_CLEARINPUT_POLARITY(__POLARITY__) \ + (((__POLARITY__) == TIM_CLEARINPUTPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_CLEARINPUTPOLARITY_NONINVERTED)) + +#define IS_TIM_CLEARINPUT_PRESCALER(__PRESCALER__) \ + (((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV8)) + +#define IS_TIM_CLEARINPUT_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_OSSR_STATE(__STATE__) \ + (((__STATE__) == TIM_OSSR_ENABLE) || ((__STATE__) == TIM_OSSR_DISABLE)) + +#define IS_TIM_OSSI_STATE(__STATE__) \ + (((__STATE__) == TIM_OSSI_ENABLE) || ((__STATE__) == TIM_OSSI_DISABLE)) + +#define IS_TIM_LOCK_LEVEL(__LEVEL__) \ + (((__LEVEL__) == TIM_LOCKLEVEL_OFF) || ((__LEVEL__) == TIM_LOCKLEVEL_1) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_2) || ((__LEVEL__) == TIM_LOCKLEVEL_3)) + +#define IS_TIM_BREAK_FILTER(__BRKFILTER__) ((__BRKFILTER__) <= 0xFUL) + + +#define IS_TIM_BREAK_STATE(__STATE__) \ + (((__STATE__) == TIM_BREAK_ENABLE) || ((__STATE__) == TIM_BREAK_DISABLE)) + +#define IS_TIM_BREAK_POLARITY(__POLARITY__) \ + (((__POLARITY__) == TIM_BREAKPOLARITY_LOW) || \ + ((__POLARITY__) == TIM_BREAKPOLARITY_HIGH)) + +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(__STATE__) \ + (((__STATE__) == TIM_AUTOMATICOUTPUT_ENABLE) || \ + ((__STATE__) == TIM_AUTOMATICOUTPUT_DISABLE)) + +#define IS_TIM_TRGO_SOURCE(__SOURCE__) \ + (((__SOURCE__) == TIM_TRGO_RESET) || ((__SOURCE__) == TIM_TRGO_ENABLE) || \ + ((__SOURCE__) == TIM_TRGO_UPDATE) || ((__SOURCE__) == TIM_TRGO_OC1) || \ + ((__SOURCE__) == TIM_TRGO_OC1REF) || ((__SOURCE__) == TIM_TRGO_OC2REF) || \ + ((__SOURCE__) == TIM_TRGO_OC3REF) || ((__SOURCE__) == TIM_TRGO_OC4REF)) + +#define IS_TIM_MSM_STATE(__STATE__) \ + (((__STATE__) == TIM_MASTERSLAVEMODE_ENABLE) || \ + ((__STATE__) == TIM_MASTERSLAVEMODE_DISABLE)) + +#define IS_TIM_SLAVE_MODE(__MODE__) \ + (((__MODE__) == TIM_SLAVEMODE_DISABLE) || ((__MODE__) == TIM_SLAVEMODE_RESET) || \ + ((__MODE__) == TIM_SLAVEMODE_GATED) || ((__MODE__) == TIM_SLAVEMODE_TRIGGER) || \ + ((__MODE__) == TIM_SLAVEMODE_EXTERNAL1)) + +#define IS_TIM_PWM_MODE(__MODE__) \ + (((__MODE__) == TIM_OCMODE_PWM1) || ((__MODE__) == TIM_OCMODE_PWM2)) + +#define IS_TIM_OC_MODE(__MODE__) \ + (((__MODE__) == TIM_OCMODE_TIMING) || ((__MODE__) == TIM_OCMODE_ACTIVE) || \ + ((__MODE__) == TIM_OCMODE_INACTIVE) || ((__MODE__) == TIM_OCMODE_TOGGLE) || \ + ((__MODE__) == TIM_OCMODE_FORCED_ACTIVE) || \ + ((__MODE__) == TIM_OCMODE_FORCED_INACTIVE)) + +#define IS_TIM_TRIGGER_SELECTION(__SELECTION__) \ + (((__SELECTION__) == TIM_TS_ITR0) || ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || ((__SELECTION__) == TIM_TS_ETRF)) + +#define IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(__SELECTION__) \ + (((__SELECTION__) == TIM_TS_ITR0) || ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_NONE)) + +#define IS_TIM_TRIGGERPOLARITY(__POLARITY__) \ + (((__POLARITY__) == TIM_TRIGGERPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_NONINVERTED) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_BOTHEDGE)) + +#define IS_TIM_TRIGGERPRESCALER(__PRESCALER__) \ + (((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV8)) + +#define IS_TIM_TRIGGERFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_TI1SELECTION(__TI1SELECTION__) \ + (((__TI1SELECTION__) == TIM_TI1SELECTION_CH1) || \ + ((__TI1SELECTION__) == TIM_TI1SELECTION_XORCOMBINATION)) + +#define IS_TIM_DMA_LENGTH(__LENGTH__) \ + (((__LENGTH__) == TIM_DMABURSTLENGTH_1TRANSFER) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_2TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_3TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_4TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_5TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_6TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_7TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_8TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_9TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_10TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_11TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_12TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_13TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_14TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_15TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_16TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_17TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_18TRANSFERS)) + +#define IS_TIM_DMA_DATA_LENGTH(LENGTH) (((LENGTH) >= 0x1U) && ((LENGTH) < 0x10000U)) + +#define IS_TIM_IC_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_DEADTIME(__DEADTIME__) ((__DEADTIME__) <= 0xFFU) + +#define IS_TIM_SLAVEMODE_TRIGGER_ENABLED(__TRIGGER__) \ + ((__TRIGGER__) == TIM_SLAVEMODE_TRIGGER) + +#define TIM_SET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__, __ICPSC__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= (__ICPSC__)) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->Instance->CCMR1 |= ((__ICPSC__) << 8U)) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCMR2 |= (__ICPSC__)) \ + : ((__HANDLE__)->Instance->CCMR2 |= ((__ICPSC__) << 8U))) + +#define TIM_RESET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC) \ + : ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC)) + +#define TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER |= (__POLARITY__)) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 4U)) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 8U)) \ + : ((__HANDLE__)->Instance->CCER |= (((__POLARITY__) << 12U)))) + +#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP)) \ + : ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP))) + +#define TIM_CHANNEL_STATE_GET(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? (__HANDLE__)->ChannelState[0] \ + : ((__CHANNEL__) == TIM_CHANNEL_2) ? (__HANDLE__)->ChannelState[1] \ + : ((__CHANNEL__) == TIM_CHANNEL_3) ? (__HANDLE__)->ChannelState[2] \ + : (__HANDLE__)->ChannelState[3]) + +#define TIM_CHANNEL_STATE_SET(__HANDLE__, __CHANNEL__, __CHANNEL_STATE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->ChannelState[0] = (__CHANNEL_STATE__)) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->ChannelState[1] = (__CHANNEL_STATE__)) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->ChannelState[2] = (__CHANNEL_STATE__)) \ + : ((__HANDLE__)->ChannelState[3] = (__CHANNEL_STATE__))) + +#define TIM_CHANNEL_STATE_SET_ALL(__HANDLE__, __CHANNEL_STATE__) \ + do \ + { \ + (__HANDLE__)->ChannelState[0] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[1] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[2] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[3] = (__CHANNEL_STATE__); \ + } while (0) + +#define TIM_CHANNEL_N_STATE_GET(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? (__HANDLE__)->ChannelNState[0] \ + : ((__CHANNEL__) == TIM_CHANNEL_2) ? (__HANDLE__)->ChannelNState[1] \ + : ((__CHANNEL__) == TIM_CHANNEL_3) ? (__HANDLE__)->ChannelNState[2] \ + : (__HANDLE__)->ChannelNState[3]) + +#define TIM_CHANNEL_N_STATE_SET(__HANDLE__, __CHANNEL__, __CHANNEL_STATE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) \ + ? ((__HANDLE__)->ChannelNState[0] = (__CHANNEL_STATE__)) \ + : ((__CHANNEL__) == TIM_CHANNEL_2) \ + ? ((__HANDLE__)->ChannelNState[1] = (__CHANNEL_STATE__)) \ + : ((__CHANNEL__) == TIM_CHANNEL_3) \ + ? ((__HANDLE__)->ChannelNState[2] = (__CHANNEL_STATE__)) \ + : ((__HANDLE__)->ChannelNState[3] = (__CHANNEL_STATE__))) + +#define TIM_CHANNEL_N_STATE_SET_ALL(__HANDLE__, __CHANNEL_STATE__) \ + do \ + { \ + (__HANDLE__)->ChannelNState[0] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[1] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[2] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[3] = (__CHANNEL_STATE__); \ + } while (0) + +/** + * @} + */ +/* End of private macros -----------------------------------------------------*/ + +/* Include TIM HAL Extended module */ +#include "stm32f0xx_hal_tim_ex.h" + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup TIM_Exported_Functions TIM Exported Functions + * @{ + */ + + /** @addtogroup TIM_Exported_Functions_Group1 TIM Time Base functions + * @brief Time Base functions + * @{ + */ + /* Time Base functions ********************************************************/ + HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim); + HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim); + void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim); + void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim); + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim); + HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim); + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim); + HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim); + /* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, + const uint32_t *pData, uint16_t Length); + HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim); + /** + * @} + */ + + /** @addtogroup TIM_Exported_Functions_Group2 TIM Output Compare functions + * @brief TIM Output Compare functions + * @{ + */ + /* Timer Output Compare functions *********************************************/ + HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim); + HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim); + void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim); + void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim); + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, + const uint32_t *pData, uint16_t Length); + HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + /** + * @} + */ + + /** @addtogroup TIM_Exported_Functions_Group3 TIM PWM functions + * @brief TIM PWM functions + * @{ + */ + /* Timer PWM functions ********************************************************/ + HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim); + HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim); + void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim); + void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim); + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, + const uint32_t *pData, uint16_t Length); + HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + /** + * @} + */ + + /** @addtogroup TIM_Exported_Functions_Group4 TIM Input Capture functions + * @brief TIM Input Capture functions + * @{ + */ + /* Timer Input Capture functions **********************************************/ + HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim); + HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim); + void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim); + void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim); + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, + uint32_t *pData, uint16_t Length); + HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + /** + * @} + */ + + /** @addtogroup TIM_Exported_Functions_Group5 TIM One Pulse functions + * @brief TIM One Pulse functions + * @{ + */ + /* Timer One Pulse functions **************************************************/ + HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, + uint32_t OnePulseMode); + HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim); + void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim); + void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim); + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, + uint32_t OutputChannel); + HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, + uint32_t OutputChannel); + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, + uint32_t OutputChannel); + HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, + uint32_t OutputChannel); + /** + * @} + */ + + /** @addtogroup TIM_Exported_Functions_Group6 TIM Encoder functions + * @brief TIM Encoder functions + * @{ + */ + /* Timer Encoder functions ****************************************************/ + HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, + const TIM_Encoder_InitTypeDef *sConfig); + HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim); + void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim); + void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim); + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, + uint32_t *pData1, uint32_t *pData2, + uint16_t Length); + HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + /** + * @} + */ + + /** @addtogroup TIM_Exported_Functions_Group7 TIM IRQ handler management + * @brief IRQ handler management + * @{ + */ + /* Interrupt Handler functions ***********************************************/ + void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim); + /** + * @} + */ + + /** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ + /* Control functions *********************************************************/ + HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, + const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, + const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, + const TIM_IC_InitTypeDef *sConfig, + uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, + TIM_OnePulse_InitTypeDef *sConfig, + uint32_t OutputChannel, + uint32_t InputChannel); + HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear( + TIM_HandleTypeDef *htim, const TIM_ClearInputConfigTypeDef *sClearInputConfig, + uint32_t Channel); + HAL_StatusTypeDef HAL_TIM_ConfigClockSource( + TIM_HandleTypeDef *htim, const TIM_ClockConfigTypeDef *sClockSourceConfig); + HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, + uint32_t TI1_Selection); + HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro( + TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig); + HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT( + TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig); + HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, + uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, + const uint32_t *BurstBuffer, + uint32_t BurstLength); + HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart( + TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, + const uint32_t *BurstBuffer, uint32_t BurstLength, uint32_t DataLength); + HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, + uint32_t BurstRequestSrc); + HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, + uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, + uint32_t *BurstBuffer, + uint32_t BurstLength); + HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart( + TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, + uint32_t *BurstBuffer, uint32_t BurstLength, uint32_t DataLength); + HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, + uint32_t BurstRequestSrc); + HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, + uint32_t EventSource); + uint32_t HAL_TIM_ReadCapturedValue(const TIM_HandleTypeDef *htim, uint32_t Channel); + /** + * @} + */ + + /** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions + * @brief TIM Callbacks functions + * @{ + */ + /* Callback in non blocking modes (Interrupt and DMA) *************************/ + void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim); + void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, + HAL_TIM_CallbackIDTypeDef CallbackID, + pTIM_CallbackTypeDef pCallback); + HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, + HAL_TIM_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /** + * @} + */ + + /** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions + * @brief Peripheral State functions + * @{ + */ + /* Peripheral State functions ************************************************/ + HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(const TIM_HandleTypeDef *htim); + HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(const TIM_HandleTypeDef *htim); + HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(const TIM_HandleTypeDef *htim); + HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(const TIM_HandleTypeDef *htim); + HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(const TIM_HandleTypeDef *htim); + HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(const TIM_HandleTypeDef *htim); + + /* Peripheral Channel state functions + * ************************************************/ + HAL_TIM_ActiveChannel HAL_TIM_GetActiveChannel(const TIM_HandleTypeDef *htim); + HAL_TIM_ChannelStateTypeDef HAL_TIM_GetChannelState(const TIM_HandleTypeDef *htim, + uint32_t Channel); + HAL_TIM_DMABurstStateTypeDef HAL_TIM_DMABurstState(const TIM_HandleTypeDef *htim); + /** + * @} + */ + + /** + * @} + */ + /* End of exported functions -------------------------------------------------*/ + + /* Private functions----------------------------------------------------------*/ + /** @defgroup TIM_Private_Functions TIM Private Functions + * @{ + */ + void TIM_Base_SetConfig(TIM_TypeDef *TIMx, const TIM_Base_InitTypeDef *Structure); + void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, + uint32_t TIM_ICSelection, uint32_t TIM_ICFilter); + void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); + void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter); + + void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma); + void TIM_DMAError(DMA_HandleTypeDef *hdma); + void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma); + void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma); + void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + void TIM_ResetCallback(TIM_HandleTypeDef *htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /** + * @} + */ + /* End of private functions --------------------------------------------------*/ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_TIM_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_hal_tim_ex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_tim_ex.h new file mode 100644 index 0000000000..9facef9f84 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_hal_tim_ex.h @@ -0,0 +1,287 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_tim_ex.h + * @author MCD Application Team + * @brief Header file of TIM HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_TIM_EX_H +#define STM32F0xx_HAL_TIM_EX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + + /** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + /** @addtogroup TIMEx + * @{ + */ + + /* Exported types ------------------------------------------------------------*/ + /** @defgroup TIMEx_Exported_Types TIM Extended Exported Types + * @{ + */ + + /** + * @brief TIM Hall sensor Configuration Structure definition + */ + + typedef struct + { + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref + TIM_Input_Capture_Polarity */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref + TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and + Max_Data = 0xF */ + + uint32_t + Commutation_Delay; /*!< Specifies the pulse value to be loaded into the + Capture Compare Register. This parameter can be a number + between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + } TIM_HallSensor_InitTypeDef; +/** + * @} + */ +/* End of exported types -----------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Constants TIM Extended Exported Constants + * @{ + */ + +/** @defgroup TIMEx_Remap TIM Extended Remapping + * @{ + */ +#define TIM_TIM14_GPIO (0x00000000U) /*!< TIM14 TI1 is connected to GPIO */ +#define TIM_TIM14_RTC (0x00000001U) /*!< TIM14 TI1 is connected to RTC_clock */ +#define TIM_TIM14_HSE (0x00000002U) /*!< TIM14 TI1 is connected to HSE/32U */ +#define TIM_TIM14_MCO (0x00000003U) /*!< TIM14 TI1 is connected to MCO */ +/** + * @} + */ + +/** + * @} + */ +/* End of exported constants -------------------------------------------------*/ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Macros TIM Extended Exported Macros + * @{ + */ + +/** + * @} + */ +/* End of exported macro -----------------------------------------------------*/ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Macros TIM Extended Private Macros + * @{ + */ +#define IS_TIM_REMAP(__INSTANCE__, __REMAP__) \ + (((__INSTANCE__) == TIM14) && (((__REMAP__)&0xFFFFFFFCU) == 0x00000000U)) + + /** + * @} + */ + /* End of private macro ------------------------------------------------------*/ + + /* Exported functions --------------------------------------------------------*/ + /** @addtogroup TIMEx_Exported_Functions TIM Extended Exported Functions + * @{ + */ + + /** @addtogroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions + * @brief Timer Hall Sensor functions + * @{ + */ + /* Timer Hall Sensor functions **********************************************/ + HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init( + TIM_HandleTypeDef *htim, const TIM_HallSensor_InitTypeDef *sConfig); + HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim); + + void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim); + void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim); + + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim); + HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim); + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim); + HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim); + /* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, + uint32_t *pData, uint16_t Length); + HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim); + /** + * @} + */ + + /** @addtogroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output + * Compare functions + * @brief Timer Complementary Output Compare functions + * @{ + */ + /* Timer Complementary Output Compare functions *****************************/ + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + + /* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, + const uint32_t *pData, uint16_t Length); + HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + /** + * @} + */ + + /** @addtogroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM + * functions + * @brief Timer Complementary PWM functions + * @{ + */ + /* Timer Complementary PWM functions ****************************************/ + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + /* Non-Blocking mode: DMA */ + HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, + const uint32_t *pData, uint16_t Length); + HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + /** + * @} + */ + + /** @addtogroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse + * functions + * @brief Timer Complementary One Pulse functions + * @{ + */ + /* Timer Complementary One Pulse functions **********************************/ + /* Blocking mode: Polling */ + HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, + uint32_t OutputChannel); + HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, + uint32_t OutputChannel); + + /* Non-Blocking mode: Interrupt */ + HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, + uint32_t OutputChannel); + HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, + uint32_t OutputChannel); + /** + * @} + */ + + /** @addtogroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ + /* Extended Control functions ************************************************/ + HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, + uint32_t InputTrigger, + uint32_t CommutationSource); + HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, + uint32_t InputTrigger, + uint32_t CommutationSource); + HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, + uint32_t InputTrigger, + uint32_t CommutationSource); + HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization( + TIM_HandleTypeDef *htim, const TIM_MasterConfigTypeDef *sMasterConfig); + HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime( + TIM_HandleTypeDef *htim, + const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig); + HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap); + /** + * @} + */ + + /** @addtogroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions + * @brief Extended Callbacks functions + * @{ + */ + /* Extended Callback **********************************************************/ + void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim); + void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim); + void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim); + /** + * @} + */ + + /** @addtogroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions + * @brief Extended Peripheral State functions + * @{ + */ + /* Extended Peripheral State functions ***************************************/ + HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim); + HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim, + uint32_t ChannelN); + /** + * @} + */ + + /** + * @} + */ + /* End of exported functions -------------------------------------------------*/ + + /* Private functions----------------------------------------------------------*/ + /** @addtogroup TIMEx_Private_Functions TIM Extended Private Functions + * @{ + */ + void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma); + void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma); + /** + * @} + */ + /* End of private functions --------------------------------------------------*/ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32F0xx_HAL_TIM_EX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_adc.c b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_adc.c new file mode 100644 index 0000000000..aeed8991ae --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_adc.c @@ -0,0 +1,515 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_adc.c + * @author MCD Application Team + * @brief ADC LL module driver + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_ll_adc.h" + +#include "stm32f0xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif + +/** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(ADC1) + +/** @addtogroup ADC_LL ADC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup ADC_LL_Private_Constants + * @{ + */ + +/* Definitions of ADC hardware constraints delays */ +/* Note: Only ADC IP HW delays are defined in ADC LL driver driver, */ +/* not timeout values: */ +/* Timeout values for ADC operations are dependent to device clock */ +/* configuration (system clock versus ADC clock), */ +/* and therefore must be defined in user application. */ +/* Refer to @ref ADC_LL_EC_HW_DELAYS for description of ADC timeout */ +/* values definition. */ +/* Note: ADC timeout values are defined here in CPU cycles to be independent */ +/* of device clock setting. */ +/* In user application, ADC timeout values should be defined with */ +/* temporal values, in function of device clock settings. */ +/* Highest ratio CPU clock frequency vs ADC clock frequency: */ +/* - ADC clock from synchronous clock with AHB prescaler 512, */ +/* APB prescaler 16, ADC prescaler 4. */ +/* - ADC clock from asynchronous clock (HSI) with prescaler 1, */ +/* with highest ratio CPU clock frequency vs HSI clock frequency: */ +/* CPU clock frequency max 48MHz, HSI frequency 14MHz: ratio 4. */ +/* Unit: CPU cycles. */ +#define ADC_CLOCK_RATIO_VS_CPU_HIGHEST ((uint32_t)512U * 16U * 4U) +#define ADC_TIMEOUT_DISABLE_CPU_CYCLES (ADC_CLOCK_RATIO_VS_CPU_HIGHEST * 1U) +#define ADC_TIMEOUT_STOP_CONVERSION_CPU_CYCLES (ADC_CLOCK_RATIO_VS_CPU_HIGHEST * 1U) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/** @addtogroup ADC_LL_Private_Macros + * @{ + */ + +/* Check of parameters for configuration of ADC hierarchical scope: */ +/* common to several ADC instances. */ +/* Check of parameters for configuration of ADC hierarchical scope: */ +/* ADC instance. */ +#define IS_LL_ADC_CLOCK(__CLOCK__) \ + (((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV4) || \ + ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV2) || \ + ((__CLOCK__) == LL_ADC_CLOCK_ASYNC)) + +#define IS_LL_ADC_RESOLUTION(__RESOLUTION__) \ + (((__RESOLUTION__) == LL_ADC_RESOLUTION_12B) || \ + ((__RESOLUTION__) == LL_ADC_RESOLUTION_10B) || \ + ((__RESOLUTION__) == LL_ADC_RESOLUTION_8B) || \ + ((__RESOLUTION__) == LL_ADC_RESOLUTION_6B)) + +#define IS_LL_ADC_DATA_ALIGN(__DATA_ALIGN__) \ + (((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_RIGHT) || \ + ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_LEFT)) + +#define IS_LL_ADC_LOW_POWER(__LOW_POWER__) \ + (((__LOW_POWER__) == LL_ADC_LP_MODE_NONE) || \ + ((__LOW_POWER__) == LL_ADC_LP_AUTOWAIT) || \ + ((__LOW_POWER__) == LL_ADC_LP_AUTOPOWEROFF) || \ + ((__LOW_POWER__) == LL_ADC_LP_AUTOWAIT_AUTOPOWEROFF)) + +/* Check of parameters for configuration of ADC hierarchical scope: */ +/* ADC group regular */ +#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \ + (((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) || \ + ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO) || \ + ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH4) || \ + ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM2_TRGO) || \ + ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) || \ + ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM15_TRGO)) + +#define IS_LL_ADC_REG_CONTINUOUS_MODE(__REG_CONTINUOUS_MODE__) \ + (((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_SINGLE) || \ + ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_CONTINUOUS)) + +#define IS_LL_ADC_REG_DMA_TRANSFER(__REG_DMA_TRANSFER__) \ + (((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_NONE) || \ + ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_LIMITED) || \ + ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_UNLIMITED)) + +#define IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(__REG_OVR_DATA_BEHAVIOR__) \ + (((__REG_OVR_DATA_BEHAVIOR__) == LL_ADC_REG_OVR_DATA_PRESERVED) || \ + ((__REG_OVR_DATA_BEHAVIOR__) == LL_ADC_REG_OVR_DATA_OVERWRITTEN)) + +#define IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(__REG_SEQ_DISCONT_MODE__) \ + (((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_DISABLE) || \ + ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_1RANK)) + +/** + * @} + */ + + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADC_LL_Exported_Functions + * @{ + */ + +/** @addtogroup ADC_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize registers of all ADC instances belonging to + * the same ADC common instance to their default reset values. + * @note This function is performing a hard reset, using high level + * clock source RCC ADC reset. + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref + * __LL_ADC_COMMON_INSTANCE() ) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC common registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Check the parameters */ + assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON)); + + /* Force reset of ADC clock (core clock) */ + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_ADC1); + + /* Release reset of ADC clock (core clock) */ + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_ADC1); + + return SUCCESS; +} + + +/** + * @brief De-initialize registers of the selected ADC instance + * to their default reset values. + * @note To reset all ADC instances quickly (perform a hard reset), + * use function @ref LL_ADC_CommonDeInit(). + * @note If this functions returns error status, it means that ADC instance + * is in an unknown state. + * In this case, perform a hard reset using high level + * clock source RCC ADC reset. + * Refer to function @ref LL_ADC_CommonDeInit(). + * @param ADCx ADC instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC registers are de-initialized + * - ERROR: ADC registers are not de-initialized + */ +ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx) +{ + ErrorStatus status = SUCCESS; + + __IO uint32_t timeout_cpu_cycles = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(ADCx)); + + /* Disable ADC instance if not already disabled. */ + if (LL_ADC_IsEnabled(ADCx) == 1U) + { + /* Stop potential ADC conversion on going on ADC group regular. */ + if (LL_ADC_REG_IsConversionOngoing(ADCx) != 0U) + { + if (LL_ADC_REG_IsStopConversionOngoing(ADCx) == 0U) + { + LL_ADC_REG_StopConversion(ADCx); + } + } + + /* Wait for ADC conversions are effectively stopped */ + timeout_cpu_cycles = ADC_TIMEOUT_STOP_CONVERSION_CPU_CYCLES; + while (LL_ADC_REG_IsStopConversionOngoing(ADCx) == 1UL) + { + timeout_cpu_cycles--; + if (timeout_cpu_cycles == 0UL) + { + /* Time-out error */ + status = ERROR; + break; + } + } + } + + /* Disable the ADC instance */ + LL_ADC_Disable(ADCx); + + /* Wait for ADC instance is effectively disabled */ + timeout_cpu_cycles = ADC_TIMEOUT_DISABLE_CPU_CYCLES; + while (LL_ADC_IsDisableOngoing(ADCx) == 1U) + { + if (timeout_cpu_cycles-- == 0U) + { + /* Time-out error */ + status = ERROR; + } + } + + /* Check whether ADC state is compliant with expected state */ + if (READ_BIT(ADCx->CR, + (ADC_CR_ADSTP | ADC_CR_ADSTART | ADC_CR_ADDIS | ADC_CR_ADEN)) == 0U) + { + /* ========== Reset ADC registers ========== */ + /* Reset register IER */ + CLEAR_BIT(ADCx->IER, (LL_ADC_IT_ADRDY | LL_ADC_IT_EOC | LL_ADC_IT_EOS | + LL_ADC_IT_OVR | LL_ADC_IT_EOSMP | LL_ADC_IT_AWD1)); + + /* Reset register ISR */ + SET_BIT(ADCx->ISR, (LL_ADC_FLAG_ADRDY | LL_ADC_FLAG_EOC | LL_ADC_FLAG_EOS | + LL_ADC_FLAG_OVR | LL_ADC_FLAG_EOSMP | LL_ADC_FLAG_AWD1)); + + /* Reset register CR */ + /* Bits ADC_CR_ADCAL, ADC_CR_ADSTP, ADC_CR_ADSTART are in access mode */ + /* "read-set": no direct reset applicable. */ + /* No action on register CR */ + + /* Reset register CFGR1 */ + CLEAR_BIT(ADCx->CFGR1, (ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | + ADC_CFGR1_DISCEN | ADC_CFGR1_AUTOFF | ADC_CFGR1_WAIT | + ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD | ADC_CFGR1_EXTEN | + ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN | ADC_CFGR1_RES | + ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN)); + + /* Reset register CFGR2 */ + /* Note: Update of ADC clock mode is conditioned to ADC state disabled: */ + /* already done above. */ + CLEAR_BIT(ADCx->CFGR2, ADC_CFGR2_CKMODE); + + /* Reset register SMPR */ + CLEAR_BIT(ADCx->SMPR, ADC_SMPR_SMP); + + /* Reset register TR */ + MODIFY_REG(ADCx->TR, ADC_TR_HT | ADC_TR_LT, ADC_TR_HT); + + /* Reset register CHSELR */ +#if defined(ADC_CCR_VBATEN) + CLEAR_BIT(ADCx->CHSELR, + (ADC_CHSELR_CHSEL18 | ADC_CHSELR_CHSEL17 | ADC_CHSELR_CHSEL16 | + ADC_CHSELR_CHSEL15 | ADC_CHSELR_CHSEL14 | ADC_CHSELR_CHSEL13 | + ADC_CHSELR_CHSEL12 | ADC_CHSELR_CHSEL11 | ADC_CHSELR_CHSEL10 | + ADC_CHSELR_CHSEL9 | ADC_CHSELR_CHSEL8 | ADC_CHSELR_CHSEL7 | + ADC_CHSELR_CHSEL6 | ADC_CHSELR_CHSEL5 | ADC_CHSELR_CHSEL4 | + ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL2 | ADC_CHSELR_CHSEL1 | + ADC_CHSELR_CHSEL0)); +#else + CLEAR_BIT(ADCx->CHSELR, + (ADC_CHSELR_CHSEL17 | ADC_CHSELR_CHSEL16 | ADC_CHSELR_CHSEL15 | + ADC_CHSELR_CHSEL14 | ADC_CHSELR_CHSEL13 | ADC_CHSELR_CHSEL12 | + ADC_CHSELR_CHSEL11 | ADC_CHSELR_CHSEL10 | ADC_CHSELR_CHSEL9 | + ADC_CHSELR_CHSEL8 | ADC_CHSELR_CHSEL7 | ADC_CHSELR_CHSEL6 | + ADC_CHSELR_CHSEL5 | ADC_CHSELR_CHSEL4 | ADC_CHSELR_CHSEL3 | + ADC_CHSELR_CHSEL2 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL0)); +#endif + + /* Reset register DR */ + /* bits in access mode read only, no direct reset applicable */ + } + else + { + /* ADC instance is in an unknown state */ + /* Need to performing a hard reset of ADC instance, using high level */ + /* clock source RCC ADC reset. */ + /* Caution: On this STM32 series, if several ADC instances are available */ + /* on the selected device, RCC ADC reset will reset */ + /* all ADC instances belonging to the common ADC instance. */ + status = ERROR; + } + + return status; +} + +/** + * @brief Initialize some features of ADC instance. + * @note These parameters have an impact on ADC scope: ADC instance. + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Instance . + * @note The setting of these parameters by function @ref LL_ADC_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + * @note After using this function, some other features must be configured + * using LL unitary functions. + * The minimum configuration remaining to be done is: + * - Set ADC group regular sequencer: + * map channel on rank corresponding to channel number. + * Refer to function @ref LL_ADC_REG_SetSequencerChannels(); + * - Set ADC channel sampling time + * Refer to function LL_ADC_SetChannelSamplingTime(); + * @param ADCx ADC instance + * @param ADC_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC registers are initialized + * - ERROR: ADC registers are not initialized + */ +ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, LL_ADC_InitTypeDef *ADC_InitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(ADCx)); + + assert_param(IS_LL_ADC_CLOCK(ADC_InitStruct->Clock)); + assert_param(IS_LL_ADC_RESOLUTION(ADC_InitStruct->Resolution)); + assert_param(IS_LL_ADC_DATA_ALIGN(ADC_InitStruct->DataAlignment)); + assert_param(IS_LL_ADC_LOW_POWER(ADC_InitStruct->LowPowerMode)); + + /* Note: Hardware constraint (refer to description of this function): */ + /* ADC instance must be disabled. */ + if (LL_ADC_IsEnabled(ADCx) == 0U) + { + /* Configuration of ADC hierarchical scope: */ + /* - ADC instance */ + /* - Set ADC data resolution */ + /* - Set ADC conversion data alignment */ + /* - Set ADC low power mode */ + MODIFY_REG(ADCx->CFGR1, + ADC_CFGR1_RES | ADC_CFGR1_ALIGN | ADC_CFGR1_WAIT | ADC_CFGR1_AUTOFF, + ADC_InitStruct->Resolution | ADC_InitStruct->DataAlignment | + ADC_InitStruct->LowPowerMode); + + MODIFY_REG(ADCx->CFGR2, ADC_CFGR2_CKMODE, ADC_InitStruct->Clock); + } + else + { + /* Initialization error: ADC instance is not disabled. */ + status = ERROR; + } + return status; +} + +/** + * @brief Set each @ref LL_ADC_InitTypeDef field to default value. + * @param ADC_InitStruct Pointer to a @ref LL_ADC_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_ADC_StructInit(LL_ADC_InitTypeDef *ADC_InitStruct) +{ + /* Set ADC_InitStruct fields to default values */ + /* Set fields of ADC instance */ + ADC_InitStruct->Clock = LL_ADC_CLOCK_SYNC_PCLK_DIV2; + ADC_InitStruct->Resolution = LL_ADC_RESOLUTION_12B; + ADC_InitStruct->DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; + ADC_InitStruct->LowPowerMode = LL_ADC_LP_MODE_NONE; +} + +/** + * @brief Initialize some features of ADC group regular. + * @note These parameters have an impact on ADC scope: ADC group regular. + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Group_Regular + * (functions with prefix "REG"). + * @note The setting of these parameters by function @ref LL_ADC_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + * @note After using this function, other features must be configured + * using LL unitary functions. + * The minimum configuration remaining to be done is: + * - Set ADC group regular sequencer: + * map channel on rank corresponding to channel number. + * Refer to function @ref LL_ADC_REG_SetSequencerChannels(); + * - Set ADC channel sampling time + * Refer to function LL_ADC_SetChannelSamplingTime(); + * @param ADCx ADC instance + * @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: ADC registers are initialized + * - ERROR: ADC registers are not initialized + */ +ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(ADCx)); + assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource)); + assert_param( + IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont)); + assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode)); + assert_param(IS_LL_ADC_REG_DMA_TRANSFER(ADC_REG_InitStruct->DMATransfer)); + assert_param(IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(ADC_REG_InitStruct->Overrun)); + + /* ADC group regular continuous mode and discontinuous mode */ + /* can not be enabled simultenaeously */ + assert_param( + (ADC_REG_InitStruct->ContinuousMode == LL_ADC_REG_CONV_SINGLE) || + (ADC_REG_InitStruct->SequencerDiscont == LL_ADC_REG_SEQ_DISCONT_DISABLE)); + + /* Note: Hardware constraint (refer to description of this function): */ + /* ADC instance must be disabled. */ + if (LL_ADC_IsEnabled(ADCx) == 0U) + { + /* Configuration of ADC hierarchical scope: */ + /* - ADC group regular */ + /* - Set ADC group regular trigger source */ + /* - Set ADC group regular sequencer discontinuous mode */ + /* - Set ADC group regular continuous mode */ + /* - Set ADC group regular conversion data transfer: no transfer or */ + /* transfer by DMA, and DMA requests mode */ + /* - Set ADC group regular overrun behavior */ + /* Note: On this STM32 series, ADC trigger edge is set to value 0x0 by */ + /* setting of trigger source to SW start. */ + MODIFY_REG( + ADCx->CFGR1, + ADC_CFGR1_EXTSEL | ADC_CFGR1_EXTEN | ADC_CFGR1_DISCEN | ADC_CFGR1_CONT | + ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG | ADC_CFGR1_OVRMOD, + ADC_REG_InitStruct->TriggerSource | ADC_REG_InitStruct->SequencerDiscont | + ADC_REG_InitStruct->ContinuousMode | ADC_REG_InitStruct->DMATransfer | + ADC_REG_InitStruct->Overrun); + } + else + { + /* Initialization error: ADC instance is not disabled. */ + status = ERROR; + } + return status; +} + +/** + * @brief Set each @ref LL_ADC_REG_InitTypeDef field to default value. + * @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ +void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct) +{ + /* Set ADC_REG_InitStruct fields to default values */ + /* Set fields of ADC group regular */ + /* Note: On this STM32 series, ADC trigger edge is set to value 0x0 by */ + /* setting of trigger source to SW start. */ + ADC_REG_InitStruct->TriggerSource = LL_ADC_REG_TRIG_SOFTWARE; + ADC_REG_InitStruct->SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; + ADC_REG_InitStruct->ContinuousMode = LL_ADC_REG_CONV_SINGLE; + ADC_REG_InitStruct->DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE; + ADC_REG_InitStruct->Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ADC1 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_adc.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_adc.h new file mode 100644 index 0000000000..4874e7a314 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_adc.h @@ -0,0 +1,3817 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_adc.h + * @author MCD Application Team + * @brief Header file of ADC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_ADC_H +#define __STM32F0xx_LL_ADC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(ADC1) + +/** @defgroup ADC_LL ADC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup ADC_LL_Private_Constants ADC Private Constants + * @{ + */ + +/* Internal mask for ADC group regular trigger: */ +/* To select into literal LL_ADC_REG_TRIG_x the relevant bits for: */ +/* - regular trigger source */ +/* - regular trigger edge */ +#define ADC_REG_TRIG_EXT_EDGE_DEFAULT \ + (ADC_CFGR1_EXTEN_0) /* Trigger edge set to rising edge (default setting for \ + compatibility with some ADC on other STM32 families having \ + this setting set by HW default value) */ + +/* Mask containing trigger source masks for each of possible */ +/* trigger edge selection duplicated with shifts [0; 4; 8; 12] */ +/* corresponding to {SW start; ext trigger; ext trigger; ext trigger}. */ +#define ADC_REG_TRIG_SOURCE_MASK \ + (((LL_ADC_REG_TRIG_SOFTWARE & ADC_CFGR1_EXTSEL) << (4U * 0U)) | \ + ((ADC_CFGR1_EXTSEL) << (4U * 1U)) | ((ADC_CFGR1_EXTSEL) << (4U * 2U)) | \ + ((ADC_CFGR1_EXTSEL) << (4U * 3U))) + +/* Mask containing trigger edge masks for each of possible */ +/* trigger edge selection duplicated with shifts [0; 4; 8; 12] */ +/* corresponding to {SW start; ext trigger; ext trigger; ext trigger}. */ +#define ADC_REG_TRIG_EDGE_MASK \ + (((LL_ADC_REG_TRIG_SOFTWARE & ADC_CFGR1_EXTEN) << (4U * 0U)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) << (4U * 1U)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) << (4U * 2U)) | \ + ((ADC_REG_TRIG_EXT_EDGE_DEFAULT) << (4U * 3U))) + +/* Definition of ADC group regular trigger bits information. */ +#define ADC_REG_TRIG_EXTSEL_BITOFFSET_POS \ + (6U) /* Value equivalent to POSITION_VAL(ADC_CFGR1_EXTSEL) */ +#define ADC_REG_TRIG_EXTEN_BITOFFSET_POS \ + (10U) /* Value equivalent to POSITION_VAL(ADC_CFGR1_EXTEN) */ + + + +/* Internal mask for ADC channel: */ +/* To select into literal LL_ADC_CHANNEL_x the relevant bits for: */ +/* - channel identifier defined by number */ +/* - channel identifier defined by bitfield */ +/* - channel differentiation between external channels (connected to */ +/* GPIO pins) and internal channels (connected to internal paths) */ +#define ADC_CHANNEL_ID_NUMBER_MASK (ADC_CFGR1_AWDCH) +#define ADC_CHANNEL_ID_BITFIELD_MASK (ADC_CHSELR_CHSEL) +#define ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS \ + (26U) /* Value equivalent to POSITION_VAL(ADC_CHANNEL_ID_NUMBER_MASK) */ +#define ADC_CHANNEL_ID_MASK \ + (ADC_CHANNEL_ID_NUMBER_MASK | ADC_CHANNEL_ID_BITFIELD_MASK | \ + ADC_CHANNEL_ID_INTERNAL_CH_MASK) +/* Equivalent mask of ADC_CHANNEL_NUMBER_MASK aligned on register LSB (bit 0) */ +#define ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0 \ + (0x0000001FU) /* Equivalent to shift: (ADC_CHANNEL_NUMBER_MASK >> \ + POSITION_VAL(ADC_CHANNEL_NUMBER_MASK)) */ + +/* Channel differentiation between external and internal channels */ +#define ADC_CHANNEL_ID_INTERNAL_CH (0x80000000U) /* Marker of internal channel */ +#define ADC_CHANNEL_ID_INTERNAL_CH_MASK (ADC_CHANNEL_ID_INTERNAL_CH) + +/* Definition of channels ID number information to be inserted into */ +/* channels literals definition. */ +#define ADC_CHANNEL_0_NUMBER (0x00000000U) +#define ADC_CHANNEL_1_NUMBER (ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_2_NUMBER (ADC_CFGR1_AWDCH_1) +#define ADC_CHANNEL_3_NUMBER (ADC_CFGR1_AWDCH_1 | ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_4_NUMBER (ADC_CFGR1_AWDCH_2) +#define ADC_CHANNEL_5_NUMBER (ADC_CFGR1_AWDCH_2 | ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_6_NUMBER (ADC_CFGR1_AWDCH_2 | ADC_CFGR1_AWDCH_1) +#define ADC_CHANNEL_7_NUMBER (ADC_CFGR1_AWDCH_2 | ADC_CFGR1_AWDCH_1 | ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_8_NUMBER (ADC_CFGR1_AWDCH_3) +#define ADC_CHANNEL_9_NUMBER (ADC_CFGR1_AWDCH_3 | ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_10_NUMBER (ADC_CFGR1_AWDCH_3 | ADC_CFGR1_AWDCH_1) +#define ADC_CHANNEL_11_NUMBER (ADC_CFGR1_AWDCH_3 | ADC_CFGR1_AWDCH_1 | ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_12_NUMBER (ADC_CFGR1_AWDCH_3 | ADC_CFGR1_AWDCH_2) +#define ADC_CHANNEL_13_NUMBER (ADC_CFGR1_AWDCH_3 | ADC_CFGR1_AWDCH_2 | ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_14_NUMBER (ADC_CFGR1_AWDCH_3 | ADC_CFGR1_AWDCH_2 | ADC_CFGR1_AWDCH_1) +#define ADC_CHANNEL_15_NUMBER \ + (ADC_CFGR1_AWDCH_3 | ADC_CFGR1_AWDCH_2 | ADC_CFGR1_AWDCH_1 | ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_16_NUMBER (ADC_CFGR1_AWDCH_4) +#define ADC_CHANNEL_17_NUMBER (ADC_CFGR1_AWDCH_4 | ADC_CFGR1_AWDCH_0) +#define ADC_CHANNEL_18_NUMBER (ADC_CFGR1_AWDCH_4 | ADC_CFGR1_AWDCH_1) + +/* Definition of channels ID bitfield information to be inserted into */ +/* channels literals definition. */ +#define ADC_CHANNEL_0_BITFIELD (ADC_CHSELR_CHSEL0) +#define ADC_CHANNEL_1_BITFIELD (ADC_CHSELR_CHSEL1) +#define ADC_CHANNEL_2_BITFIELD (ADC_CHSELR_CHSEL2) +#define ADC_CHANNEL_3_BITFIELD (ADC_CHSELR_CHSEL3) +#define ADC_CHANNEL_4_BITFIELD (ADC_CHSELR_CHSEL4) +#define ADC_CHANNEL_5_BITFIELD (ADC_CHSELR_CHSEL5) +#define ADC_CHANNEL_6_BITFIELD (ADC_CHSELR_CHSEL6) +#define ADC_CHANNEL_7_BITFIELD (ADC_CHSELR_CHSEL7) +#define ADC_CHANNEL_8_BITFIELD (ADC_CHSELR_CHSEL8) +#define ADC_CHANNEL_9_BITFIELD (ADC_CHSELR_CHSEL9) +#define ADC_CHANNEL_10_BITFIELD (ADC_CHSELR_CHSEL10) +#define ADC_CHANNEL_11_BITFIELD (ADC_CHSELR_CHSEL11) +#define ADC_CHANNEL_12_BITFIELD (ADC_CHSELR_CHSEL12) +#define ADC_CHANNEL_13_BITFIELD (ADC_CHSELR_CHSEL13) +#define ADC_CHANNEL_14_BITFIELD (ADC_CHSELR_CHSEL14) +#define ADC_CHANNEL_15_BITFIELD (ADC_CHSELR_CHSEL15) +#define ADC_CHANNEL_16_BITFIELD (ADC_CHSELR_CHSEL16) +#define ADC_CHANNEL_17_BITFIELD (ADC_CHSELR_CHSEL17) +#define ADC_CHANNEL_18_BITFIELD (ADC_CHSELR_CHSEL18) + +/* Internal mask for ADC analog watchdog: */ +/* To select into literals LL_ADC_AWD_CHANNELx_xxx the relevant bits for: */ +/* (concatenation of multiple bits used in different analog watchdogs, */ +/* (feature of several watchdogs not available on all STM32 families)). */ +/* - analog watchdog 1: monitored channel defined by number, */ +/* selection of ADC group (ADC group regular). */ + +/* Internal register offset for ADC analog watchdog channel configuration */ +#define ADC_AWD_CR1_REGOFFSET (0x00000000U) + +#define ADC_AWD_CRX_REGOFFSET_MASK (ADC_AWD_CR1_REGOFFSET) + +#define ADC_AWD_CR1_CHANNEL_MASK (ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL) +#define ADC_AWD_CR_ALL_CHANNEL_MASK (ADC_AWD_CR1_CHANNEL_MASK) + +/* Internal register offset for ADC analog watchdog threshold configuration */ +#define ADC_AWD_TR1_REGOFFSET (ADC_AWD_CR1_REGOFFSET) +#define ADC_AWD_TRX_REGOFFSET_MASK (ADC_AWD_TR1_REGOFFSET) + + +/* ADC registers bits positions */ +#define ADC_CFGR1_RES_BITOFFSET_POS \ + (3U) /* Value equivalent to POSITION_VAL(ADC_CFGR1_RES) */ +#define ADC_CFGR1_AWDSGL_BITOFFSET_POS \ + (22U) /* Value equivalent to POSITION_VAL(ADC_CFGR1_AWDSGL) */ +#define ADC_TR_HT_BITOFFSET_POS (16U) /* Value equivalent to POSITION_VAL(ADC_TR_HT) */ +#define ADC_CHSELR_CHSEL0_BITOFFSET_POS \ + (0U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL0) */ +#define ADC_CHSELR_CHSEL1_BITOFFSET_POS \ + (1U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL1) */ +#define ADC_CHSELR_CHSEL2_BITOFFSET_POS \ + (2U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL2) */ +#define ADC_CHSELR_CHSEL3_BITOFFSET_POS \ + (3U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL3) */ +#define ADC_CHSELR_CHSEL4_BITOFFSET_POS \ + (4U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL4) */ +#define ADC_CHSELR_CHSEL5_BITOFFSET_POS \ + (5U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL5) */ +#define ADC_CHSELR_CHSEL6_BITOFFSET_POS \ + (6U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL6) */ +#define ADC_CHSELR_CHSEL7_BITOFFSET_POS \ + (7U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL7) */ +#define ADC_CHSELR_CHSEL8_BITOFFSET_POS \ + (8U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL8) */ +#define ADC_CHSELR_CHSEL9_BITOFFSET_POS \ + (9U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL9) */ +#define ADC_CHSELR_CHSEL10_BITOFFSET_POS \ + (10U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL10) */ +#define ADC_CHSELR_CHSEL11_BITOFFSET_POS \ + (11U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL11) */ +#define ADC_CHSELR_CHSEL12_BITOFFSET_POS \ + (12U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL12) */ +#define ADC_CHSELR_CHSEL13_BITOFFSET_POS \ + (13U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL13) */ +#define ADC_CHSELR_CHSEL14_BITOFFSET_POS \ + (14U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL14) */ +#define ADC_CHSELR_CHSEL15_BITOFFSET_POS \ + (15U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL15) */ +#define ADC_CHSELR_CHSEL16_BITOFFSET_POS \ + (16U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL16) */ +#define ADC_CHSELR_CHSEL17_BITOFFSET_POS \ + (17U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL17) */ +#define ADC_CHSELR_CHSEL18_BITOFFSET_POS \ + (18U) /* Value equivalent to POSITION_VAL(ADC_CHSELR_CHSEL18) */ + + +/* ADC registers bits groups */ +#define ADC_CR_BITS_PROPERTY_RS \ + (ADC_CR_ADCAL | ADC_CR_ADSTP | ADC_CR_ADSTART | ADC_CR_ADDIS | \ + ADC_CR_ADEN) /* ADC register CR bits with HW property "rs": Software can read as \ + well as set this bit. Writing '0' has no effect on the bit value. \ + */ + + +/* ADC internal channels related definitions */ +/* Internal voltage reference VrefInt */ +#define VREFINT_CAL_ADDR \ + ((uint16_t *)(0x1FFFF7BAU)) /* Internal voltage reference, address of parameter \ + VREFINT_CAL: VrefInt ADC raw data acquired at \ + temperature 30 DegC (tolerance: +-5 DegC), Vref+ \ + = 3.3 V (tolerance: +-10 mV). */ +#define VREFINT_CAL_VREF \ + (3300U) /* Analog voltage reference (Vref+) value with which temperature sensor has \ + been calibrated in production (tolerance: +-10 mV) (unit: mV). */ +/* Temperature sensor */ +#define TEMPSENSOR_CAL1_ADDR \ + ((uint16_t *)(0x1FFFF7B8U)) /* Internal temperature sensor, address of parameter \ + TS_CAL1: On STM32F0, temperature sensor ADC raw data \ + acquired at temperature 30 DegC (tolerance: +-5 \ + DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */ +#define TEMPSENSOR_CAL2_ADDR \ + ((uint16_t *)(0x1FFFF7C2U)) /* Internal temperature sensor, address of parameter \ + TS_CAL2: On STM32F0, temperature sensor ADC raw data \ + acquired at temperature 110 DegC (tolerance: +-5 \ + DegC), Vref+ = 3.3 V (tolerance: +-10 mV). */ +#define TEMPSENSOR_CAL1_TEMP \ + ((int32_t)30) /* Internal temperature sensor, temperature at which temperature \ + sensor has been calibrated in production for data into \ + TEMPSENSOR_CAL1_ADDR (tolerance: +-5 DegC) (unit: DegC). */ +#define TEMPSENSOR_CAL2_TEMP \ + ((int32_t)110) /* Internal temperature sensor, temperature at which temperature \ + sensor has been calibrated in production for data into \ + TEMPSENSOR_CAL2_ADDR (tolerance: +-5 DegC) (unit: DegC). */ +#define TEMPSENSOR_CAL_VREFANALOG \ + (3300U) /* Analog voltage reference (Vref+) voltage with which temperature sensor \ + has been calibrated in production (+-10 mV) (unit: mV). */ + + +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup ADC_LL_ES_INIT ADC Exported Init structure + * @{ + */ + + /** + * @brief Structure definition of some features of ADC instance. + * @note These parameters have an impact on ADC scope: ADC instance. + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Instance . + * @note The setting of these parameters by function @ref LL_ADC_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + */ + typedef struct + { + uint32_t Clock; /*!< Set ADC instance clock source and prescaler. + This parameter can be a value of @ref ADC_LL_EC_CLOCK_SOURCE + @note On this STM32 series, this parameter has some clock + ratio constraints: ADC clock synchronous (from PCLK) with + prescaler 1 must be enabled only if PCLK has a 50% duty clock + cycle (APB prescaler configured inside the RCC must be bypassed + and the system clock must by 50% duty cycle). + + + This feature can be modified afterwards using unitary + function @ref LL_ADC_SetClock(). For more details, refer to + description of this function. */ + + uint32_t + Resolution; /*!< Set ADC resolution. + This parameter can be a value of @ref ADC_LL_EC_RESOLUTION + + This feature can be modified afterwards using unitary + function @ref LL_ADC_SetResolution(). */ + + uint32_t + DataAlignment; /*!< Set ADC conversion data alignment. + This parameter can be a value of @ref ADC_LL_EC_DATA_ALIGN + + This feature can be modified afterwards using unitary + function @ref LL_ADC_SetDataAlignment(). */ + + uint32_t + LowPowerMode; /*!< Set ADC low power mode. + This parameter can be a value of @ref ADC_LL_EC_LP_MODE + + This feature can be modified afterwards using unitary + function @ref LL_ADC_SetLowPowerMode(). */ + + } LL_ADC_InitTypeDef; + + /** + * @brief Structure definition of some features of ADC group regular. + * @note These parameters have an impact on ADC scope: ADC group regular. + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Group_Regular + * (functions with prefix "REG"). + * @note The setting of these parameters by function @ref LL_ADC_REG_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + */ + typedef struct + { + uint32_t TriggerSource; /*!< Set ADC group regular conversion trigger source: + internal (SW start) or from external IP (timer event, + external interrupt line). This parameter can be a value + of @ref ADC_LL_EC_REG_TRIGGER_SOURCE + @note On this STM32 series, setting trigger source to + external trigger also set trigger polarity to rising + edge (default setting for compatibility with some ADC + on other STM32 families having this setting set by HW + default value). In case of need to modify trigger edge, + use function @ref LL_ADC_REG_SetTriggerEdge(). + + This feature can be modified afterwards using unitary + function @ref LL_ADC_REG_SetTriggerSource(). */ + + uint32_t + SequencerDiscont; /*!< Set ADC group regular sequencer discontinuous mode: + sequence subdivided and scan conversions interrupted + every selected number of ranks. This parameter can be a + value of @ref ADC_LL_EC_REG_SEQ_DISCONT_MODE + @note This parameter has an effect only if group + regular sequencer is enabled (several ADC channels + enabled in group regular sequencer). + + This feature can be modified afterwards using unitary + function @ref LL_ADC_REG_SetSequencerDiscont(). */ + + uint32_t + ContinuousMode; /*!< Set ADC continuous conversion mode on ADC group regular, + whether ADC conversions are performed in single mode (one + conversion per trigger) or in continuous mode (after the + first trigger, following conversions launched successively + automatically). This parameter can be a value of @ref + ADC_LL_EC_REG_CONTINUOUS_MODE Note: It is not possible to + enable both ADC group regular continuous mode and + discontinuous mode. + + This feature can be modified afterwards using unitary + function @ref LL_ADC_REG_SetContinuousMode(). */ + + uint32_t + DMATransfer; /*!< Set ADC group regular conversion data transfer: no transfer + or transfer by DMA, and DMA requests mode. This parameter can + be a value of @ref ADC_LL_EC_REG_DMA_TRANSFER + + This feature can be modified afterwards using unitary + function @ref LL_ADC_REG_SetDMATransfer(). */ + + uint32_t Overrun; /*!< Set ADC group regular behavior in case of overrun: + data preserved or overwritten. + This parameter can be a value of @ref + ADC_LL_EC_REG_OVR_DATA_BEHAVIOR + + This feature can be modified afterwards using unitary + function @ref LL_ADC_REG_SetOverrun(). */ + + } LL_ADC_REG_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ADC_LL_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADC_LL_EC_FLAG ADC flags + * @brief Flags defines which can be used with LL_ADC_ReadReg function + * @{ + */ +#define LL_ADC_FLAG_ADRDY ADC_ISR_ADRDY /*!< ADC flag ADC instance ready */ +#define LL_ADC_FLAG_EOC \ + ADC_ISR_EOC /*!< ADC flag ADC group regular end of unitary conversion */ +#define LL_ADC_FLAG_EOS \ + ADC_ISR_EOS /*!< ADC flag ADC group regular end of sequence conversions */ +#define LL_ADC_FLAG_OVR ADC_ISR_OVR /*!< ADC flag ADC group regular overrun */ +#define LL_ADC_FLAG_EOSMP \ + ADC_ISR_EOSMP /*!< ADC flag ADC group regular end of sampling phase */ +#define LL_ADC_FLAG_AWD1 ADC_ISR_AWD /*!< ADC flag ADC analog watchdog 1 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_IT ADC interruptions for configuration (interruption enable or + * disable) + * @brief IT defines which can be used with LL_ADC_ReadReg and LL_ADC_WriteReg + * functions + * @{ + */ +#define LL_ADC_IT_ADRDY ADC_IER_ADRDYIE /*!< ADC interruption ADC instance ready */ +#define LL_ADC_IT_EOC \ + ADC_IER_EOCIE /*!< ADC interruption ADC group regular end of unitary conversion */ +#define LL_ADC_IT_EOS \ + ADC_IER_EOSIE /*!< ADC interruption ADC group regular end of sequence conversions */ +#define LL_ADC_IT_OVR ADC_IER_OVRIE /*!< ADC interruption ADC group regular overrun */ +#define LL_ADC_IT_EOSMP \ + ADC_IER_EOSMPIE /*!< ADC interruption ADC group regular end of sampling phase */ +#define LL_ADC_IT_AWD1 ADC_IER_AWDIE /*!< ADC interruption ADC analog watchdog 1 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REGISTERS ADC registers compliant with specific purpose + * @{ + */ +/* List of ADC registers intended to be used (most commonly) with */ +/* DMA transfer. */ +/* Refer to function @ref LL_ADC_DMA_GetRegAddr(). */ +#define LL_ADC_DMA_REG_REGULAR_DATA \ + (0x00000000U) /* ADC group regular conversion data register (corresponding to \ + register DR) to be used with ADC configured in independent mode. \ + Without DMA transfer, register accessed by LL function @ref \ + LL_ADC_REG_ReadConversionData32() and other functions @ref \ + LL_ADC_REG_ReadConversionDatax() */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_COMMON_PATH_INTERNAL ADC common - Measurement path to internal + * channels + * @{ + */ +/* Note: Other measurement paths to internal channels may be available */ +/* (connections to other peripherals). */ +/* If they are not listed below, they do not require any specific */ +/* path enable. In this case, Access to measurement path is done */ +/* only by selecting the corresponding ADC internal channel. */ +#define LL_ADC_PATH_INTERNAL_NONE \ + (0x00000000U) /*!< ADC measurement paths all disabled \ + */ +#define LL_ADC_PATH_INTERNAL_VREFINT \ + (ADC_CCR_VREFEN) /*!< ADC measurement path to internal channel VrefInt */ +#define LL_ADC_PATH_INTERNAL_TEMPSENSOR \ + (ADC_CCR_TSEN) /*!< ADC measurement path to internal channel temperature sensor */ +#if defined(ADC_CCR_VBATEN) +#define LL_ADC_PATH_INTERNAL_VBAT \ + (ADC_CCR_VBATEN) /*!< ADC measurement path to internal channel Vbat */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CLOCK_SOURCE ADC instance - Clock source + * @{ + */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV4 \ + (ADC_CFGR2_CKMODE_1) /*!< ADC synchronous clock derived from AHB clock divided by 4 \ + */ +#define LL_ADC_CLOCK_SYNC_PCLK_DIV2 \ + (ADC_CFGR2_CKMODE_0) /*!< ADC synchronous clock derived from AHB clock divided by 2 \ + */ +#define LL_ADC_CLOCK_ASYNC \ + (0x00000000U) /*!< ADC asynchronous clock. On this STM32 series, asynchronous clock \ + has no prescaler. */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_RESOLUTION ADC instance - Resolution + * @{ + */ +#define LL_ADC_RESOLUTION_12B (0x00000000U) /*!< ADC resolution 12 bits */ +#define LL_ADC_RESOLUTION_10B (ADC_CFGR1_RES_0) /*!< ADC resolution 10 bits */ +#define LL_ADC_RESOLUTION_8B (ADC_CFGR1_RES_1) /*!< ADC resolution 8 bits */ +#define LL_ADC_RESOLUTION_6B \ + (ADC_CFGR1_RES_1 | ADC_CFGR1_RES_0) /*!< ADC resolution 6 bits */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_DATA_ALIGN ADC instance - Data alignment + * @{ + */ +#define LL_ADC_DATA_ALIGN_RIGHT \ + (0x00000000U) /*!< ADC conversion data alignment: right aligned (alignment on data \ + register LSB bit 0)*/ +#define LL_ADC_DATA_ALIGN_LEFT \ + (ADC_CFGR1_ALIGN) /*!< ADC conversion data alignment: left aligned (alignment on \ + data register MSB bit 15)*/ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_LP_MODE ADC instance - Low power mode + * @{ + */ +#define LL_ADC_LP_MODE_NONE (0x00000000U) /*!< No ADC low power mode activated */ +#define LL_ADC_LP_AUTOWAIT \ + (ADC_CFGR1_WAIT) /*!< ADC low power mode auto delay: Dynamic low power mode, ADC \ + conversions are performed only when necessary (when previous ADC \ + conversion data is read). See description with function @ref \ + LL_ADC_SetLowPowerMode(). */ +#define LL_ADC_LP_AUTOPOWEROFF \ + (ADC_CFGR1_AUTOFF) /*!< ADC low power mode auto power-off: the ADC automatically \ + powers-off after a ADC conversion and automatically wakes up \ + when a new ADC conversion is triggered (with startup time \ + between trigger and start of sampling). See description with \ + function @ref LL_ADC_SetLowPowerMode(). Note: On STM32F0, if \ + enabled, this feature also turns off the ADC dedicated 14 MHz \ + RC oscillator (HSI14) during auto wait phase. */ +#define LL_ADC_LP_AUTOWAIT_AUTOPOWEROFF \ + (ADC_CFGR1_WAIT | ADC_CFGR1_AUTOFF) /*!< ADC low power modes auto wait and auto \ + power-off combined. See description with \ + function @ref LL_ADC_SetLowPowerMode(). */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_GROUPS ADC instance - Groups + * @{ + */ +#define LL_ADC_GROUP_REGULAR \ + (0x00000001U) /*!< ADC group regular (available on all STM32 devices) */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CHANNEL ADC instance - Channel number + * @{ + */ +#define LL_ADC_CHANNEL_0 \ + (ADC_CHANNEL_0_NUMBER | \ + ADC_CHANNEL_0_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN0 */ +#define LL_ADC_CHANNEL_1 \ + (ADC_CHANNEL_1_NUMBER | \ + ADC_CHANNEL_1_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN1 */ +#define LL_ADC_CHANNEL_2 \ + (ADC_CHANNEL_2_NUMBER | \ + ADC_CHANNEL_2_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN2 */ +#define LL_ADC_CHANNEL_3 \ + (ADC_CHANNEL_3_NUMBER | \ + ADC_CHANNEL_3_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN3 */ +#define LL_ADC_CHANNEL_4 \ + (ADC_CHANNEL_4_NUMBER | \ + ADC_CHANNEL_4_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN4 */ +#define LL_ADC_CHANNEL_5 \ + (ADC_CHANNEL_5_NUMBER | \ + ADC_CHANNEL_5_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN5 */ +#define LL_ADC_CHANNEL_6 \ + (ADC_CHANNEL_6_NUMBER | \ + ADC_CHANNEL_6_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN6 */ +#define LL_ADC_CHANNEL_7 \ + (ADC_CHANNEL_7_NUMBER | \ + ADC_CHANNEL_7_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN7 */ +#define LL_ADC_CHANNEL_8 \ + (ADC_CHANNEL_8_NUMBER | \ + ADC_CHANNEL_8_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN8 */ +#define LL_ADC_CHANNEL_9 \ + (ADC_CHANNEL_9_NUMBER | \ + ADC_CHANNEL_9_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN9 */ +#define LL_ADC_CHANNEL_10 \ + (ADC_CHANNEL_10_NUMBER | \ + ADC_CHANNEL_10_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN10 */ +#define LL_ADC_CHANNEL_11 \ + (ADC_CHANNEL_11_NUMBER | \ + ADC_CHANNEL_11_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN11 */ +#define LL_ADC_CHANNEL_12 \ + (ADC_CHANNEL_12_NUMBER | \ + ADC_CHANNEL_12_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN12 */ +#define LL_ADC_CHANNEL_13 \ + (ADC_CHANNEL_13_NUMBER | \ + ADC_CHANNEL_13_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN13 */ +#define LL_ADC_CHANNEL_14 \ + (ADC_CHANNEL_14_NUMBER | \ + ADC_CHANNEL_14_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN14 */ +#define LL_ADC_CHANNEL_15 \ + (ADC_CHANNEL_15_NUMBER | \ + ADC_CHANNEL_15_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN15 */ +#define LL_ADC_CHANNEL_16 \ + (ADC_CHANNEL_16_NUMBER | \ + ADC_CHANNEL_16_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN16 */ +#define LL_ADC_CHANNEL_17 \ + (ADC_CHANNEL_17_NUMBER | \ + ADC_CHANNEL_17_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN17 */ +#define LL_ADC_CHANNEL_VREFINT \ + (LL_ADC_CHANNEL_17 | \ + ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel connected to VrefInt: \ + Internal voltage reference. */ +#define LL_ADC_CHANNEL_TEMPSENSOR \ + (LL_ADC_CHANNEL_16 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel connected \ + to Temperature sensor. */ +#if defined(ADC_CCR_VBATEN) +#define LL_ADC_CHANNEL_18 \ + (ADC_CHANNEL_18_NUMBER | \ + ADC_CHANNEL_18_BITFIELD) /*!< ADC external channel (channel connected to GPIO pin) \ + ADCx_IN18 */ +#define LL_ADC_CHANNEL_VBAT \ + (LL_ADC_CHANNEL_18 | \ + ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel connected to Vbat/2: Vbat \ + voltage through a divider ladder of factor 1/2 to \ + have Vbat always below Vdda. */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_TRIGGER_SOURCE ADC group regular - Trigger source + * @{ + */ +#define LL_ADC_REG_TRIG_SOFTWARE \ + (0x00000000U) /*!< ADC group regular conversion trigger internal: SW start. */ +#define LL_ADC_REG_TRIG_EXT_TIM1_TRGO \ + (ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from \ + external IP: TIM1 TRGO. Trigger edge set to \ + rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM1_CH4 \ + (ADC_CFGR1_EXTSEL_0 | \ + ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from \ + external IP: TIM1 channel 4 event (capture \ + compare: input capture or output capture). \ + Trigger edge set to rising edge (default \ + setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM2_TRGO \ + (ADC_CFGR1_EXTSEL_1 | \ + ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from \ + external IP: TIM2 TRGO. Trigger edge set to \ + rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM3_TRGO \ + (ADC_CFGR1_EXTSEL_1 | ADC_CFGR1_EXTSEL_0 | \ + ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from \ + external IP: TIM3 TRGO. Trigger edge set to \ + rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM15_TRGO \ + (ADC_CFGR1_EXTSEL_2 | \ + ADC_REG_TRIG_EXT_EDGE_DEFAULT) /*!< ADC group regular conversion trigger from \ + external IP: TIM15 TRGO. Trigger edge set to \ + rising edge (default setting). */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_TRIGGER_EDGE ADC group regular - Trigger edge + * @{ + */ +#define LL_ADC_REG_TRIG_EXT_RISING \ + (ADC_CFGR1_EXTEN_0) /*!< ADC group regular conversion trigger polarity set to rising \ + edge */ +#define LL_ADC_REG_TRIG_EXT_FALLING \ + (ADC_CFGR1_EXTEN_1) /*!< ADC group regular conversion trigger polarity set to \ + falling edge */ +#define LL_ADC_REG_TRIG_EXT_RISINGFALLING \ + (ADC_CFGR1_EXTEN_1 | \ + ADC_CFGR1_EXTEN_0) /*!< ADC group regular conversion trigger polarity set to both \ + rising and falling edges */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_CONTINUOUS_MODE ADC group regular - Continuous mode + * @{ + */ +#define LL_ADC_REG_CONV_SINGLE \ + (0x00000000U) /*!< ADC conversions are performed in single mode: one conversion per \ + trigger */ +#define LL_ADC_REG_CONV_CONTINUOUS \ + (ADC_CFGR1_CONT) /*!< ADC conversions are performed in continuous mode: after the \ + first trigger, following conversions launched successively \ + automatically */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_DMA_TRANSFER ADC group regular - DMA transfer of ADC + * conversion data + * @{ + */ +#define LL_ADC_REG_DMA_TRANSFER_NONE \ + (0x00000000U) /*!< ADC conversions are not transferred by DMA */ +#define LL_ADC_REG_DMA_TRANSFER_LIMITED \ + (ADC_CFGR1_DMAEN) /*!< ADC conversion data are transferred by DMA, in limited mode \ + (one shot mode): DMA transfer requests are stopped when number \ + of DMA data transfers (number of ADC conversions) is reached. \ + This ADC mode is intended to be used with DMA mode \ + non-circular. */ +#define LL_ADC_REG_DMA_TRANSFER_UNLIMITED \ + (ADC_CFGR1_DMACFG | \ + ADC_CFGR1_DMAEN) /*!< ADC conversion data are transferred by DMA, in unlimited \ + mode: DMA transfer requests are unlimited, whatever number of \ + DMA data transferred (number of ADC conversions). This ADC mode \ + is intended to be used with DMA mode circular. */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_OVR_DATA_BEHAVIOR ADC group regular - Overrun behavior on + * conversion data + * @{ + */ +#define LL_ADC_REG_OVR_DATA_PRESERVED \ + (0x00000000U) /*!< ADC group regular behavior in case of overrun: data preserved */ +#define LL_ADC_REG_OVR_DATA_OVERWRITTEN \ + (ADC_CFGR1_OVRMOD) /*!< ADC group regular behavior in case of overrun: data \ + overwritten */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SEQ_SCAN_DIRECTION ADC group regular - Sequencer scan + * direction + * @{ + */ +#define LL_ADC_REG_SEQ_SCAN_DIR_FORWARD \ + (0x00000000U) /*!< ADC group regular sequencer scan direction forward: from lowest \ + channel number to highest channel number (scan of all ranks, ADC \ + conversion of ranks with channels enabled in sequencer). On some \ + other STM32 families, this setting is not available and the default \ + scan direction is forward. */ +#define LL_ADC_REG_SEQ_SCAN_DIR_BACKWARD \ + (ADC_CFGR1_SCANDIR) /*!< ADC group regular sequencer scan direction backward: from \ + highest channel number to lowest channel number (scan of all \ + ranks, ADC conversion of ranks with channels enabled in \ + sequencer) */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SEQ_DISCONT_MODE ADC group regular - Sequencer discontinuous + * mode + * @{ + */ +#define LL_ADC_REG_SEQ_DISCONT_DISABLE \ + (0x00000000U) /*!< ADC group regular sequencer discontinuous mode disable */ +#define LL_ADC_REG_SEQ_DISCONT_1RANK \ + (ADC_CFGR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with \ + sequence interruption every rank */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CHANNEL_SAMPLINGTIME Channel - Sampling time + * @{ + */ +#define LL_ADC_SAMPLINGTIME_1CYCLE_5 \ + (0x00000000U) /*!< Sampling time 1.5 ADC clock cycle */ +#define LL_ADC_SAMPLINGTIME_7CYCLES_5 \ + (ADC_SMPR_SMP_0) /*!< Sampling time 7.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_13CYCLES_5 \ + (ADC_SMPR_SMP_1) /*!< Sampling time 13.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_28CYCLES_5 \ + (ADC_SMPR_SMP_1 | ADC_SMPR_SMP_0) /*!< Sampling time 28.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_41CYCLES_5 \ + (ADC_SMPR_SMP_2) /*!< Sampling time 41.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_55CYCLES_5 \ + (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_0) /*!< Sampling time 55.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_71CYCLES_5 \ + (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1) /*!< Sampling time 71.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_239CYCLES_5 \ + (ADC_SMPR_SMP_2 | ADC_SMPR_SMP_1 | \ + ADC_SMPR_SMP_0) /*!< Sampling time 239.5 ADC clock cycles */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_NUMBER Analog watchdog - Analog watchdog number + * @{ + */ +#define LL_ADC_AWD1 \ + (ADC_AWD_CR1_CHANNEL_MASK | \ + ADC_AWD_CR1_REGOFFSET) /*!< ADC analog watchdog number 1 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_CHANNELS Analog watchdog - Monitored channels + * @{ + */ +#define LL_ADC_AWD_DISABLE (0x00000000U) /*!< ADC analog watchdog monitoring disabled */ +#define LL_ADC_AWD_ALL_CHANNELS_REG \ + (ADC_CFGR1_AWDEN) /*!< ADC analog watchdog monitoring of all channels, converted by \ + group regular only */ +#define LL_ADC_AWD_CHANNEL_0_REG \ + ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN0, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_1_REG \ + ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN1, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_2_REG \ + ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN2, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_3_REG \ + ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN3, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_4_REG \ + ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN4, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_5_REG \ + ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN5, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_6_REG \ + ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN6, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_7_REG \ + ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN7, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_8_REG \ + ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN8, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_9_REG \ + ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN9, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_10_REG \ + ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN10, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_11_REG \ + ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN11, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_12_REG \ + ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN12, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_13_REG \ + ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN13, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_14_REG \ + ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN14, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_15_REG \ + ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN15, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_16_REG \ + ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN16, converted by group \ + regular only */ +#define LL_ADC_AWD_CHANNEL_17_REG \ + ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN17, converted by group \ + regular only */ +#define LL_ADC_AWD_CH_VREFINT_REG \ + ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel \ + connected to VrefInt: Internal voltage reference, converted by \ + group regular only */ +#define LL_ADC_AWD_CH_TEMPSENSOR_REG \ + ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel \ + connected to Temperature sensor, converted by group regular \ + only */ +#if defined(ADC_CCR_VBATEN) +#define LL_ADC_AWD_CHANNEL_18_REG \ + ((LL_ADC_CHANNEL_18 & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel \ + (channel connected to GPIO pin) ADCx_IN18, converted by group \ + regular only */ +#define LL_ADC_AWD_CH_VBAT_REG \ + ((LL_ADC_CHANNEL_VBAT & ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | \ + ADC_CFGR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel \ + connected to Vbat/3: Vbat voltage through a divider ladder of \ + factor 1/3 to have Vbat always below Vdda, converted by group \ + regular only */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_THRESHOLDS Analog watchdog - Thresholds + * @{ + */ +#define LL_ADC_AWD_THRESHOLD_HIGH (ADC_TR_HT) /*!< ADC analog watchdog threshold high */ +#define LL_ADC_AWD_THRESHOLD_LOW (ADC_TR_LT) /*!< ADC analog watchdog threshold low */ +#define LL_ADC_AWD_THRESHOLDS_HIGH_LOW \ + (ADC_TR_HT | ADC_TR_LT) /*!< ADC analog watchdog both thresholds high and low \ + concatenated into the same data */ +/** + * @} + */ + + +/** @defgroup ADC_LL_EC_HW_DELAYS Definitions of ADC hardware constraints delays + * @note Only ADC IP HW delays are defined in ADC LL driver driver, + * not timeout values. + * For details on delays values, refer to descriptions in source code + * above each literal definition. + * @{ + */ + +/* Note: Only ADC IP HW delays are defined in ADC LL driver driver, */ +/* not timeout values. */ +/* Timeout values for ADC operations are dependent to device clock */ +/* configuration (system clock versus ADC clock), */ +/* and therefore must be defined in user application. */ +/* Indications for estimation of ADC timeout delays, for this */ +/* STM32 series: */ +/* - ADC calibration time: maximum delay is 83/fADC. */ +/* (refer to device datasheet, parameter "tCAL") */ +/* - ADC enable time: maximum delay is 1 conversion cycle. */ +/* (refer to device datasheet, parameter "tSTAB") */ +/* - ADC disable time: maximum delay should be a few ADC clock cycles */ +/* - ADC stop conversion time: maximum delay should be a few ADC clock */ +/* cycles */ +/* - ADC conversion time: duration depending on ADC clock and ADC */ +/* configuration. */ +/* (refer to device reference manual, section "Timing") */ + + +/* Delay for internal voltage reference stabilization time. */ +/* Delay set to maximum value (refer to device datasheet, */ +/* parameter "tSTART"). */ +/* Unit: us */ +#define LL_ADC_DELAY_VREFINT_STAB_US \ + (10U) /*!< Delay for internal voltage reference stabilization time */ + +/* Delay for temperature sensor stabilization time. */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tSTART"). */ +/* Unit: us */ +#define LL_ADC_DELAY_TEMPSENSOR_STAB_US \ + (10U) /*!< Delay for temperature sensor stabilization time */ + +/* Delay required between ADC end of calibration and ADC enable. */ +/* Note: On this STM32 series, a minimum number of ADC clock cycles */ +/* are required between ADC end of calibration and ADC enable. */ +/* Wait time can be computed in user application by waiting for the */ +/* equivalent number of CPU cycles, by taking into account */ +/* ratio of CPU clock versus ADC clock prescalers. */ +/* Unit: ADC clock cycles. */ +#define LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES \ + (2U) /*!< Delay required between ADC end of calibration and ADC enable */ + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ADC_LL_Exported_Macros ADC Exported Macros + * @{ + */ + +/** @defgroup ADC_LL_EM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in ADC register + * @param __INSTANCE__ ADC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_ADC_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in ADC register + * @param __INSTANCE__ ADC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_ADC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup ADC_LL_EM_HELPER_MACRO ADC helper macro + * @{ + */ + +/** + * @brief Helper macro to get ADC channel number in decimal format + * from literals LL_ADC_CHANNEL_x. + * @note Example: + * __LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_4) + * will return decimal number "4". + * @note The input can be a value from functions where a channel + * number is returned, either defined with number + * or with bitfield (only one bit must be set). + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval Value between Min_Data=0 and Max_Data=18 + */ +#define __LL_ADC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) \ + ( \ + (((__CHANNEL__)&ADC_CHANNEL_ID_BITFIELD_MASK) == 0U) \ + ? (((__CHANNEL__)&ADC_CHANNEL_ID_NUMBER_MASK) >> \ + ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL0) == ADC_CHSELR_CHSEL0) \ + ? (0U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL1) == ADC_CHSELR_CHSEL1) \ + ? (1U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL2) == ADC_CHSELR_CHSEL2) \ + ? (2U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL3) == ADC_CHSELR_CHSEL3) ? (3U) \ + : ( \ + (((__CHANNEL__)&ADC_CHSELR_CHSEL4) == ADC_CHSELR_CHSEL4) ? (4U) \ + : ( \ + (((__CHANNEL__)&ADC_CHSELR_CHSEL5) == ADC_CHSELR_CHSEL5) ? (5U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL6) == ADC_CHSELR_CHSEL6) ? (6U) \ + : ( \ + (((__CHANNEL__)&ADC_CHSELR_CHSEL7) == ADC_CHSELR_CHSEL7) ? (7U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL8) == \ + ADC_CHSELR_CHSEL8) \ + ? (8U) \ + : ( \ + ( \ + ( \ + ( \ + __CHANNEL__)&ADC_CHSELR_CHSEL9) == ADC_CHSELR_CHSEL9) \ + ? (9U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL10) == ADC_CHSELR_CHSEL10) ? (10U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL11) == \ + ADC_CHSELR_CHSEL11) \ + ? (11U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL12) == \ + ADC_CHSELR_CHSEL12) \ + ? (12U) \ + : (((( \ + __CHANNEL__)&ADC_CHSELR_CHSEL13) == \ + ADC_CHSELR_CHSEL13) \ + ? (13U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL14) == ADC_CHSELR_CHSEL14) ? (14U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL15) == \ + ADC_CHSELR_CHSEL15) \ + ? (15U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL16) == ADC_CHSELR_CHSEL16) ? (16U) \ + : ((( \ + (__CHANNEL__)&ADC_CHSELR_CHSEL17) == \ + ADC_CHSELR_CHSEL17) \ + ? (17U) \ + : ((((__CHANNEL__)&ADC_CHSELR_CHSEL18) == ADC_CHSELR_CHSEL18) ? (18U) \ + : (0U))))))))))))))))))))) + +/** + * @brief Helper macro to get ADC channel in literal format LL_ADC_CHANNEL_x + * from number in decimal format. + * @note Example: + * __LL_ADC_DECIMAL_NB_TO_CHANNEL(4) + * will return a data equivalent to "LL_ADC_CHANNEL_4". + * @param __DECIMAL_NB__ Value between Min_Data=0 and Max_Data=18 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT (2) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1)(2) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB.\n (2) For ADC channel + * read back from ADC register, comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + */ +#define __LL_ADC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__) \ + (((__DECIMAL_NB__) << ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) | \ + (ADC_CHSELR_CHSEL0 << (__DECIMAL_NB__))) + +/** + * @brief Helper macro to determine whether the selected channel + * corresponds to literal definitions of driver. + * @note The different literal definitions of ADC channels are: + * - ADC internal channel: + * LL_ADC_CHANNEL_VREFINT, LL_ADC_CHANNEL_TEMPSENSOR, ... + * - ADC external channel (channel connected to a GPIO pin): + * LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ... + * @note The channel parameter must be a value defined from literal + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...), + * must not be a value from functions where a channel number is + * returned from ADC registers, + * because internal and external channels share the same channel + * number in ADC registers. The differentiation is made only with + * parameters definitions of driver. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval Value "0" if the channel corresponds to a parameter definition of a ADC + * external channel (channel connected to a GPIO pin). Value "1" if the channel + * corresponds to a parameter definition of a ADC internal channel. + */ +#define __LL_ADC_IS_CHANNEL_INTERNAL(__CHANNEL__) \ + (((__CHANNEL__)&ADC_CHANNEL_ID_INTERNAL_CH_MASK) != 0U) + +/** + * @brief Helper macro to convert a channel defined from parameter + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * to its equivalent parameter definition of a ADC external channel + * (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...). + * @note The channel parameter can be, additionally to a value + * defined from parameter definition of a ADC internal channel + * (LL_ADC_CHANNEL_VREFINT, LL_ADC_CHANNEL_TEMPSENSOR, ...), + * a value defined from parameter definition of + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...) + * or a value from functions where a channel number is returned + * from ADC registers. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 + */ +#define __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(__CHANNEL__) \ + ((__CHANNEL__) & ~ADC_CHANNEL_ID_INTERNAL_CH_MASK) + +/** + * @brief Helper macro to determine whether the internal channel + * selected is available on the ADC instance selected. + * @note The channel parameter must be a value defined from parameter + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * must not be a value defined from parameter definition of + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...) + * or a value from functions where a channel number is + * returned from ADC registers, + * because internal and external channels share the same channel + * number in ADC registers. The differentiation is made only with + * parameters definitions of driver. + * @param __ADC_INSTANCE__ ADC instance + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_VREFINT + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval Value "0" if the internal channel selected is not available on the ADC instance + * selected. Value "1" if the internal channel selected is available on the ADC instance + * selected. + */ +#if defined(ADC_CCR_VBATEN) +#define __LL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE(__ADC_INSTANCE__, __CHANNEL__) \ + (((__CHANNEL__) == LL_ADC_CHANNEL_VREFINT) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_TEMPSENSOR) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_VBAT)) +#else +#define __LL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE(__ADC_INSTANCE__, __CHANNEL__) \ + (((__CHANNEL__) == LL_ADC_CHANNEL_VREFINT) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_TEMPSENSOR)) +#endif + +/** + * @brief Helper macro to define ADC analog watchdog parameter: + * define a single channel to monitor with analog watchdog + * from sequencer channel and groups definition. + * @note To be used with function @ref LL_ADC_SetAnalogWDMonitChannels(). + * Example: + * LL_ADC_SetAnalogWDMonitChannels( + * ADC1, LL_ADC_AWD1, + * __LL_ADC_ANALOGWD_CHANNEL_GROUP(LL_ADC_CHANNEL4, LL_ADC_GROUP_REGULAR)) + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT (2) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (2) + * @arg @ref LL_ADC_CHANNEL_VBAT (1)(2) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB.\n (2) For ADC channel + * read back from ADC register, comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + * @param __GROUP__ This parameter can be one of the following values: + * @arg @ref LL_ADC_GROUP_REGULAR + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG + * @arg @ref LL_ADC_AWD_CH_VBAT_REG (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + */ +#define __LL_ADC_ANALOGWD_CHANNEL_GROUP(__CHANNEL__, __GROUP__) \ + (((__CHANNEL__)&ADC_CHANNEL_ID_MASK) | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL) + +/** + * @brief Helper macro to set the value of ADC analog watchdog threshold high + * or low in function of ADC resolution, when ADC resolution is + * different of 12 bits. + * @note To be used with function @ref LL_ADC_ConfigAnalogWDThresholds() + * or @ref LL_ADC_SetAnalogWDThresholds(). + * Example, with a ADC resolution of 8 bits, to set the value of + * analog watchdog threshold high (on 8 bits): + * LL_ADC_SetAnalogWDThresholds + * (< ADCx param >, + * __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(LL_ADC_RESOLUTION_8B, + * ) + * ); + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @param __AWD_THRESHOLD__ Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +#define __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(__ADC_RESOLUTION__, \ + __AWD_THRESHOLD__) \ + ((__AWD_THRESHOLD__) << ((__ADC_RESOLUTION__) >> (ADC_CFGR1_RES_BITOFFSET_POS - 1U))) + +/** + * @brief Helper macro to get the value of ADC analog watchdog threshold high + * or low in function of ADC resolution, when ADC resolution is + * different of 12 bits. + * @note To be used with function @ref LL_ADC_GetAnalogWDThresholds(). + * Example, with a ADC resolution of 8 bits, to get the value of + * analog watchdog threshold high (on 8 bits): + * < threshold_value_6_bits > = __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION + * (LL_ADC_RESOLUTION_8B, + * LL_ADC_GetAnalogWDThresholds(, LL_ADC_AWD_THRESHOLD_HIGH) + * ); + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @param __AWD_THRESHOLD_12_BITS__ Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +#define __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION(__ADC_RESOLUTION__, \ + __AWD_THRESHOLD_12_BITS__) \ + ((__AWD_THRESHOLD_12_BITS__) >> \ + ((__ADC_RESOLUTION__) >> (ADC_CFGR1_RES_BITOFFSET_POS - 1U))) + +/** + * @brief Helper macro to get the ADC analog watchdog threshold high + * or low from raw value containing both thresholds concatenated. + * @note To be used with function @ref LL_ADC_GetAnalogWDThresholds(). + * Example, to get analog watchdog threshold high from the register raw value: + * __LL_ADC_ANALOGWD_THRESHOLDS_HIGH_LOW(LL_ADC_AWD_THRESHOLD_HIGH, + * ); + * @param __AWD_THRESHOLD_TYPE__ This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_THRESHOLD_HIGH + * @arg @ref LL_ADC_AWD_THRESHOLD_LOW + * @param __AWD_THRESHOLDS__ Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +#define __LL_ADC_ANALOGWD_THRESHOLDS_HIGH_LOW(__AWD_THRESHOLD_TYPE__, \ + __AWD_THRESHOLDS__) \ + (((__AWD_THRESHOLD_TYPE__) == LL_ADC_AWD_THRESHOLD_LOW) \ + ? ((__AWD_THRESHOLDS__)&LL_ADC_AWD_THRESHOLD_LOW) \ + : (((__AWD_THRESHOLDS__) >> ADC_TR_HT_BITOFFSET_POS) & \ + LL_ADC_AWD_THRESHOLD_LOW)) + +/** + * @brief Helper macro to select the ADC common instance + * to which is belonging the selected ADC instance. + * @note ADC common register instance can be used for: + * - Set parameters common to several ADC instances + * - Multimode (for devices with several ADC instances) + * Refer to functions having argument "ADCxy_COMMON" as parameter. + * @param __ADCx__ ADC instance + * @retval ADC common register instance + */ +#define __LL_ADC_COMMON_INSTANCE(__ADCx__) (ADC1_COMMON) + +/** + * @brief Helper macro to check if all ADC instances sharing the same + * ADC common instance are disabled. + * @note This check is required by functions with setting conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled. + * Refer to functions having argument "ADCxy_COMMON" as parameter. + * @note On devices with only 1 ADC common instance, parameter of this macro + * is useless and can be ignored (parameter kept for compatibility + * with devices featuring several ADC common instances). + * @param __ADCXY_COMMON__ ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref + * __LL_ADC_COMMON_INSTANCE() ) + * @retval Value "0" if all ADC instances sharing the same ADC common instance + * are disabled. + * Value "1" if at least one ADC instance sharing the same ADC common instance + * is enabled. + */ +#define __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) LL_ADC_IsEnabled(ADC1) + +/** + * @brief Helper macro to define the ADC conversion data full-scale digital + * value corresponding to the selected ADC resolution. + * @note ADC conversion data full-scale corresponds to voltage range + * determined by analog voltage references Vref+ and Vref- + * (refer to reference manual). + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__) \ + (0xFFFU >> ((__ADC_RESOLUTION__) >> (ADC_CFGR1_RES_BITOFFSET_POS - 1U))) + +/** + * @brief Helper macro to convert the ADC conversion data from + * a resolution to another resolution. + * @param __DATA__ ADC conversion data to be converted + * @param __ADC_RESOLUTION_CURRENT__ Resolution of to the data to be converted + * This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @param __ADC_RESOLUTION_TARGET__ Resolution of the data after conversion + * This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval ADC conversion data to the requested resolution + */ +#define __LL_ADC_CONVERT_DATA_RESOLUTION(__DATA__, __ADC_RESOLUTION_CURRENT__, \ + __ADC_RESOLUTION_TARGET__) \ + (((__DATA__) << ((__ADC_RESOLUTION_CURRENT__) >> \ + (ADC_CFGR1_RES_BITOFFSET_POS - 1U))) >> \ + ((__ADC_RESOLUTION_TARGET__) >> (ADC_CFGR1_RES_BITOFFSET_POS - 1U))) + +/** + * @brief Helper macro to calculate the voltage (unit: mVolt) + * corresponding to a ADC conversion data (unit: digital value). + * @note Analog reference voltage (Vref+) must be either known from + * user board environment or can be calculated using ADC measurement + * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE(). + * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit: mV) + * @param __ADC_DATA__ ADC conversion data (resolution 12 bits) + * (unit: digital value). + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __LL_ADC_CALC_DATA_TO_VOLTAGE(__VREFANALOG_VOLTAGE__, __ADC_DATA__, \ + __ADC_RESOLUTION__) \ + ((__ADC_DATA__) * (__VREFANALOG_VOLTAGE__) / \ + __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)) + +/** + * @brief Helper macro to calculate analog reference voltage (Vref+) + * (unit: mVolt) from ADC conversion data of internal voltage + * reference VrefInt. + * @note Computation is using VrefInt calibration value + * stored in system memory for each device during production. + * @note This voltage depends on user board environment: voltage level + * connected to pin Vref+. + * On devices with small package, the pin Vref+ is not present + * and internally bonded to pin Vdda. + * @note On this STM32 series, calibration data of internal voltage reference + * VrefInt corresponds to a resolution of 12 bits, + * this is the recommended ADC resolution to convert voltage of + * internal voltage reference VrefInt. + * Otherwise, this macro performs the processing to scale + * ADC conversion data to 12 bits. + * @param __VREFINT_ADC_DATA__ ADC conversion data (resolution 12 bits) + * of internal voltage reference VrefInt (unit: digital value). + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval Analog reference voltage (unit: mV) + */ +#define __LL_ADC_CALC_VREFANALOG_VOLTAGE(__VREFINT_ADC_DATA__, __ADC_RESOLUTION__) \ + (((uint32_t)(*VREFINT_CAL_ADDR) * VREFINT_CAL_VREF) / \ + __LL_ADC_CONVERT_DATA_RESOLUTION((__VREFINT_ADC_DATA__), (__ADC_RESOLUTION__), \ + LL_ADC_RESOLUTION_12B)) + +/** + * @brief Helper macro to calculate the temperature (unit: degree Celsius) + * from ADC conversion data of internal temperature sensor. + * @note Computation is using temperature sensor calibration values + * stored in system memory for each device during production. + * @note Calculation formula: + * Temperature = ((TS_ADC_DATA - TS_CAL1) + * * (TS_CAL2_TEMP - TS_CAL1_TEMP)) + * / (TS_CAL2 - TS_CAL1) + TS_CAL1_TEMP + * with TS_ADC_DATA = temperature sensor raw data measured by ADC + * Avg_Slope = (TS_CAL2 - TS_CAL1) + * / (TS_CAL2_TEMP - TS_CAL1_TEMP) + * TS_CAL1 = equivalent TS_ADC_DATA at temperature + * TEMP_DEGC_CAL1 (calibrated in factory) + * TS_CAL2 = equivalent TS_ADC_DATA at temperature + * TEMP_DEGC_CAL2 (calibrated in factory) + * Caution: Calculation relevancy under reserve that calibration + * parameters are correct (address and data). + * To calculate temperature using temperature sensor + * datasheet typical values (generic values less, therefore + * less accurate than calibrated values), + * use helper macro @ref __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(). + * @note As calculation input, the analog reference voltage (Vref+) must be + * defined as it impacts the ADC LSB equivalent voltage. + * @note Analog reference voltage (Vref+) must be either known from + * user board environment or can be calculated using ADC measurement + * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE(). + * @note On this STM32 series, calibration data of temperature sensor + * corresponds to a resolution of 12 bits, + * this is the recommended ADC resolution to convert voltage of + * temperature sensor. + * Otherwise, this macro performs the processing to scale + * ADC conversion data to 12 bits. + * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit: mV) + * @param __TEMPSENSOR_ADC_DATA__ ADC conversion data of internal + * temperature sensor (unit: digital value). + * @param __ADC_RESOLUTION__ ADC resolution at which internal temperature + * sensor voltage has been measured. + * This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval Temperature (unit: degree Celsius) + */ +#define __LL_ADC_CALC_TEMPERATURE(__VREFANALOG_VOLTAGE__, __TEMPSENSOR_ADC_DATA__, \ + __ADC_RESOLUTION__) \ + ((((((int32_t)((__LL_ADC_CONVERT_DATA_RESOLUTION((__TEMPSENSOR_ADC_DATA__), \ + (__ADC_RESOLUTION__), \ + LL_ADC_RESOLUTION_12B) * \ + (__VREFANALOG_VOLTAGE__)) / \ + TEMPSENSOR_CAL_VREFANALOG) - \ + (int32_t)*TEMPSENSOR_CAL1_ADDR)) * \ + (int32_t)(TEMPSENSOR_CAL2_TEMP - TEMPSENSOR_CAL1_TEMP)) / \ + (int32_t)((int32_t)*TEMPSENSOR_CAL2_ADDR - (int32_t)*TEMPSENSOR_CAL1_ADDR)) + \ + TEMPSENSOR_CAL1_TEMP) + +/** + * @brief Helper macro to calculate the temperature (unit: degree Celsius) + * from ADC conversion data of internal temperature sensor. + * @note Computation is using temperature sensor typical values + * (refer to device datasheet). + * @note Calculation formula: + * Temperature = (TS_TYP_CALx_VOLT(uV) - TS_ADC_DATA * Conversion_uV) + * / Avg_Slope + CALx_TEMP + * with TS_ADC_DATA = temperature sensor raw data measured by ADC + * (unit: digital value) + * Avg_Slope = temperature sensor slope + * (unit: uV/Degree Celsius) + * TS_TYP_CALx_VOLT = temperature sensor digital value at + * temperature CALx_TEMP (unit: mV) + * Caution: Calculation relevancy under reserve the temperature sensor + * of the current device has characteristics in line with + * datasheet typical values. + * If temperature sensor calibration values are available on + * on this device (presence of macro __LL_ADC_CALC_TEMPERATURE()), + * temperature calculation will be more accurate using + * helper macro @ref __LL_ADC_CALC_TEMPERATURE(). + * @note As calculation input, the analog reference voltage (Vref+) must be + * defined as it impacts the ADC LSB equivalent voltage. + * @note Analog reference voltage (Vref+) must be either known from + * user board environment or can be calculated using ADC measurement + * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE(). + * @note ADC measurement data must correspond to a resolution of 12bits + * (full scale digital value 4095). If not the case, the data must be + * preliminarily rescaled to an equivalent resolution of 12 bits. + * @param __TEMPSENSOR_TYP_AVGSLOPE__ Device datasheet data: Temperature sensor slope + * typical value (unit: uV/DegCelsius). On STM32F0, refer to device datasheet parameter + * "Avg_Slope". + * @param __TEMPSENSOR_TYP_CALX_V__ Device datasheet data: Temperature sensor voltage + * typical value (at temperature and Vref+ defined in parameters below) (unit: mV). On + * STM32F0, refer to device datasheet parameter "V30" (corresponding to TS_CAL1). + * @param __TEMPSENSOR_CALX_TEMP__ Device datasheet data: Temperature at which + * temperature sensor voltage (see parameter above) is corresponding (unit: mV) + * @param __VREFANALOG_VOLTAGE__ Analog voltage reference (Vref+) voltage (unit: + * mV) + * @param __TEMPSENSOR_ADC_DATA__ ADC conversion data of internal temperature + * sensor (unit: digital value). + * @param __ADC_RESOLUTION__ ADC resolution at which internal temperature + * sensor voltage has been measured. This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval Temperature (unit: degree Celsius) + */ +#define __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS( \ + __TEMPSENSOR_TYP_AVGSLOPE__, __TEMPSENSOR_TYP_CALX_V__, __TEMPSENSOR_CALX_TEMP__, \ + __VREFANALOG_VOLTAGE__, __TEMPSENSOR_ADC_DATA__, __ADC_RESOLUTION__) \ + (((((int32_t)(((__TEMPSENSOR_TYP_CALX_V__)) * 1000) - \ + (int32_t)((((__TEMPSENSOR_ADC_DATA__) * (__VREFANALOG_VOLTAGE__)) / \ + __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)) * \ + 1000))) / \ + (__TEMPSENSOR_TYP_AVGSLOPE__)) + \ + (__TEMPSENSOR_CALX_TEMP__)) + + /** + * @} + */ + + /** + * @} + */ + + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup ADC_LL_Exported_Functions ADC Exported Functions + * @{ + */ + + /** @defgroup ADC_LL_EF_DMA_Management ADC DMA management + * @{ + */ + /* Note: LL ADC functions to set DMA transfer are located into sections of */ + /* configuration of ADC instance, groups and multimode (if available): */ + /* @ref LL_ADC_REG_SetDMATransfer(), ... */ + + /** + * @brief Function to help to configure DMA transfer from ADC: retrieve the + * ADC register address from ADC instance and a list of ADC registers + * intended to be used (most commonly) with DMA transfer. + * @note These ADC registers are data registers: + * when ADC conversion data is available in ADC data registers, + * ADC generates a DMA transfer request. + * @note This macro is intended to be used with LL DMA driver, refer to + * function "LL_DMA_ConfigAddresses()". + * Example: + * LL_DMA_ConfigAddresses(DMA1, + * LL_DMA_CHANNEL_1, + * LL_ADC_DMA_GetRegAddr(ADC1, + * LL_ADC_DMA_REG_REGULAR_DATA), (uint32_t)&< array or variable >, + * LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + * @note For devices with several ADC: in multimode, some devices + * use a different data register outside of ADC instance scope + * (common data register). This macro manages this register difference, + * only ADC instance has to be set as parameter. + * @rmtoll DR DATA LL_ADC_DMA_GetRegAddr + * @param ADCx ADC instance + * @param Register This parameter can be one of the following values: + * @arg @ref LL_ADC_DMA_REG_REGULAR_DATA + * @retval ADC register address + */ + __STATIC_INLINE uint32_t LL_ADC_DMA_GetRegAddr(ADC_TypeDef *ADCx, uint32_t Register) + { + /* Prevent unused argument compilation warning */ + (void)Register; + + /* Retrieve address of register DR */ + return (uint32_t) & (ADCx->DR); + } + + /** + * @} + */ + + /** @defgroup ADC_LL_EF_Configuration_ADC_Common Configuration of ADC hierarchical + * scope: common to several ADC instances + * @{ + */ + + /** + * @brief Set parameter common to several ADC: measurement path to internal + * channels (VrefInt, temperature sensor, ...). + * @note One or several values can be selected. + * Example: (LL_ADC_PATH_INTERNAL_VREFINT | + * LL_ADC_PATH_INTERNAL_TEMPSENSOR) + * @note Stabilization time of measurement path to internal channel: + * After enabling internal paths, before starting ADC conversion, + * a delay is required for internal voltage reference and + * temperature sensor stabilization time. + * Refer to device datasheet. + * Refer to literal @ref LL_ADC_DELAY_VREFINT_STAB_US. + * Refer to literal @ref LL_ADC_DELAY_TEMPSENSOR_STAB_US. + * @note ADC internal channel sampling time constraint: + * For ADC conversion of internal channels, + * a sampling time minimum value is required. + * Refer to device datasheet. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled. + * This check can be done with function @ref LL_ADC_IsEnabled() for each + * ADC instance or by using helper macro helper macro + * @ref __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(). + * @rmtoll CCR VREFEN LL_ADC_SetCommonPathInternalCh\n + * CCR TSEN LL_ADC_SetCommonPathInternalCh\n + * CCR VBATEN LL_ADC_SetCommonPathInternalCh + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref + * __LL_ADC_COMMON_INSTANCE() ) + * @param PathInternal This parameter can be a combination of the following values: + * @arg @ref LL_ADC_PATH_INTERNAL_NONE + * @arg @ref LL_ADC_PATH_INTERNAL_VREFINT + * @arg @ref LL_ADC_PATH_INTERNAL_TEMPSENSOR + * @arg @ref LL_ADC_PATH_INTERNAL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval None + */ + __STATIC_INLINE void LL_ADC_SetCommonPathInternalCh(ADC_Common_TypeDef *ADCxy_COMMON, + uint32_t PathInternal) + { +#if defined(ADC_CCR_VBATEN) + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_VREFEN | ADC_CCR_TSEN | ADC_CCR_VBATEN, + PathInternal); +#else + MODIFY_REG(ADCxy_COMMON->CCR, ADC_CCR_VREFEN | ADC_CCR_TSEN, PathInternal); +#endif + } + + /** + * @brief Get parameter common to several ADC: measurement path to internal + * channels (VrefInt, temperature sensor, ...). + * @note One or several values can be selected. + * Example: (LL_ADC_PATH_INTERNAL_VREFINT | + * LL_ADC_PATH_INTERNAL_TEMPSENSOR) + * @rmtoll CCR VREFEN LL_ADC_GetCommonPathInternalCh\n + * CCR TSEN LL_ADC_GetCommonPathInternalCh\n + * CCR VBATEN LL_ADC_GetCommonPathInternalCh + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref + * __LL_ADC_COMMON_INSTANCE() ) + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_ADC_PATH_INTERNAL_NONE + * @arg @ref LL_ADC_PATH_INTERNAL_VREFINT + * @arg @ref LL_ADC_PATH_INTERNAL_TEMPSENSOR + * @arg @ref LL_ADC_PATH_INTERNAL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + */ + __STATIC_INLINE uint32_t + LL_ADC_GetCommonPathInternalCh(ADC_Common_TypeDef *ADCxy_COMMON) + { +#if defined(ADC_CCR_VBATEN) + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, + ADC_CCR_VREFEN | ADC_CCR_TSEN | ADC_CCR_VBATEN)); +#else + return (uint32_t)(READ_BIT(ADCxy_COMMON->CCR, ADC_CCR_VREFEN | ADC_CCR_TSEN)); +#endif + } + + /** + * @} + */ + + /** @defgroup ADC_LL_EF_Configuration_ADC_Instance Configuration of ADC hierarchical + * scope: ADC instance + * @{ + */ + + /** + * @brief Set ADC instance clock source and prescaler. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled. + * @rmtoll CFGR2 CKMODE LL_ADC_SetClock + * @param ADCx ADC instance + * @param ClockSource This parameter can be one of the following values: + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV4 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV2 + * @arg @ref LL_ADC_CLOCK_ASYNC (1) + * + * (1) On this STM32 series, synchronous clock has no prescaler. + * @retval None + */ + __STATIC_INLINE void LL_ADC_SetClock(ADC_TypeDef *ADCx, uint32_t ClockSource) + { + MODIFY_REG(ADCx->CFGR2, ADC_CFGR2_CKMODE, ClockSource); + } + + /** + * @brief Get ADC instance clock source and prescaler. + * @rmtoll CFGR2 CKMODE LL_ADC_GetClock + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV4 + * @arg @ref LL_ADC_CLOCK_SYNC_PCLK_DIV2 + * @arg @ref LL_ADC_CLOCK_ASYNC (1) + * + * (1) On this STM32 series, synchronous clock has no prescaler. + */ + __STATIC_INLINE uint32_t LL_ADC_GetClock(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR2, ADC_CFGR2_CKMODE)); + } + + /** + * @brief Set ADC resolution. + * Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 RES LL_ADC_SetResolution + * @param ADCx ADC instance + * @param Resolution This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + * @retval None + */ + __STATIC_INLINE void LL_ADC_SetResolution(ADC_TypeDef *ADCx, uint32_t Resolution) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_RES, Resolution); + } + + /** + * @brief Get ADC resolution. + * Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CFGR1 RES LL_ADC_GetResolution + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @arg @ref LL_ADC_RESOLUTION_10B + * @arg @ref LL_ADC_RESOLUTION_8B + * @arg @ref LL_ADC_RESOLUTION_6B + */ + __STATIC_INLINE uint32_t LL_ADC_GetResolution(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, ADC_CFGR1_RES)); + } + + /** + * @brief Set ADC conversion data alignment. + * @note Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 ALIGN LL_ADC_SetDataAlignment + * @param ADCx ADC instance + * @param DataAlignment This parameter can be one of the following values: + * @arg @ref LL_ADC_DATA_ALIGN_RIGHT + * @arg @ref LL_ADC_DATA_ALIGN_LEFT + * @retval None + */ + __STATIC_INLINE void LL_ADC_SetDataAlignment(ADC_TypeDef *ADCx, + uint32_t DataAlignment) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_ALIGN, DataAlignment); + } + + /** + * @brief Get ADC conversion data alignment. + * @note Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CFGR1 ALIGN LL_ADC_GetDataAlignment + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_DATA_ALIGN_RIGHT + * @arg @ref LL_ADC_DATA_ALIGN_LEFT + */ + __STATIC_INLINE uint32_t LL_ADC_GetDataAlignment(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, ADC_CFGR1_ALIGN)); + } + + /** + * @brief Set ADC low power mode. + * @note Description of ADC low power modes: + * - ADC low power mode "auto wait": Dynamic low power mode, + * ADC conversions occurrences are limited to the minimum necessary + * in order to reduce power consumption. + * New ADC conversion starts only when the previous + * unitary conversion data (for ADC group regular) + * has been retrieved by user software. + * In the meantime, ADC remains idle: does not performs any + * other conversion. + * This mode allows to automatically adapt the ADC conversions + * triggers to the speed of the software that reads the data. + * Moreover, this avoids risk of overrun for low frequency + * applications. + * How to use this low power mode: + * - Do not use with interruption or DMA since these modes + * have to clear immediately the EOC flag to free the + * IRQ vector sequencer. + * - Do use with polling: 1. Start conversion, + * 2. Later on, when conversion data is needed: poll for end of + * conversion to ensure that conversion is completed and + * retrieve ADC conversion data. This will trig another + * ADC conversion start. + * - ADC low power mode "auto power-off" (feature available on + * this device if parameter LL_ADC_LP_MODE_AUTOOFF is available): + * the ADC automatically powers-off after a conversion and + * automatically wakes up when a new conversion is triggered + * (with startup time between trigger and start of sampling). + * This feature can be combined with low power mode "auto wait". + * @note With ADC low power mode "auto wait", the ADC conversion data read + * is corresponding to previous ADC conversion start, independently + * of delay during which ADC was idle. + * Therefore, the ADC conversion data may be outdated: does not + * correspond to the current voltage level on the selected + * ADC channel. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 WAIT LL_ADC_SetLowPowerMode\n + * CFGR1 AUTOFF LL_ADC_SetLowPowerMode + * @param ADCx ADC instance + * @param LowPowerMode This parameter can be one of the following values: + * @arg @ref LL_ADC_LP_MODE_NONE + * @arg @ref LL_ADC_LP_AUTOWAIT + * @arg @ref LL_ADC_LP_AUTOPOWEROFF + * @arg @ref LL_ADC_LP_AUTOWAIT_AUTOPOWEROFF + * @retval None + */ + __STATIC_INLINE void LL_ADC_SetLowPowerMode(ADC_TypeDef *ADCx, uint32_t LowPowerMode) + { + MODIFY_REG(ADCx->CFGR1, (ADC_CFGR1_WAIT | ADC_CFGR1_AUTOFF), LowPowerMode); + } + + /** + * @brief Get ADC low power mode: + * @note Description of ADC low power modes: + * - ADC low power mode "auto wait": Dynamic low power mode, + * ADC conversions occurrences are limited to the minimum necessary + * in order to reduce power consumption. + * New ADC conversion starts only when the previous + * unitary conversion data (for ADC group regular) + * has been retrieved by user software. + * In the meantime, ADC remains idle: does not performs any + * other conversion. + * This mode allows to automatically adapt the ADC conversions + * triggers to the speed of the software that reads the data. + * Moreover, this avoids risk of overrun for low frequency + * applications. + * How to use this low power mode: + * - Do not use with interruption or DMA since these modes + * have to clear immediately the EOC flag to free the + * IRQ vector sequencer. + * - Do use with polling: 1. Start conversion, + * 2. Later on, when conversion data is needed: poll for end of + * conversion to ensure that conversion is completed and + * retrieve ADC conversion data. This will trig another + * ADC conversion start. + * - ADC low power mode "auto power-off" (feature available on + * this device if parameter LL_ADC_LP_MODE_AUTOOFF is available): + * the ADC automatically powers-off after a conversion and + * automatically wakes up when a new conversion is triggered + * (with startup time between trigger and start of sampling). + * This feature can be combined with low power mode "auto wait". + * @note With ADC low power mode "auto wait", the ADC conversion data read + * is corresponding to previous ADC conversion start, independently + * of delay during which ADC was idle. + * Therefore, the ADC conversion data may be outdated: does not + * correspond to the current voltage level on the selected + * ADC channel. + * @rmtoll CFGR1 WAIT LL_ADC_GetLowPowerMode\n + * CFGR1 AUTOFF LL_ADC_GetLowPowerMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_LP_MODE_NONE + * @arg @ref LL_ADC_LP_AUTOWAIT + * @arg @ref LL_ADC_LP_AUTOPOWEROFF + * @arg @ref LL_ADC_LP_AUTOWAIT_AUTOPOWEROFF + */ + __STATIC_INLINE uint32_t LL_ADC_GetLowPowerMode(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, (ADC_CFGR1_WAIT | ADC_CFGR1_AUTOFF))); + } + + /** + * @brief Set sampling time common to a group of channels. + * @note Unit: ADC clock cycles. + * @note On this STM32 series, sampling time scope is on ADC instance: + * Sampling time common to all channels. + * (on some other STM32 families, sampling time is channel wise) + * @note In case of internal channel (VrefInt, TempSensor, ...) to be + * converted: + * sampling time constraints must be respected (sampling time can be + * adjusted in function of ADC clock frequency and sampling time + * setting). + * Refer to device datasheet for timings values (parameters TS_vrefint, + * TS_temp, ...). + * @note Conversion time is the addition of sampling time and processing time. + * On this STM32 series, ADC processing time is: + * - 12.5 ADC clock cycles at ADC resolution 12 bits + * - 10.5 ADC clock cycles at ADC resolution 10 bits + * - 8.5 ADC clock cycles at ADC resolution 8 bits + * - 6.5 ADC clock cycles at ADC resolution 6 bits + * @note In case of ADC conversion of internal channel (VrefInt, + * temperature sensor, ...), a sampling time minimum value + * is required. + * Refer to device datasheet. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll SMPR SMP LL_ADC_SetSamplingTimeCommonChannels + * @param ADCx ADC instance + * @param SamplingTime This parameter can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_1CYCLE_5 + * @arg @ref LL_ADC_SAMPLINGTIME_7CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_13CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_28CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_41CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_55CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_71CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_239CYCLES_5 + * @retval None + */ + __STATIC_INLINE void LL_ADC_SetSamplingTimeCommonChannels(ADC_TypeDef *ADCx, + uint32_t SamplingTime) + { + MODIFY_REG(ADCx->SMPR, ADC_SMPR_SMP, SamplingTime); + } + + /** + * @brief Get sampling time common to a group of channels. + * @note Unit: ADC clock cycles. + * @note On this STM32 series, sampling time scope is on ADC instance: + * Sampling time common to all channels. + * (on some other STM32 families, sampling time is channel wise) + * @note Conversion time is the addition of sampling time and processing time. + * Refer to reference manual for ADC processing time of + * this STM32 series. + * @rmtoll SMPR SMP LL_ADC_GetSamplingTimeCommonChannels + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_1CYCLE_5 + * @arg @ref LL_ADC_SAMPLINGTIME_7CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_13CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_28CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_41CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_55CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_71CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_239CYCLES_5 + */ + __STATIC_INLINE uint32_t LL_ADC_GetSamplingTimeCommonChannels(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->SMPR, ADC_SMPR_SMP)); + } + + /** + * @} + */ + + /** @defgroup ADC_LL_EF_Configuration_ADC_Group_Regular Configuration of ADC + * hierarchical scope: group regular + * @{ + */ + + /** + * @brief Set ADC group regular conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note On this STM32 series, setting trigger source to external trigger + * also set trigger polarity to rising edge + * (default setting for compatibility with some ADC on other + * STM32 families having this setting set by HW default value). + * In case of need to modify trigger edge, use + * function @ref LL_ADC_REG_SetTriggerEdge(). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 EXTSEL LL_ADC_REG_SetTriggerSource\n + * CFGR1 EXTEN LL_ADC_REG_SetTriggerSource + * @param ADCx ADC instance + * @param TriggerSource This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_SOFTWARE + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH4 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_TRGO (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM15_TRGO (1) + * + * (1) On STM32F0, parameter not available on all devices + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetTriggerSource(ADC_TypeDef *ADCx, + uint32_t TriggerSource) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_EXTEN | ADC_CFGR1_EXTSEL, TriggerSource); + } + + /** + * @brief Get ADC group regular conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note To determine whether group regular trigger source is + * internal (SW start) or external, without detail + * of which peripheral is selected as external trigger, + * (equivalent to + * "if(LL_ADC_REG_GetTriggerSource(ADC1) == LL_ADC_REG_TRIG_SOFTWARE)") + * use function @ref LL_ADC_REG_IsTriggerSourceSWStart. + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CFGR1 EXTSEL LL_ADC_REG_GetTriggerSource\n + * CFGR1 EXTEN LL_ADC_REG_GetTriggerSource + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_SOFTWARE + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH4 + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_TRGO (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM15_TRGO (1) + * + * (1) On STM32F0, parameter not available on all devices + */ + __STATIC_INLINE uint32_t LL_ADC_REG_GetTriggerSource(ADC_TypeDef *ADCx) + { + uint32_t TriggerSource = + READ_BIT(ADCx->CFGR1, ADC_CFGR1_EXTSEL | ADC_CFGR1_EXTEN); + + /* Value for shift of {0; 4; 8; 12} depending on value of bitfield */ + /* corresponding to ADC_CFGR1_EXTEN {0; 1; 2; 3}. */ + uint32_t ShiftExten = ((TriggerSource & ADC_CFGR1_EXTEN) >> + (ADC_REG_TRIG_EXTEN_BITOFFSET_POS - 2U)); + + /* Set bitfield corresponding to ADC_CFGR1_EXTEN and ADC_CFGR1_EXTSEL */ + /* to match with triggers literals definition. */ + return ((TriggerSource & (ADC_REG_TRIG_SOURCE_MASK >> ShiftExten) & + ADC_CFGR1_EXTSEL) | + ((ADC_REG_TRIG_EDGE_MASK >> ShiftExten) & ADC_CFGR1_EXTEN)); + } + + /** + * @brief Get ADC group regular conversion trigger source internal (SW start) + or external. + * @note In case of group regular trigger source set to external trigger, + * to determine which peripheral is selected as external trigger, + * use function @ref LL_ADC_REG_GetTriggerSource(). + * @rmtoll CFGR1 EXTEN LL_ADC_REG_IsTriggerSourceSWStart + * @param ADCx ADC instance + * @retval Value "0" if trigger source external trigger + * Value "1" if trigger source SW start. + */ + __STATIC_INLINE uint32_t LL_ADC_REG_IsTriggerSourceSWStart(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->CFGR1, ADC_CFGR1_EXTEN) == + (LL_ADC_REG_TRIG_SOFTWARE & ADC_CFGR1_EXTEN)); + } + + /** + * @brief Set ADC group regular conversion trigger polarity. + * @note Applicable only for trigger source set to external trigger. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 EXTEN LL_ADC_REG_SetTriggerEdge + * @param ADCx ADC instance + * @param ExternalTriggerEdge This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_EXT_RISING + * @arg @ref LL_ADC_REG_TRIG_EXT_FALLING + * @arg @ref LL_ADC_REG_TRIG_EXT_RISINGFALLING + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetTriggerEdge(ADC_TypeDef *ADCx, + uint32_t ExternalTriggerEdge) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_EXTEN, ExternalTriggerEdge); + } + + /** + * @brief Get ADC group regular conversion trigger polarity. + * @note Applicable only for trigger source set to external trigger. + * @rmtoll CFGR1 EXTEN LL_ADC_REG_GetTriggerEdge + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_EXT_RISING + * @arg @ref LL_ADC_REG_TRIG_EXT_FALLING + * @arg @ref LL_ADC_REG_TRIG_EXT_RISINGFALLING + */ + __STATIC_INLINE uint32_t LL_ADC_REG_GetTriggerEdge(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, ADC_CFGR1_EXTEN)); + } + + + /** + * @brief Set ADC group regular sequencer scan direction. + * @note On some other STM32 families, this setting is not available and + * the default scan direction is forward. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 SCANDIR LL_ADC_REG_SetSequencerScanDirection + * @param ADCx ADC instance + * @param ScanDirection This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_SCAN_DIR_FORWARD + * @arg @ref LL_ADC_REG_SEQ_SCAN_DIR_BACKWARD + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetSequencerScanDirection(ADC_TypeDef *ADCx, + uint32_t ScanDirection) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_SCANDIR, ScanDirection); + } + + /** + * @brief Get ADC group regular sequencer scan direction. + * @note On some other STM32 families, this setting is not available and + * the default scan direction is forward. + * @rmtoll CFGR1 SCANDIR LL_ADC_REG_GetSequencerScanDirection + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_SCAN_DIR_FORWARD + * @arg @ref LL_ADC_REG_SEQ_SCAN_DIR_BACKWARD + */ + __STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerScanDirection(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, ADC_CFGR1_SCANDIR)); + } + + /** + * @brief Set ADC group regular sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @note It is not possible to enable both ADC group regular + * continuous mode and sequencer discontinuous mode. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 DISCEN LL_ADC_REG_SetSequencerDiscont\n + * @param ADCx ADC instance + * @param SeqDiscont This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_REG_SEQ_DISCONT_1RANK + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetSequencerDiscont(ADC_TypeDef *ADCx, + uint32_t SeqDiscont) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_DISCEN, SeqDiscont); + } + + /** + * @brief Get ADC group regular sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @rmtoll CFGR1 DISCEN LL_ADC_REG_GetSequencerDiscont\n + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_REG_SEQ_DISCONT_1RANK + */ + __STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerDiscont(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, ADC_CFGR1_DISCEN)); + } + + /** + * @brief Set ADC group regular sequence: channel on rank corresponding to + * channel number. + * @note This function performs: + * - Channels ordering into each rank of scan sequence: + * rank of each channel is fixed by channel HW number + * (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + * - Set channels selected by overwriting the current sequencer + * configuration. + * @note On this STM32 series, ADC group regular sequencer is + * not fully configurable: sequencer length and each rank + * affectation to a channel are fixed by channel HW number. + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note On this STM32 series, to measure internal channels (VrefInt, + * TempSensor, ...), measurement paths to internal channels must be + * enabled separately. + * This can be done using function @ref LL_ADC_SetCommonPathInternalCh(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @note One or several values can be selected. + * Example: (LL_ADC_CHANNEL_4 | LL_ADC_CHANNEL_12 | ...) + * @rmtoll CHSELR CHSEL0 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL1 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL2 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL3 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL4 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL5 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL6 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL7 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL8 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL9 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL10 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL11 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL12 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL13 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL14 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL15 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL16 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL17 LL_ADC_REG_SetSequencerChannels\n + * CHSELR CHSEL18 LL_ADC_REG_SetSequencerChannels + * @param ADCx ADC instance + * @param Channel This parameter can be a combination of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetSequencerChannels(ADC_TypeDef *ADCx, + uint32_t Channel) + { + /* Parameter "Channel" is used with masks because containing */ + /* other bits reserved for other purpose. */ + WRITE_REG(ADCx->CHSELR, (Channel & ADC_CHANNEL_ID_BITFIELD_MASK)); + } + + /** + * @brief Add channel to ADC group regular sequence: channel on rank corresponding to + * channel number. + * @note This function performs: + * - Channels ordering into each rank of scan sequence: + * rank of each channel is fixed by channel HW number + * (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + * - Set channels selected by adding them to the current sequencer + * configuration. + * @note On this STM32 series, ADC group regular sequencer is + * not fully configurable: sequencer length and each rank + * affectation to a channel are fixed by channel HW number. + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note On this STM32 series, to measure internal channels (VrefInt, + * TempSensor, ...), measurement paths to internal channels must be + * enabled separately. + * This can be done using function @ref LL_ADC_SetCommonPathInternalCh(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @note One or several values can be selected. + * Example: (LL_ADC_CHANNEL_4 | LL_ADC_CHANNEL_12 | ...) + * @rmtoll CHSELR CHSEL0 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL1 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL2 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL3 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL4 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL5 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL6 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL7 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL8 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL9 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL10 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL11 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL12 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL13 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL14 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL15 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL16 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL17 LL_ADC_REG_SetSequencerChAdd\n + * CHSELR CHSEL18 LL_ADC_REG_SetSequencerChAdd + * @param ADCx ADC instance + * @param Channel This parameter can be a combination of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetSequencerChAdd(ADC_TypeDef *ADCx, uint32_t Channel) + { + /* Parameter "Channel" is used with masks because containing */ + /* other bits reserved for other purpose. */ + SET_BIT(ADCx->CHSELR, (Channel & ADC_CHANNEL_ID_BITFIELD_MASK)); + } + + /** + * @brief Remove channel to ADC group regular sequence: channel on rank corresponding + * to channel number. + * @note This function performs: + * - Channels ordering into each rank of scan sequence: + * rank of each channel is fixed by channel HW number + * (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + * - Set channels selected by removing them to the current sequencer + * configuration. + * @note On this STM32 series, ADC group regular sequencer is + * not fully configurable: sequencer length and each rank + * affectation to a channel are fixed by channel HW number. + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note On this STM32 series, to measure internal channels (VrefInt, + * TempSensor, ...), measurement paths to internal channels must be + * enabled separately. + * This can be done using function @ref LL_ADC_SetCommonPathInternalCh(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @note One or several values can be selected. + * Example: (LL_ADC_CHANNEL_4 | LL_ADC_CHANNEL_12 | ...) + * @rmtoll CHSELR CHSEL0 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL1 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL2 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL3 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL4 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL5 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL6 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL7 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL8 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL9 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL10 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL11 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL12 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL13 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL14 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL15 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL16 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL17 LL_ADC_REG_SetSequencerChRem\n + * CHSELR CHSEL18 LL_ADC_REG_SetSequencerChRem + * @param ADCx ADC instance + * @param Channel This parameter can be a combination of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetSequencerChRem(ADC_TypeDef *ADCx, uint32_t Channel) + { + /* Parameter "Channel" is used with masks because containing */ + /* other bits reserved for other purpose. */ + CLEAR_BIT(ADCx->CHSELR, (Channel & ADC_CHANNEL_ID_BITFIELD_MASK)); + } + + /** + * @brief Get ADC group regular sequence: channel on rank corresponding to + * channel number. + * @note This function performs: + * - Channels order reading into each rank of scan sequence: + * rank of each channel is fixed by channel HW number + * (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + * @note On this STM32 series, ADC group regular sequencer is + * not fully configurable: sequencer length and each rank + * affectation to a channel are fixed by channel HW number. + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note On this STM32 series, to measure internal channels (VrefInt, + * TempSensor, ...), measurement paths to internal channels must be + * enabled separately. + * This can be done using function @ref LL_ADC_SetCommonPathInternalCh(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @note One or several values can be retrieved. + * Example: (LL_ADC_CHANNEL_4 | LL_ADC_CHANNEL_12 | ...) + * @rmtoll CHSELR CHSEL0 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL1 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL2 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL3 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL4 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL5 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL6 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL7 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL8 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL9 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL10 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL11 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL12 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL13 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL14 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL15 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL16 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL17 LL_ADC_REG_GetSequencerChannels\n + * CHSELR CHSEL18 LL_ADC_REG_GetSequencerChannels + * @param ADCx ADC instance + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_18 (1) + * @arg @ref LL_ADC_CHANNEL_VREFINT + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR + * @arg @ref LL_ADC_CHANNEL_VBAT (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + */ + __STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerChannels(ADC_TypeDef *ADCx) + { + uint32_t ChannelsBitfield = READ_BIT(ADCx->CHSELR, ADC_CHSELR_CHSEL); + + return ( + (((ChannelsBitfield & ADC_CHSELR_CHSEL0) >> ADC_CHSELR_CHSEL0_BITOFFSET_POS) * + LL_ADC_CHANNEL_0) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL1) >> ADC_CHSELR_CHSEL1_BITOFFSET_POS) * + LL_ADC_CHANNEL_1) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL2) >> ADC_CHSELR_CHSEL2_BITOFFSET_POS) * + LL_ADC_CHANNEL_2) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL3) >> ADC_CHSELR_CHSEL3_BITOFFSET_POS) * + LL_ADC_CHANNEL_3) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL4) >> ADC_CHSELR_CHSEL4_BITOFFSET_POS) * + LL_ADC_CHANNEL_4) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL5) >> ADC_CHSELR_CHSEL5_BITOFFSET_POS) * + LL_ADC_CHANNEL_5) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL6) >> ADC_CHSELR_CHSEL6_BITOFFSET_POS) * + LL_ADC_CHANNEL_6) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL7) >> ADC_CHSELR_CHSEL7_BITOFFSET_POS) * + LL_ADC_CHANNEL_7) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL8) >> ADC_CHSELR_CHSEL8_BITOFFSET_POS) * + LL_ADC_CHANNEL_8) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL9) >> ADC_CHSELR_CHSEL9_BITOFFSET_POS) * + LL_ADC_CHANNEL_9) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL10) >> + ADC_CHSELR_CHSEL10_BITOFFSET_POS) * + LL_ADC_CHANNEL_10) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL11) >> + ADC_CHSELR_CHSEL11_BITOFFSET_POS) * + LL_ADC_CHANNEL_11) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL12) >> + ADC_CHSELR_CHSEL12_BITOFFSET_POS) * + LL_ADC_CHANNEL_12) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL13) >> + ADC_CHSELR_CHSEL13_BITOFFSET_POS) * + LL_ADC_CHANNEL_13) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL14) >> + ADC_CHSELR_CHSEL14_BITOFFSET_POS) * + LL_ADC_CHANNEL_14) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL15) >> + ADC_CHSELR_CHSEL15_BITOFFSET_POS) * + LL_ADC_CHANNEL_15) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL16) >> + ADC_CHSELR_CHSEL16_BITOFFSET_POS) * + LL_ADC_CHANNEL_16) | + (((ChannelsBitfield & ADC_CHSELR_CHSEL17) >> + ADC_CHSELR_CHSEL17_BITOFFSET_POS) * + LL_ADC_CHANNEL_17) +#if defined(ADC_CCR_VBATEN) + | (((ChannelsBitfield & ADC_CHSELR_CHSEL18) >> + ADC_CHSELR_CHSEL18_BITOFFSET_POS) * + LL_ADC_CHANNEL_18) +#endif + ); + } + /** + * @brief Set ADC continuous conversion mode on ADC group regular. + * @note Description of ADC continuous conversion mode: + * - single mode: one conversion per trigger + * - continuous mode: after the first trigger, following + * conversions launched successively automatically. + * @note It is not possible to enable both ADC group regular + * continuous mode and sequencer discontinuous mode. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 CONT LL_ADC_REG_SetContinuousMode + * @param ADCx ADC instance + * @param Continuous This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_CONV_SINGLE + * @arg @ref LL_ADC_REG_CONV_CONTINUOUS + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetContinuousMode(ADC_TypeDef *ADCx, + uint32_t Continuous) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_CONT, Continuous); + } + + /** + * @brief Get ADC continuous conversion mode on ADC group regular. + * @note Description of ADC continuous conversion mode: + * - single mode: one conversion per trigger + * - continuous mode: after the first trigger, following + * conversions launched successively automatically. + * @rmtoll CFGR1 CONT LL_ADC_REG_GetContinuousMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_CONV_SINGLE + * @arg @ref LL_ADC_REG_CONV_CONTINUOUS + */ + __STATIC_INLINE uint32_t LL_ADC_REG_GetContinuousMode(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, ADC_CFGR1_CONT)); + } + + /** + * @brief Set ADC group regular conversion data transfer: no transfer or + * transfer by DMA, and DMA requests mode. + * @note If transfer by DMA selected, specifies the DMA requests + * mode: + * - Limited mode (One shot mode): DMA transfer requests are stopped + * when number of DMA data transfers (number of + * ADC conversions) is reached. + * This ADC mode is intended to be used with DMA mode non-circular. + * - Unlimited mode: DMA transfer requests are unlimited, + * whatever number of DMA data transfers (number of + * ADC conversions). + * This ADC mode is intended to be used with DMA mode circular. + * @note If ADC DMA requests mode is set to unlimited and DMA is set to + * mode non-circular: + * when DMA transfers size will be reached, DMA will stop transfers of + * ADC conversions data ADC will raise an overrun error + * (overrun flag and interruption if enabled). + * @note To configure DMA source address (peripheral address), + * use function @ref LL_ADC_DMA_GetRegAddr(). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 DMAEN LL_ADC_REG_SetDMATransfer\n + * CFGR1 DMACFG LL_ADC_REG_SetDMATransfer + * @param ADCx ADC instance + * @param DMATransfer This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_DMA_TRANSFER_NONE + * @arg @ref LL_ADC_REG_DMA_TRANSFER_LIMITED + * @arg @ref LL_ADC_REG_DMA_TRANSFER_UNLIMITED + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetDMATransfer(ADC_TypeDef *ADCx, + uint32_t DMATransfer) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG, DMATransfer); + } + + /** + * @brief Get ADC group regular conversion data transfer: no transfer or + * transfer by DMA, and DMA requests mode. + * @note If transfer by DMA selected, specifies the DMA requests + * mode: + * - Limited mode (One shot mode): DMA transfer requests are stopped + * when number of DMA data transfers (number of + * ADC conversions) is reached. + * This ADC mode is intended to be used with DMA mode non-circular. + * - Unlimited mode: DMA transfer requests are unlimited, + * whatever number of DMA data transfers (number of + * ADC conversions). + * This ADC mode is intended to be used with DMA mode circular. + * @note If ADC DMA requests mode is set to unlimited and DMA is set to + * mode non-circular: + * when DMA transfers size will be reached, DMA will stop transfers of + * ADC conversions data ADC will raise an overrun error + * (overrun flag and interruption if enabled). + * @note To configure DMA source address (peripheral address), + * use function @ref LL_ADC_DMA_GetRegAddr(). + * @rmtoll CFGR1 DMAEN LL_ADC_REG_GetDMATransfer\n + * CFGR1 DMACFG LL_ADC_REG_GetDMATransfer + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_DMA_TRANSFER_NONE + * @arg @ref LL_ADC_REG_DMA_TRANSFER_LIMITED + * @arg @ref LL_ADC_REG_DMA_TRANSFER_UNLIMITED + */ + __STATIC_INLINE uint32_t LL_ADC_REG_GetDMATransfer(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG)); + } + + /** + * @brief Set ADC group regular behavior in case of overrun: + * data preserved or overwritten. + * @note Compatibility with devices without feature overrun: + * other devices without this feature have a behavior + * equivalent to data overwritten. + * The default setting of overrun is data preserved. + * Therefore, for compatibility with all devices, parameter + * overrun should be set to data overwritten. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 OVRMOD LL_ADC_REG_SetOverrun + * @param ADCx ADC instance + * @param Overrun This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_OVR_DATA_PRESERVED + * @arg @ref LL_ADC_REG_OVR_DATA_OVERWRITTEN + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_SetOverrun(ADC_TypeDef *ADCx, uint32_t Overrun) + { + MODIFY_REG(ADCx->CFGR1, ADC_CFGR1_OVRMOD, Overrun); + } + + /** + * @brief Get ADC group regular behavior in case of overrun: + * data preserved or overwritten. + * @rmtoll CFGR1 OVRMOD LL_ADC_REG_GetOverrun + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_OVR_DATA_PRESERVED + * @arg @ref LL_ADC_REG_OVR_DATA_OVERWRITTEN + */ + __STATIC_INLINE uint32_t LL_ADC_REG_GetOverrun(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->CFGR1, ADC_CFGR1_OVRMOD)); + } + + /** + * @} + */ + + + /** @defgroup ADC_LL_EF_Configuration_ADC_AnalogWatchdog Configuration of ADC + * transversal scope: analog watchdog + * @{ + */ + + /** + * @brief Set ADC analog watchdog monitored channels: + * a single channel or all channels, + * on ADC group regular. + * @note Once monitored channels are selected, analog watchdog + * is enabled. + * @note In case of need to define a single channel to monitor + * with analog watchdog from sequencer channel definition, + * use helper macro @ref __LL_ADC_ANALOGWD_CHANNEL_GROUP(). + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC group regular. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 AWDCH LL_ADC_SetAnalogWDMonitChannels\n + * CFGR1 AWDSGL LL_ADC_SetAnalogWDMonitChannels\n + * CFGR1 AWDEN LL_ADC_SetAnalogWDMonitChannels + * @param ADCx ADC instance + * @param AWDChannelGroup This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG + * @arg @ref LL_ADC_AWD_CH_VBAT_REG (1) + * + * (1) On STM32F0, parameter not available on all devices: all devices except + * STM32F030x6, STM32F030x8, STM32F030xC, STM32F070x6, STM32F070xB. + * @retval None + */ + __STATIC_INLINE void LL_ADC_SetAnalogWDMonitChannels(ADC_TypeDef *ADCx, + uint32_t AWDChannelGroup) + { + MODIFY_REG(ADCx->CFGR1, (ADC_CFGR1_AWDCH | ADC_CFGR1_AWDSGL | ADC_CFGR1_AWDEN), + (AWDChannelGroup & ADC_AWD_CR_ALL_CHANNEL_MASK)); + } + + /** + * @brief Get ADC analog watchdog monitored channel. + * @note Usage of the returned channel number: + * - To reinject this channel into another function LL_ADC_xxx: + * the returned channel number is only partly formatted on definition + * of literals LL_ADC_CHANNEL_x. Therefore, it has to be compared + * with parts of literals LL_ADC_CHANNEL_x or using + * helper macro @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Then the selected literal LL_ADC_CHANNEL_x can be used + * as parameter for another function. + * - To get the channel number in decimal format: + * process the returned value with the helper macro + * @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Applicable only when the analog watchdog is set to monitor + * one channel. + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC group regular. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll CFGR1 AWDCH LL_ADC_GetAnalogWDMonitChannels\n + * CFGR1 AWDSGL LL_ADC_GetAnalogWDMonitChannels\n + * CFGR1 AWDEN LL_ADC_GetAnalogWDMonitChannels + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_18_REG + */ + __STATIC_INLINE uint32_t LL_ADC_GetAnalogWDMonitChannels(ADC_TypeDef *ADCx) + { + uint32_t AWDChannelGroup = + READ_BIT(ADCx->CFGR1, (ADC_CFGR1_AWDCH | ADC_CFGR1_AWDSGL | ADC_CFGR1_AWDEN)); + + /* Note: Set variable according to channel definition including channel ID */ + /* with bitfield. */ + uint32_t AWDChannelSingle = + ((AWDChannelGroup & ADC_CFGR1_AWDSGL) >> ADC_CFGR1_AWDSGL_BITOFFSET_POS); + uint32_t AWDChannelBitField = + (ADC_CHANNEL_0_BITFIELD << ((AWDChannelGroup & ADC_CHANNEL_ID_NUMBER_MASK) >> + ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS)); + + return (AWDChannelGroup | (AWDChannelBitField * AWDChannelSingle)); + } + + /** + * @brief Set ADC analog watchdog thresholds value of both thresholds + * high and low. + * @note If value of only one threshold high or low must be set, + * use function @ref LL_ADC_SetAnalogWDThresholds(). + * @note In case of ADC resolution different of 12 bits, + * analog watchdog thresholds data require a specific shift. + * Use helper macro @ref __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(). + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC group regular. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll TR HT LL_ADC_ConfigAnalogWDThresholds\n + * TR LT LL_ADC_ConfigAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDThresholdHighValue Value between Min_Data=0x000 and Max_Data=0xFFF + * @param AWDThresholdLowValue Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ + __STATIC_INLINE void LL_ADC_ConfigAnalogWDThresholds(ADC_TypeDef *ADCx, + uint32_t AWDThresholdHighValue, + uint32_t AWDThresholdLowValue) + { + MODIFY_REG( + ADCx->TR, ADC_TR_HT | ADC_TR_LT, + (AWDThresholdHighValue << ADC_TR_HT_BITOFFSET_POS) | AWDThresholdLowValue); + } + + /** + * @brief Set ADC analog watchdog threshold value of threshold + * high or low. + * @note If values of both thresholds high or low must be set, + * use function @ref LL_ADC_ConfigAnalogWDThresholds(). + * @note In case of ADC resolution different of 12 bits, + * analog watchdog thresholds data require a specific shift. + * Use helper macro @ref __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(). + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC group regular. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be disabled or enabled without conversion on going + * on group regular. + * @rmtoll TR HT LL_ADC_SetAnalogWDThresholds\n + * TR LT LL_ADC_SetAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDThresholdsHighLow This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_THRESHOLD_HIGH + * @arg @ref LL_ADC_AWD_THRESHOLD_LOW + * @param AWDThresholdValue Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ + __STATIC_INLINE void LL_ADC_SetAnalogWDThresholds(ADC_TypeDef *ADCx, + uint32_t AWDThresholdsHighLow, + uint32_t AWDThresholdValue) + { + /* Parameter "AWDThresholdsHighLow" is used with mask "0x00000010" */ + /* to be equivalent to "POSITION_VAL(AWDThresholdsHighLow)": if threshold */ + /* high is selected, then data is shifted to LSB. Else(threshold low), */ + /* data is not shifted. */ + MODIFY_REG( + ADCx->TR, AWDThresholdsHighLow, + AWDThresholdValue << ((AWDThresholdsHighLow >> ADC_TR_HT_BITOFFSET_POS) & + 0x00000010U)); + } + + /** + * @brief Get ADC analog watchdog threshold value of threshold high, + * threshold low or raw data with ADC thresholds high and low + * concatenated. + * @note If raw data with ADC thresholds high and low is retrieved, + * the data of each threshold high or low can be isolated + * using helper macro: + * @ref __LL_ADC_ANALOGWD_THRESHOLDS_HIGH_LOW(). + * @note In case of ADC resolution different of 12 bits, + * analog watchdog thresholds data require a specific shift. + * Use helper macro @ref __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION(). + * @rmtoll TR1 HT1 LL_ADC_GetAnalogWDThresholds\n + * TR2 HT2 LL_ADC_GetAnalogWDThresholds\n + * TR3 HT3 LL_ADC_GetAnalogWDThresholds\n + * TR1 LT1 LL_ADC_GetAnalogWDThresholds\n + * TR2 LT2 LL_ADC_GetAnalogWDThresholds\n + * TR3 LT3 LL_ADC_GetAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDThresholdsHighLow This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_THRESHOLD_HIGH + * @arg @ref LL_ADC_AWD_THRESHOLD_LOW + * @arg @ref LL_ADC_AWD_THRESHOLDS_HIGH_LOW + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ + __STATIC_INLINE uint32_t LL_ADC_GetAnalogWDThresholds(ADC_TypeDef *ADCx, + uint32_t AWDThresholdsHighLow) + { + /* Parameter "AWDThresholdsHighLow" is used with mask "0x00000010" */ + /* to be equivalent to "POSITION_VAL(AWDThresholdsHighLow)": if threshold */ + /* high is selected, then data is shifted to LSB. Else(threshold low or */ + /* both thresholds), data is not shifted. */ + return (uint32_t)(READ_BIT(ADCx->TR, (AWDThresholdsHighLow | ADC_TR_LT)) >> + ((~AWDThresholdsHighLow) & 0x00000010U)); + } + + /** + * @} + */ + + /** @defgroup ADC_LL_EF_Operation_ADC_Instance Operation on ADC hierarchical scope: + * ADC instance + * @{ + */ + + /** + * @brief Enable the selected ADC instance. + * @note On this STM32 series, after ADC enable, a delay for + * ADC internal analog stabilization is required before performing a + * ADC conversion start. + * Refer to device datasheet, parameter tSTAB. + * @note On this STM32 series, flag LL_ADC_FLAG_ADRDY is raised when the ADC + * is enabled and when conversion clock is active. + * (not only core clock: this ADC has a dual clock domain) + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled and ADC internal voltage regulator enabled. + * @rmtoll CR ADEN LL_ADC_Enable + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_Enable(ADC_TypeDef *ADCx) + { + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, ADC_CR_BITS_PROPERTY_RS, ADC_CR_ADEN); + } + + /** + * @brief Disable the selected ADC instance. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be not disabled. Must be enabled without conversion on going + * on group regular. + * @rmtoll CR ADDIS LL_ADC_Disable + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_Disable(ADC_TypeDef *ADCx) + { + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, ADC_CR_BITS_PROPERTY_RS, ADC_CR_ADDIS); + } + + /** + * @brief Get the selected ADC instance enable state. + * @note On this STM32 series, flag LL_ADC_FLAG_ADRDY is raised when the ADC + * is enabled and when conversion clock is active. + * (not only core clock: this ADC has a dual clock domain) + * @rmtoll CR ADEN LL_ADC_IsEnabled + * @param ADCx ADC instance + * @retval 0: ADC is disabled, 1: ADC is enabled. + */ + __STATIC_INLINE uint32_t LL_ADC_IsEnabled(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->CR, ADC_CR_ADEN) == (ADC_CR_ADEN)); + } + + /** + * @brief Get the selected ADC instance disable state. + * @rmtoll CR ADDIS LL_ADC_IsDisableOngoing + * @param ADCx ADC instance + * @retval 0: no ADC disable command on going. + */ + __STATIC_INLINE uint32_t LL_ADC_IsDisableOngoing(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->CR, ADC_CR_ADDIS) == (ADC_CR_ADDIS)); + } + + /** + * @brief Start ADC calibration in the mode single-ended + * or differential (for devices with differential mode available). + * @note On this STM32 series, a minimum number of ADC clock cycles + * are required between ADC end of calibration and ADC enable. + * Refer to literal @ref LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES. + * @note In case of usage of ADC with DMA transfer: + * On this STM32 series, ADC DMA transfer request should be disabled + * during calibration: + * Calibration factor is available in data register + * and also transferred by DMA. + * To not insert ADC calibration factor among ADC conversion data + * in array variable, DMA transfer must be disabled during + * calibration. + * (DMA transfer setting backup and disable before calibration, + * DMA transfer setting restore after calibration. + * Refer to functions @ref LL_ADC_REG_GetDMATransfer(), + * @ref LL_ADC_REG_SetDMATransfer() ). + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be ADC disabled. + * @rmtoll CR ADCAL LL_ADC_StartCalibration + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_StartCalibration(ADC_TypeDef *ADCx) + { + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, ADC_CR_BITS_PROPERTY_RS, ADC_CR_ADCAL); + } + + /** + * @brief Get ADC calibration state. + * @rmtoll CR ADCAL LL_ADC_IsCalibrationOnGoing + * @param ADCx ADC instance + * @retval 0: calibration complete, 1: calibration in progress. + */ + __STATIC_INLINE uint32_t LL_ADC_IsCalibrationOnGoing(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->CR, ADC_CR_ADCAL) == (ADC_CR_ADCAL)); + } + + /** + * @} + */ + + /** @defgroup ADC_LL_EF_Operation_ADC_Group_Regular Operation on ADC hierarchical + * scope: group regular + * @{ + */ + + /** + * @brief Start ADC group regular conversion. + * @note On this STM32 series, this function is relevant for both + * internal trigger (SW start) and external trigger: + * - If ADC trigger has been set to software start, ADC conversion + * starts immediately. + * - If ADC trigger has been set to external trigger, ADC conversion + * will start at next trigger event (on the selected trigger edge) + * following the ADC start conversion command. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled without conversion on going on group regular, + * without conversion stop command on going on group regular, + * without ADC disable command on going. + * @rmtoll CR ADSTART LL_ADC_REG_StartConversion + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_StartConversion(ADC_TypeDef *ADCx) + { + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, ADC_CR_BITS_PROPERTY_RS, ADC_CR_ADSTART); + } + + /** + * @brief Stop ADC group regular conversion. + * @note On this STM32 series, setting of this feature is conditioned to + * ADC state: + * ADC must be enabled with conversion on going on group regular, + * without ADC disable command on going. + * @rmtoll CR ADSTP LL_ADC_REG_StopConversion + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_REG_StopConversion(ADC_TypeDef *ADCx) + { + /* Note: Write register with some additional bits forced to state reset */ + /* instead of modifying only the selected bit for this function, */ + /* to not interfere with bits with HW property "rs". */ + MODIFY_REG(ADCx->CR, ADC_CR_BITS_PROPERTY_RS, ADC_CR_ADSTP); + } + + /** + * @brief Get ADC group regular conversion state. + * @rmtoll CR ADSTART LL_ADC_REG_IsConversionOngoing + * @param ADCx ADC instance + * @retval 0: no conversion is on going on ADC group regular. + */ + __STATIC_INLINE uint32_t LL_ADC_REG_IsConversionOngoing(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->CR, ADC_CR_ADSTART) == (ADC_CR_ADSTART)); + } + + /** + * @brief Get ADC group regular command of conversion stop state + * @rmtoll CR ADSTP LL_ADC_REG_IsStopConversionOngoing + * @param ADCx ADC instance + * @retval 0: no command of conversion stop is on going on ADC group regular. + */ + __STATIC_INLINE uint32_t LL_ADC_REG_IsStopConversionOngoing(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->CR, ADC_CR_ADSTP) == (ADC_CR_ADSTP)); + } + + /** + * @brief Get ADC group regular conversion data, range fit for + * all ADC configurations: all ADC resolutions and + * all oversampling increased data width (for devices + * with feature oversampling). + * @rmtoll DR DATA LL_ADC_REG_ReadConversionData32 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ + __STATIC_INLINE uint32_t LL_ADC_REG_ReadConversionData32(ADC_TypeDef *ADCx) + { + return (uint32_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); + } + + /** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 12 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR DATA LL_ADC_REG_ReadConversionData12 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ + __STATIC_INLINE uint16_t LL_ADC_REG_ReadConversionData12(ADC_TypeDef *ADCx) + { + return (uint16_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); + } + + /** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 10 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR DATA LL_ADC_REG_ReadConversionData10 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x000 and Max_Data=0x3FF + */ + __STATIC_INLINE uint16_t LL_ADC_REG_ReadConversionData10(ADC_TypeDef *ADCx) + { + return (uint16_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); + } + + /** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 8 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR DATA LL_ADC_REG_ReadConversionData8 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ + __STATIC_INLINE uint8_t LL_ADC_REG_ReadConversionData8(ADC_TypeDef *ADCx) + { + return (uint8_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); + } + + /** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 6 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR DATA LL_ADC_REG_ReadConversionData6 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00 and Max_Data=0x3F + */ + __STATIC_INLINE uint8_t LL_ADC_REG_ReadConversionData6(ADC_TypeDef *ADCx) + { + return (uint8_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); + } + + /** + * @} + */ + + /** @defgroup ADC_LL_EF_FLAG_Management ADC flag management + * @{ + */ + + /** + * @brief Get flag ADC ready. + * @note On this STM32 series, flag LL_ADC_FLAG_ADRDY is raised when the ADC + * is enabled and when conversion clock is active. + * (not only core clock: this ADC has a dual clock domain) + * @rmtoll ISR ADRDY LL_ADC_IsActiveFlag_ADRDY + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_ADRDY(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->ISR, LL_ADC_FLAG_ADRDY) == (LL_ADC_FLAG_ADRDY)); + } + + /** + * @brief Get flag ADC group regular end of unitary conversion. + * @rmtoll ISR EOC LL_ADC_IsActiveFlag_EOC + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_EOC(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->ISR, ADC_ISR_EOC) == (ADC_ISR_EOC)); + } + + /** + * @brief Get flag ADC group regular end of sequence conversions. + * @rmtoll ISR EOSEQ LL_ADC_IsActiveFlag_EOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_EOS(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->ISR, LL_ADC_FLAG_EOS) == (LL_ADC_FLAG_EOS)); + } + + /** + * @brief Get flag ADC group regular overrun. + * @rmtoll ISR OVR LL_ADC_IsActiveFlag_OVR + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_OVR(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->ISR, LL_ADC_FLAG_OVR) == (LL_ADC_FLAG_OVR)); + } + + /** + * @brief Get flag ADC group regular end of sampling phase. + * @rmtoll ISR EOSMP LL_ADC_IsActiveFlag_EOSMP + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_EOSMP(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->ISR, LL_ADC_FLAG_EOSMP) == (LL_ADC_FLAG_EOSMP)); + } + + /** + * @brief Get flag ADC analog watchdog 1 flag + * @rmtoll ISR AWD LL_ADC_IsActiveFlag_AWD1 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_AWD1(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->ISR, LL_ADC_FLAG_AWD1) == (LL_ADC_FLAG_AWD1)); + } + + /** + * @brief Clear flag ADC ready. + * @note On this STM32 series, flag LL_ADC_FLAG_ADRDY is raised when the ADC + * is enabled and when conversion clock is active. + * (not only core clock: this ADC has a dual clock domain) + * @rmtoll ISR ADRDY LL_ADC_ClearFlag_ADRDY + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_ClearFlag_ADRDY(ADC_TypeDef *ADCx) + { + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_ADRDY); + } + + /** + * @brief Clear flag ADC group regular end of unitary conversion. + * @rmtoll ISR EOC LL_ADC_ClearFlag_EOC + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_ClearFlag_EOC(ADC_TypeDef *ADCx) + { + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_EOC); + } + + /** + * @brief Clear flag ADC group regular end of sequence conversions. + * @rmtoll ISR EOSEQ LL_ADC_ClearFlag_EOS + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_ClearFlag_EOS(ADC_TypeDef *ADCx) + { + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_EOS); + } + + /** + * @brief Clear flag ADC group regular overrun. + * @rmtoll ISR OVR LL_ADC_ClearFlag_OVR + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_ClearFlag_OVR(ADC_TypeDef *ADCx) + { + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_OVR); + } + + /** + * @brief Clear flag ADC group regular end of sampling phase. + * @rmtoll ISR EOSMP LL_ADC_ClearFlag_EOSMP + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_ClearFlag_EOSMP(ADC_TypeDef *ADCx) + { + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_EOSMP); + } + + /** + * @brief Clear flag ADC analog watchdog 1. + * @rmtoll ISR AWD LL_ADC_ClearFlag_AWD1 + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_ClearFlag_AWD1(ADC_TypeDef *ADCx) + { + WRITE_REG(ADCx->ISR, LL_ADC_FLAG_AWD1); + } + + /** + * @} + */ + + /** @defgroup ADC_LL_EF_IT_Management ADC IT management + * @{ + */ + + /** + * @brief Enable ADC ready. + * @rmtoll IER ADRDYIE LL_ADC_EnableIT_ADRDY + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_EnableIT_ADRDY(ADC_TypeDef *ADCx) + { + SET_BIT(ADCx->IER, LL_ADC_IT_ADRDY); + } + + /** + * @brief Enable interruption ADC group regular end of unitary conversion. + * @rmtoll IER EOCIE LL_ADC_EnableIT_EOC + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_EnableIT_EOC(ADC_TypeDef *ADCx) + { + SET_BIT(ADCx->IER, LL_ADC_IT_EOC); + } + + /** + * @brief Enable interruption ADC group regular end of sequence conversions. + * @rmtoll IER EOSEQIE LL_ADC_EnableIT_EOS + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_EnableIT_EOS(ADC_TypeDef *ADCx) + { + SET_BIT(ADCx->IER, LL_ADC_IT_EOS); + } + + /** + * @brief Enable ADC group regular interruption overrun. + * @rmtoll IER OVRIE LL_ADC_EnableIT_OVR + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_EnableIT_OVR(ADC_TypeDef *ADCx) + { + SET_BIT(ADCx->IER, LL_ADC_IT_OVR); + } + + /** + * @brief Enable interruption ADC group regular end of sampling. + * @rmtoll IER EOSMPIE LL_ADC_EnableIT_EOSMP + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_EnableIT_EOSMP(ADC_TypeDef *ADCx) + { + SET_BIT(ADCx->IER, LL_ADC_IT_EOSMP); + } + + /** + * @brief Enable interruption ADC analog watchdog 1. + * @rmtoll IER AWDIE LL_ADC_EnableIT_AWD1 + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_EnableIT_AWD1(ADC_TypeDef *ADCx) + { + SET_BIT(ADCx->IER, LL_ADC_IT_AWD1); + } + + /** + * @brief Disable interruption ADC ready. + * @rmtoll IER ADRDYIE LL_ADC_DisableIT_ADRDY + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_DisableIT_ADRDY(ADC_TypeDef *ADCx) + { + CLEAR_BIT(ADCx->IER, LL_ADC_IT_ADRDY); + } + + /** + * @brief Disable interruption ADC group regular end of unitary conversion. + * @rmtoll IER EOCIE LL_ADC_DisableIT_EOC + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_DisableIT_EOC(ADC_TypeDef *ADCx) + { + CLEAR_BIT(ADCx->IER, LL_ADC_IT_EOC); + } + + /** + * @brief Disable interruption ADC group regular end of sequence conversions. + * @rmtoll IER EOSEQIE LL_ADC_DisableIT_EOS + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_DisableIT_EOS(ADC_TypeDef *ADCx) + { + CLEAR_BIT(ADCx->IER, LL_ADC_IT_EOS); + } + + /** + * @brief Disable interruption ADC group regular overrun. + * @rmtoll IER OVRIE LL_ADC_DisableIT_OVR + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_DisableIT_OVR(ADC_TypeDef *ADCx) + { + CLEAR_BIT(ADCx->IER, LL_ADC_IT_OVR); + } + + /** + * @brief Disable interruption ADC group regular end of sampling. + * @rmtoll IER EOSMPIE LL_ADC_DisableIT_EOSMP + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_DisableIT_EOSMP(ADC_TypeDef *ADCx) + { + CLEAR_BIT(ADCx->IER, LL_ADC_IT_EOSMP); + } + + /** + * @brief Disable interruption ADC analog watchdog 1. + * @rmtoll IER AWDIE LL_ADC_DisableIT_AWD1 + * @param ADCx ADC instance + * @retval None + */ + __STATIC_INLINE void LL_ADC_DisableIT_AWD1(ADC_TypeDef *ADCx) + { + CLEAR_BIT(ADCx->IER, LL_ADC_IT_AWD1); + } + + /** + * @brief Get state of interruption ADC ready + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER ADRDYIE LL_ADC_IsEnabledIT_ADRDY + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_ADRDY(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->IER, LL_ADC_IT_ADRDY) == (LL_ADC_IT_ADRDY)); + } + + /** + * @brief Get state of interruption ADC group regular end of unitary conversion + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER EOCIE LL_ADC_IsEnabledIT_EOC + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_EOC(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->IER, LL_ADC_IT_EOC) == (LL_ADC_IT_EOC)); + } + + /** + * @brief Get state of interruption ADC group regular end of sequence conversions + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER EOSEQIE LL_ADC_IsEnabledIT_EOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_EOS(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->IER, LL_ADC_IT_EOS) == (LL_ADC_IT_EOS)); + } + + /** + * @brief Get state of interruption ADC group regular overrun + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER OVRIE LL_ADC_IsEnabledIT_OVR + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_OVR(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->IER, LL_ADC_IT_OVR) == (LL_ADC_IT_OVR)); + } + + /** + * @brief Get state of interruption ADC group regular end of sampling + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER EOSMPIE LL_ADC_IsEnabledIT_EOSMP + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_EOSMP(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->IER, LL_ADC_IT_EOSMP) == (LL_ADC_IT_EOSMP)); + } + + /** + * @brief Get state of interruption ADC analog watchdog 1 + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll IER AWDIE LL_ADC_IsEnabledIT_AWD1 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_AWD1(ADC_TypeDef *ADCx) + { + return (READ_BIT(ADCx->IER, LL_ADC_IT_AWD1) == (LL_ADC_IT_AWD1)); + } + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup ADC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + /* Initialization of some features of ADC common parameters and multimode */ + /* Note: On this STM32 series, there is no ADC common initialization */ + /* function. */ + ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON); + + /* De-initialization of ADC instance */ + ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx); + + /* Initialization of some features of ADC instance */ + ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, LL_ADC_InitTypeDef *ADC_InitStruct); + void LL_ADC_StructInit(LL_ADC_InitTypeDef *ADC_InitStruct); + + /* Initialization of some features of ADC instance and ADC group regular */ + ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, + LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct); + void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* ADC1 */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_ADC_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_bus.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_bus.h new file mode 100644 index 0000000000..c00ed13b2b --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_bus.h @@ -0,0 +1,842 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_bus.h + * @author MCD Application Team + * @brief Header file of BUS LL module. + + @verbatim + ##### RCC Limitations ##### + ============================================================================== + [..] + A delay between an RCC peripheral clock enable and the effective peripheral + enabling should be taken into account in order to manage the peripheral read/write + from/to registers. + (+) This delay depends on the peripheral mapping. + (++) AHB & APB peripherals, 1 dummy read is necessary + + [..] + Workarounds: + (#) For AHB & APB peripherals, a dummy read to the peripheral register has been + inserted in each LL_{BUS}_GRP{x}_EnableClock() function. + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_BUS_H +#define __STM32F0xx_LL_BUS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(RCC) + +/** @defgroup BUS_LL BUS + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup BUS_LL_Exported_Constants BUS Exported Constants + * @{ + */ + +/** @defgroup BUS_LL_EC_AHB1_GRP1_PERIPH AHB1 GRP1 PERIPH + * @{ + */ +#define LL_AHB1_GRP1_PERIPH_ALL (uint32_t)0xFFFFFFFFU +#define LL_AHB1_GRP1_PERIPH_DMA1 RCC_AHBENR_DMA1EN +#if defined(DMA2) +#define LL_AHB1_GRP1_PERIPH_DMA2 RCC_AHBENR_DMA2EN +#endif /*DMA2*/ +#define LL_AHB1_GRP1_PERIPH_SRAM RCC_AHBENR_SRAMEN +#define LL_AHB1_GRP1_PERIPH_FLASH RCC_AHBENR_FLITFEN +#define LL_AHB1_GRP1_PERIPH_CRC RCC_AHBENR_CRCEN +#define LL_AHB1_GRP1_PERIPH_GPIOA RCC_AHBENR_GPIOAEN +#define LL_AHB1_GRP1_PERIPH_GPIOB RCC_AHBENR_GPIOBEN +#define LL_AHB1_GRP1_PERIPH_GPIOC RCC_AHBENR_GPIOCEN +#if defined(GPIOD) +#define LL_AHB1_GRP1_PERIPH_GPIOD RCC_AHBENR_GPIODEN +#endif /*GPIOD*/ +#if defined(GPIOE) +#define LL_AHB1_GRP1_PERIPH_GPIOE RCC_AHBENR_GPIOEEN +#endif /*GPIOE*/ +#define LL_AHB1_GRP1_PERIPH_GPIOF RCC_AHBENR_GPIOFEN +#if defined(TSC) +#define LL_AHB1_GRP1_PERIPH_TSC RCC_AHBENR_TSCEN +#endif /*TSC*/ +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB1_GRP1_PERIPH APB1 GRP1 PERIPH + * @{ + */ +#define LL_APB1_GRP1_PERIPH_ALL (uint32_t)0xFFFFFFFFU +#if defined(TIM2) +#define LL_APB1_GRP1_PERIPH_TIM2 RCC_APB1ENR_TIM2EN +#endif /*TIM2*/ +#define LL_APB1_GRP1_PERIPH_TIM3 RCC_APB1ENR_TIM3EN +#if defined(TIM6) +#define LL_APB1_GRP1_PERIPH_TIM6 RCC_APB1ENR_TIM6EN +#endif /*TIM6*/ +#if defined(TIM7) +#define LL_APB1_GRP1_PERIPH_TIM7 RCC_APB1ENR_TIM7EN +#endif /*TIM7*/ +#define LL_APB1_GRP1_PERIPH_TIM14 RCC_APB1ENR_TIM14EN +#define LL_APB1_GRP1_PERIPH_WWDG RCC_APB1ENR_WWDGEN +#if defined(SPI2) +#define LL_APB1_GRP1_PERIPH_SPI2 RCC_APB1ENR_SPI2EN +#endif /*SPI2*/ +#if defined(USART2) +#define LL_APB1_GRP1_PERIPH_USART2 RCC_APB1ENR_USART2EN +#endif /* USART2 */ +#if defined(USART3) +#define LL_APB1_GRP1_PERIPH_USART3 RCC_APB1ENR_USART3EN +#endif /* USART3 */ +#if defined(USART4) +#define LL_APB1_GRP1_PERIPH_USART4 RCC_APB1ENR_USART4EN +#endif /* USART4 */ +#if defined(USART5) +#define LL_APB1_GRP1_PERIPH_USART5 RCC_APB1ENR_USART5EN +#endif /* USART5 */ +#define LL_APB1_GRP1_PERIPH_I2C1 RCC_APB1ENR_I2C1EN +#if defined(I2C2) +#define LL_APB1_GRP1_PERIPH_I2C2 RCC_APB1ENR_I2C2EN +#endif /*I2C2*/ +#if defined(USB) +#define LL_APB1_GRP1_PERIPH_USB RCC_APB1ENR_USBEN +#endif /* USB */ +#if defined(CAN) +#define LL_APB1_GRP1_PERIPH_CAN RCC_APB1ENR_CANEN +#endif /*CAN*/ +#if defined(CRS) +#define LL_APB1_GRP1_PERIPH_CRS RCC_APB1ENR_CRSEN +#endif /*CRS*/ +#define LL_APB1_GRP1_PERIPH_PWR RCC_APB1ENR_PWREN +#if defined(DAC) +#define LL_APB1_GRP1_PERIPH_DAC1 RCC_APB1ENR_DACEN +#endif /*DAC*/ +#if defined(CEC) +#define LL_APB1_GRP1_PERIPH_CEC RCC_APB1ENR_CECEN +#endif /*CEC*/ +/** + * @} + */ + +/** @defgroup BUS_LL_EC_APB1_GRP2_PERIPH APB1 GRP2 PERIPH + * @{ + */ +#define LL_APB1_GRP2_PERIPH_ALL (uint32_t)0xFFFFFFFFU +#define LL_APB1_GRP2_PERIPH_SYSCFG RCC_APB2ENR_SYSCFGEN +#define LL_APB1_GRP2_PERIPH_ADC1 RCC_APB2ENR_ADC1EN +#if defined(USART8) +#define LL_APB1_GRP2_PERIPH_USART8 RCC_APB2ENR_USART8EN +#endif /*USART8*/ +#if defined(USART7) +#define LL_APB1_GRP2_PERIPH_USART7 RCC_APB2ENR_USART7EN +#endif /*USART7*/ +#if defined(USART6) +#define LL_APB1_GRP2_PERIPH_USART6 RCC_APB2ENR_USART6EN +#endif /*USART6*/ +#define LL_APB1_GRP2_PERIPH_TIM1 RCC_APB2ENR_TIM1EN +#define LL_APB1_GRP2_PERIPH_SPI1 RCC_APB2ENR_SPI1EN +#define LL_APB1_GRP2_PERIPH_USART1 RCC_APB2ENR_USART1EN +#if defined(TIM15) +#define LL_APB1_GRP2_PERIPH_TIM15 RCC_APB2ENR_TIM15EN +#endif /*TIM15*/ +#define LL_APB1_GRP2_PERIPH_TIM16 RCC_APB2ENR_TIM16EN +#define LL_APB1_GRP2_PERIPH_TIM17 RCC_APB2ENR_TIM17EN +#define LL_APB1_GRP2_PERIPH_DBGMCU RCC_APB2ENR_DBGMCUEN + /** + * @} + */ + + /** + * @} + */ + + /* Exported macro ------------------------------------------------------------*/ + /* Exported functions --------------------------------------------------------*/ + /** @defgroup BUS_LL_Exported_Functions BUS Exported Functions + * @{ + */ + + /** @defgroup BUS_LL_EF_AHB1 AHB1 + * @{ + */ + + /** + * @brief Enable AHB1 peripherals clock. + * @rmtoll AHBENR DMA1EN LL_AHB1_GRP1_EnableClock\n + * AHBENR DMA2EN LL_AHB1_GRP1_EnableClock\n + * AHBENR SRAMEN LL_AHB1_GRP1_EnableClock\n + * AHBENR FLITFEN LL_AHB1_GRP1_EnableClock\n + * AHBENR CRCEN LL_AHB1_GRP1_EnableClock\n + * AHBENR GPIOAEN LL_AHB1_GRP1_EnableClock\n + * AHBENR GPIOBEN LL_AHB1_GRP1_EnableClock\n + * AHBENR GPIOCEN LL_AHB1_GRP1_EnableClock\n + * AHBENR GPIODEN LL_AHB1_GRP1_EnableClock\n + * AHBENR GPIOEEN LL_AHB1_GRP1_EnableClock\n + * AHBENR GPIOFEN LL_AHB1_GRP1_EnableClock\n + * AHBENR TSCEN LL_AHB1_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOD (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB1_GRP1_PERIPH_TSC (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_AHB1_GRP1_EnableClock(uint32_t Periphs) + { + __IO uint32_t tmpreg; + SET_BIT(RCC->AHBENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHBENR, Periphs); + (void)tmpreg; + } + + /** + * @brief Check if AHB1 peripheral clock is enabled or not + * @rmtoll AHBENR DMA1EN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR DMA2EN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR SRAMEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR FLITFEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR CRCEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR GPIOAEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR GPIOBEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR GPIOCEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR GPIODEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR GPIOEEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR GPIOFEN LL_AHB1_GRP1_IsEnabledClock\n + * AHBENR TSCEN LL_AHB1_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOD (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB1_GRP1_PERIPH_TSC (*) + * + * (*) value not defined in all devices. + * @retval State of Periphs (1 or 0). + */ + __STATIC_INLINE uint32_t LL_AHB1_GRP1_IsEnabledClock(uint32_t Periphs) + { + return (READ_BIT(RCC->AHBENR, Periphs) == Periphs); + } + + /** + * @brief Disable AHB1 peripherals clock. + * @rmtoll AHBENR DMA1EN LL_AHB1_GRP1_DisableClock\n + * AHBENR DMA2EN LL_AHB1_GRP1_DisableClock\n + * AHBENR SRAMEN LL_AHB1_GRP1_DisableClock\n + * AHBENR FLITFEN LL_AHB1_GRP1_DisableClock\n + * AHBENR CRCEN LL_AHB1_GRP1_DisableClock\n + * AHBENR GPIOAEN LL_AHB1_GRP1_DisableClock\n + * AHBENR GPIOBEN LL_AHB1_GRP1_DisableClock\n + * AHBENR GPIOCEN LL_AHB1_GRP1_DisableClock\n + * AHBENR GPIODEN LL_AHB1_GRP1_DisableClock\n + * AHBENR GPIOEEN LL_AHB1_GRP1_DisableClock\n + * AHBENR GPIOFEN LL_AHB1_GRP1_DisableClock\n + * AHBENR TSCEN LL_AHB1_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_DMA1 + * @arg @ref LL_AHB1_GRP1_PERIPH_DMA2 (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_SRAM + * @arg @ref LL_AHB1_GRP1_PERIPH_FLASH + * @arg @ref LL_AHB1_GRP1_PERIPH_CRC + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOD (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB1_GRP1_PERIPH_TSC (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_AHB1_GRP1_DisableClock(uint32_t Periphs) + { + CLEAR_BIT(RCC->AHBENR, Periphs); + } + + /** + * @brief Force AHB1 peripherals reset. + * @rmtoll AHBRSTR GPIOARST LL_AHB1_GRP1_ForceReset\n + * AHBRSTR GPIOBRST LL_AHB1_GRP1_ForceReset\n + * AHBRSTR GPIOCRST LL_AHB1_GRP1_ForceReset\n + * AHBRSTR GPIODRST LL_AHB1_GRP1_ForceReset\n + * AHBRSTR GPIOERST LL_AHB1_GRP1_ForceReset\n + * AHBRSTR GPIOFRST LL_AHB1_GRP1_ForceReset\n + * AHBRSTR TSCRST LL_AHB1_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOD (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB1_GRP1_PERIPH_TSC (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_AHB1_GRP1_ForceReset(uint32_t Periphs) + { + SET_BIT(RCC->AHBRSTR, Periphs); + } + + /** + * @brief Release AHB1 peripherals reset. + * @rmtoll AHBRSTR GPIOARST LL_AHB1_GRP1_ReleaseReset\n + * AHBRSTR GPIOBRST LL_AHB1_GRP1_ReleaseReset\n + * AHBRSTR GPIOCRST LL_AHB1_GRP1_ReleaseReset\n + * AHBRSTR GPIODRST LL_AHB1_GRP1_ReleaseReset\n + * AHBRSTR GPIOERST LL_AHB1_GRP1_ReleaseReset\n + * AHBRSTR GPIOFRST LL_AHB1_GRP1_ReleaseReset\n + * AHBRSTR TSCRST LL_AHB1_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_AHB1_GRP1_PERIPH_ALL + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOA + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOB + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOC + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOD (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOE (*) + * @arg @ref LL_AHB1_GRP1_PERIPH_GPIOF + * @arg @ref LL_AHB1_GRP1_PERIPH_TSC (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_AHB1_GRP1_ReleaseReset(uint32_t Periphs) + { + CLEAR_BIT(RCC->AHBRSTR, Periphs); + } + + /** + * @} + */ + + /** @defgroup BUS_LL_EF_APB1_GRP1 APB1 GRP1 + * @{ + */ + + /** + * @brief Enable APB1 peripherals clock (available in register 1). + * @rmtoll APB1ENR TIM2EN LL_APB1_GRP1_EnableClock\n + * APB1ENR TIM3EN LL_APB1_GRP1_EnableClock\n + * APB1ENR TIM6EN LL_APB1_GRP1_EnableClock\n + * APB1ENR TIM7EN LL_APB1_GRP1_EnableClock\n + * APB1ENR TIM14EN LL_APB1_GRP1_EnableClock\n + * APB1ENR WWDGEN LL_APB1_GRP1_EnableClock\n + * APB1ENR SPI2EN LL_APB1_GRP1_EnableClock\n + * APB1ENR USART2EN LL_APB1_GRP1_EnableClock\n + * APB1ENR USART3EN LL_APB1_GRP1_EnableClock\n + * APB1ENR USART4EN LL_APB1_GRP1_EnableClock\n + * APB1ENR USART5EN LL_APB1_GRP1_EnableClock\n + * APB1ENR I2C1EN LL_APB1_GRP1_EnableClock\n + * APB1ENR I2C2EN LL_APB1_GRP1_EnableClock\n + * APB1ENR USBEN LL_APB1_GRP1_EnableClock\n + * APB1ENR CANEN LL_APB1_GRP1_EnableClock\n + * APB1ENR CRSEN LL_APB1_GRP1_EnableClock\n + * APB1ENR PWREN LL_APB1_GRP1_EnableClock\n + * APB1ENR DACEN LL_APB1_GRP1_EnableClock\n + * APB1ENR CECEN LL_APB1_GRP1_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USB (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CAN (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CRS (*) + * @arg @ref LL_APB1_GRP1_PERIPH_PWR + * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_APB1_GRP1_EnableClock(uint32_t Periphs) + { + __IO uint32_t tmpreg; + SET_BIT(RCC->APB1ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB1ENR, Periphs); + (void)tmpreg; + } + + /** + * @brief Check if APB1 peripheral clock is enabled or not (available in register 1). + * @rmtoll APB1ENR TIM2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR TIM3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR TIM6EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR TIM7EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR TIM14EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR WWDGEN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR SPI2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR USART2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR USART3EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR USART4EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR USART5EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR I2C1EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR I2C2EN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR USBEN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR CANEN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR CRSEN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR PWREN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR DACEN LL_APB1_GRP1_IsEnabledClock\n + * APB1ENR CECEN LL_APB1_GRP1_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USB (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CAN (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CRS (*) + * @arg @ref LL_APB1_GRP1_PERIPH_PWR + * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * + * (*) value not defined in all devices. + * @retval State of Periphs (1 or 0). + */ + __STATIC_INLINE uint32_t LL_APB1_GRP1_IsEnabledClock(uint32_t Periphs) + { + return (READ_BIT(RCC->APB1ENR, Periphs) == Periphs); + } + + /** + * @brief Disable APB1 peripherals clock (available in register 1). + * @rmtoll APB1ENR TIM2EN LL_APB1_GRP1_DisableClock\n + * APB1ENR TIM3EN LL_APB1_GRP1_DisableClock\n + * APB1ENR TIM6EN LL_APB1_GRP1_DisableClock\n + * APB1ENR TIM7EN LL_APB1_GRP1_DisableClock\n + * APB1ENR TIM14EN LL_APB1_GRP1_DisableClock\n + * APB1ENR WWDGEN LL_APB1_GRP1_DisableClock\n + * APB1ENR SPI2EN LL_APB1_GRP1_DisableClock\n + * APB1ENR USART2EN LL_APB1_GRP1_DisableClock\n + * APB1ENR USART3EN LL_APB1_GRP1_DisableClock\n + * APB1ENR USART4EN LL_APB1_GRP1_DisableClock\n + * APB1ENR USART5EN LL_APB1_GRP1_DisableClock\n + * APB1ENR I2C1EN LL_APB1_GRP1_DisableClock\n + * APB1ENR I2C2EN LL_APB1_GRP1_DisableClock\n + * APB1ENR USBEN LL_APB1_GRP1_DisableClock\n + * APB1ENR CANEN LL_APB1_GRP1_DisableClock\n + * APB1ENR CRSEN LL_APB1_GRP1_DisableClock\n + * APB1ENR PWREN LL_APB1_GRP1_DisableClock\n + * APB1ENR DACEN LL_APB1_GRP1_DisableClock\n + * APB1ENR CECEN LL_APB1_GRP1_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USB (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CAN (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CRS (*) + * @arg @ref LL_APB1_GRP1_PERIPH_PWR + * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_APB1_GRP1_DisableClock(uint32_t Periphs) + { + CLEAR_BIT(RCC->APB1ENR, Periphs); + } + + /** + * @brief Force APB1 peripherals reset (available in register 1). + * @rmtoll APB1RSTR TIM2RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR TIM3RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR TIM6RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR TIM7RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR TIM14RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR WWDGRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR SPI2RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR USART2RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR USART3RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR USART4RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR USART5RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR I2C1RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR I2C2RST LL_APB1_GRP1_ForceReset\n + * APB1RSTR USBRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR CANRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR CRSRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR PWRRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR DACRST LL_APB1_GRP1_ForceReset\n + * APB1RSTR CECRST LL_APB1_GRP1_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USB (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CAN (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CRS (*) + * @arg @ref LL_APB1_GRP1_PERIPH_PWR + * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_APB1_GRP1_ForceReset(uint32_t Periphs) + { + SET_BIT(RCC->APB1RSTR, Periphs); + } + + /** + * @brief Release APB1 peripherals reset (available in register 1). + * @rmtoll APB1RSTR TIM2RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR TIM3RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR TIM6RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR TIM7RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR TIM14RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR WWDGRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR SPI2RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR USART2RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR USART3RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR USART4RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR USART5RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR I2C1RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR I2C2RST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR USBRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR CANRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR CRSRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR PWRRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR DACRST LL_APB1_GRP1_ReleaseReset\n + * APB1RSTR CECRST LL_APB1_GRP1_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP1_PERIPH_ALL + * @arg @ref LL_APB1_GRP1_PERIPH_TIM2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM3 + * @arg @ref LL_APB1_GRP1_PERIPH_TIM6 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM7 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_TIM14 + * @arg @ref LL_APB1_GRP1_PERIPH_WWDG + * @arg @ref LL_APB1_GRP1_PERIPH_SPI2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART3 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART4 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USART5 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_I2C1 + * @arg @ref LL_APB1_GRP1_PERIPH_I2C2 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_USB (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CAN (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CRS (*) + * @arg @ref LL_APB1_GRP1_PERIPH_PWR + * @arg @ref LL_APB1_GRP1_PERIPH_DAC1 (*) + * @arg @ref LL_APB1_GRP1_PERIPH_CEC (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_APB1_GRP1_ReleaseReset(uint32_t Periphs) + { + CLEAR_BIT(RCC->APB1RSTR, Periphs); + } + + /** + * @} + */ + + /** @defgroup BUS_LL_EF_APB1_GRP2 APB1 GRP2 + * @{ + */ + + /** + * @brief Enable APB1 peripherals clock (available in register 2). + * @rmtoll APB2ENR SYSCFGEN LL_APB1_GRP2_EnableClock\n + * APB2ENR ADC1EN LL_APB1_GRP2_EnableClock\n + * APB2ENR USART8EN LL_APB1_GRP2_EnableClock\n + * APB2ENR USART7EN LL_APB1_GRP2_EnableClock\n + * APB2ENR USART6EN LL_APB1_GRP2_EnableClock\n + * APB2ENR TIM1EN LL_APB1_GRP2_EnableClock\n + * APB2ENR SPI1EN LL_APB1_GRP2_EnableClock\n + * APB2ENR USART1EN LL_APB1_GRP2_EnableClock\n + * APB2ENR TIM15EN LL_APB1_GRP2_EnableClock\n + * APB2ENR TIM16EN LL_APB1_GRP2_EnableClock\n + * APB2ENR TIM17EN LL_APB1_GRP2_EnableClock\n + * APB2ENR DBGMCUEN LL_APB1_GRP2_EnableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_SYSCFG + * @arg @ref LL_APB1_GRP2_PERIPH_ADC1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART8 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART7 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM1 + * @arg @ref LL_APB1_GRP2_PERIPH_SPI1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART1 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM15 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM16 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM17 + * @arg @ref LL_APB1_GRP2_PERIPH_DBGMCU + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_APB1_GRP2_EnableClock(uint32_t Periphs) + { + __IO uint32_t tmpreg; + SET_BIT(RCC->APB2ENR, Periphs); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB2ENR, Periphs); + (void)tmpreg; + } + + /** + * @brief Check if APB1 peripheral clock is enabled or not (available in register 2). + * @rmtoll APB2ENR SYSCFGEN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR ADC1EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR USART8EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR USART7EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR USART6EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR TIM1EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR SPI1EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR USART1EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR TIM15EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR TIM16EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR TIM17EN LL_APB1_GRP2_IsEnabledClock\n + * APB2ENR DBGMCUEN LL_APB1_GRP2_IsEnabledClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_SYSCFG + * @arg @ref LL_APB1_GRP2_PERIPH_ADC1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART8 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART7 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM1 + * @arg @ref LL_APB1_GRP2_PERIPH_SPI1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART1 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM15 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM16 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM17 + * @arg @ref LL_APB1_GRP2_PERIPH_DBGMCU + * + * (*) value not defined in all devices. + * @retval State of Periphs (1 or 0). + */ + __STATIC_INLINE uint32_t LL_APB1_GRP2_IsEnabledClock(uint32_t Periphs) + { + return (READ_BIT(RCC->APB2ENR, Periphs) == Periphs); + } + + /** + * @brief Disable APB1 peripherals clock (available in register 2). + * @rmtoll APB2ENR SYSCFGEN LL_APB1_GRP2_DisableClock\n + * APB2ENR ADC1EN LL_APB1_GRP2_DisableClock\n + * APB2ENR USART8EN LL_APB1_GRP2_DisableClock\n + * APB2ENR USART7EN LL_APB1_GRP2_DisableClock\n + * APB2ENR USART6EN LL_APB1_GRP2_DisableClock\n + * APB2ENR TIM1EN LL_APB1_GRP2_DisableClock\n + * APB2ENR SPI1EN LL_APB1_GRP2_DisableClock\n + * APB2ENR USART1EN LL_APB1_GRP2_DisableClock\n + * APB2ENR TIM15EN LL_APB1_GRP2_DisableClock\n + * APB2ENR TIM16EN LL_APB1_GRP2_DisableClock\n + * APB2ENR TIM17EN LL_APB1_GRP2_DisableClock\n + * APB2ENR DBGMCUEN LL_APB1_GRP2_DisableClock + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_SYSCFG + * @arg @ref LL_APB1_GRP2_PERIPH_ADC1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART8 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART7 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM1 + * @arg @ref LL_APB1_GRP2_PERIPH_SPI1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART1 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM15 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM16 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM17 + * @arg @ref LL_APB1_GRP2_PERIPH_DBGMCU + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_APB1_GRP2_DisableClock(uint32_t Periphs) + { + CLEAR_BIT(RCC->APB2ENR, Periphs); + } + + /** + * @brief Force APB1 peripherals reset (available in register 2). + * @rmtoll APB2RSTR SYSCFGRST LL_APB1_GRP2_ForceReset\n + * APB2RSTR ADC1RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR USART8RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR USART7RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR USART6RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR TIM1RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR SPI1RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR USART1RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR TIM15RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR TIM16RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR TIM17RST LL_APB1_GRP2_ForceReset\n + * APB2RSTR DBGMCURST LL_APB1_GRP2_ForceReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_SYSCFG + * @arg @ref LL_APB1_GRP2_PERIPH_ADC1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART8 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART7 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM1 + * @arg @ref LL_APB1_GRP2_PERIPH_SPI1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART1 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM15 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM16 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM17 + * @arg @ref LL_APB1_GRP2_PERIPH_DBGMCU + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_APB1_GRP2_ForceReset(uint32_t Periphs) + { + SET_BIT(RCC->APB2RSTR, Periphs); + } + + /** + * @brief Release APB1 peripherals reset (available in register 2). + * @rmtoll APB2RSTR SYSCFGRST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR ADC1RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR USART8RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR USART7RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR USART6RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR TIM1RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR SPI1RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR USART1RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR TIM15RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR TIM16RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR TIM17RST LL_APB1_GRP2_ReleaseReset\n + * APB2RSTR DBGMCURST LL_APB1_GRP2_ReleaseReset + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_APB1_GRP2_PERIPH_ALL + * @arg @ref LL_APB1_GRP2_PERIPH_SYSCFG + * @arg @ref LL_APB1_GRP2_PERIPH_ADC1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART8 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART7 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_USART6 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM1 + * @arg @ref LL_APB1_GRP2_PERIPH_SPI1 + * @arg @ref LL_APB1_GRP2_PERIPH_USART1 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM15 (*) + * @arg @ref LL_APB1_GRP2_PERIPH_TIM16 + * @arg @ref LL_APB1_GRP2_PERIPH_TIM17 + * @arg @ref LL_APB1_GRP2_PERIPH_DBGMCU + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_APB1_GRP2_ReleaseReset(uint32_t Periphs) + { + CLEAR_BIT(RCC->APB2RSTR, Periphs); + } + + /** + * @} + */ + + + /** + * @} + */ + + /** + * @} + */ + +#endif /* defined(RCC) */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_BUS_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_comp.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_comp.h new file mode 100644 index 0000000000..5a2a9f4b88 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_comp.h @@ -0,0 +1,911 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_comp.h + * @author MCD Application Team + * @brief Header file of COMP LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_COMP_H +#define __STM32F0xx_LL_COMP_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(COMP1) || defined(COMP2) + +/** @defgroup COMP_LL COMP + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup COMP_LL_Private_Constants COMP Private Constants + * @{ + */ + +/* Differentiation between COMP instances */ +/* Note: Value not corresponding to a register offset since both */ +/* COMP instances are sharing the same register) . */ +#define COMPX_BASE COMP_BASE +#define COMPX (COMP1 - COMP2) + +/* COMP registers bits positions */ +#define LL_COMP_OUTPUT_LEVEL_BITOFFSET_POS \ + ((uint32_t)14U) /* Value equivalent to POSITION_VAL(COMP_CSR_COMP1OUT) */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup COMP_LL_Private_Macros COMP Private Macros + * @{ + */ + +/** + * @brief Driver macro reserved for internal use: if COMP instance selected + * is odd (COMP1, COMP3, ...), return value '1', else return '0'. + * @param __COMP_INSTANCE__ COMP instance + * @retval If COMP instance is odd, value '1'. Else, value '0'. + */ +#define __COMP_IS_INSTANCE_ODD(__COMP_INSTANCE__) \ + ((~(((uint32_t)(__COMP_INSTANCE__)-COMP_BASE) >> 1U)) & 0x00000001) + +/** + * @brief Driver macro reserved for internal use: if COMP instance selected + * is even (COMP2, COMP4, ...), return value '1', else return '0'. + * @param __COMP_INSTANCE__ COMP instance + * @retval If COMP instance is even, value '1'. Else, value '0'. + */ +#define __COMP_IS_INSTANCE_EVEN(__COMP_INSTANCE__) \ + (((uint32_t)(__COMP_INSTANCE__)-COMP_BASE) >> 1U) + +/** + * @brief Driver macro reserved for internal use: from COMP instance + * selected, set offset of bits into COMP register. + * @note Since both COMP instances are sharing the same register + * with 2 area of bits with an offset of 16 bits, this function + * returns value "0" if COMP1 is selected and "16" if COMP2 is + * selected. + * @param __COMP_INSTANCE__ COMP instance + * @retval Bits offset in register 32 bits + */ +#define __COMP_BITOFFSET_INSTANCE(__COMP_INSTANCE__) \ + (((uint32_t)(__COMP_INSTANCE__)-COMP_BASE) << 3U) + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup COMP_LL_ES_INIT COMP Exported Init structure + * @{ + */ + + /** + * @brief Structure definition of some features of COMP instance. + */ + typedef struct + { + uint32_t + PowerMode; /*!< Set comparator operating mode to adjust power and speed. + This parameter can be a value of @ref COMP_LL_EC_POWERMODE + + This feature can be modified afterwards using unitary function + @ref LL_COMP_SetPowerMode(). */ + + uint32_t + InputPlus; /*!< Set comparator input plus (non-inverting input). + This parameter can be a value of @ref COMP_LL_EC_INPUT_PLUS + + This feature can be modified afterwards using unitary function + @ref LL_COMP_SetInputPlus(). */ + + uint32_t + InputMinus; /*!< Set comparator input minus (inverting input). + This parameter can be a value of @ref COMP_LL_EC_INPUT_MINUS + + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetInputMinus(). */ + + uint32_t + InputHysteresis; /*!< Set comparator hysteresis mode of the input minus. + This parameter can be a value of @ref + COMP_LL_EC_INPUT_HYSTERESIS + + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetInputHysteresis(). */ + + uint32_t + OutputSelection; /*!< Set comparator output selection. + This parameter can be a value of @ref + COMP_LL_EC_OUTPUT_SELECTION + + This feature can be modified afterwards using unitary + function @ref LL_COMP_SetOutputSelection(). */ + + uint32_t OutputPolarity; /*!< Set comparator output polarity. + This parameter can be a value of @ref + COMP_LL_EC_OUTPUT_POLARITY + + This feature can be modified afterwards using + unitary function @ref LL_COMP_SetOutputPolarity(). */ + + } LL_COMP_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup COMP_LL_Exported_Constants COMP Exported Constants + * @{ + */ + +/** @defgroup COMP_LL_EC_COMMON_WINDOWMODE Comparator common modes - Window mode + * @{ + */ +#define LL_COMP_WINDOWMODE_DISABLE \ + ((uint32_t)0x00000000U) /*!< Window mode disable: Comparators 1 and 2 are \ + independent */ +#define LL_COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON \ + (COMP_CSR_WNDWEN) /*!< Window mode enable: Comparators instances pair COMP1 and \ + COMP2 have their input plus connected together. The common \ + input is COMP1 input plus (COMP2 input plus is no more \ + accessible). */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_POWERMODE Comparator modes - Power mode + * @{ + */ +#define LL_COMP_POWERMODE_HIGHSPEED \ + ((uint32_t)0x00000000U) /*!< COMP power mode to high speed */ +#define LL_COMP_POWERMODE_MEDIUMSPEED \ + (COMP_CSR_COMP1MODE_0) /*!< COMP power mode to medium speed */ +#define LL_COMP_POWERMODE_LOWPOWER \ + (COMP_CSR_COMP1MODE_1) /*!< COMP power mode to low power */ +#define LL_COMP_POWERMODE_ULTRALOWPOWER \ + (COMP_CSR_COMP1MODE_1 | \ + COMP_CSR_COMP1MODE_0) /*!< COMP power mode to ultra-low power */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_INPUT_PLUS Comparator inputs - Input plus (input non-inverting) + * selection + * @{ + */ +#define LL_COMP_INPUT_PLUS_IO1 \ + ((uint32_t)0x00000000U) /*!< Comparator input plus connected to IO1 (pin PA1 for \ + COMP1, pin PA3 for COMP2) */ +#define LL_COMP_INPUT_PLUS_DAC1_CH1 \ + (COMP_CSR_COMP1SW1) /*!< Comparator input plus connected to DAC1 channel 1 \ + (DAC_OUT1), through dedicated switch (Note: this switch is \ + solely intended to redirect signals onto high impedance \ + input, such as COMP1 input plus (highly resistive switch)) \ + (specific to COMP instance: COMP1) */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_INPUT_MINUS Comparator inputs - Input minus (input inverting) + * selection + * @{ + */ +#define LL_COMP_INPUT_MINUS_1_4VREFINT \ + ((uint32_t)0x00000000U) /*!< Comparator input minus connected to 1/4 VrefInt */ +#define LL_COMP_INPUT_MINUS_1_2VREFINT \ + (COMP_CSR_COMP1INSEL_0) /*!< Comparator input minus connected to 1/2 VrefInt */ +#define LL_COMP_INPUT_MINUS_3_4VREFINT \ + (COMP_CSR_COMP1INSEL_1) /*!< Comparator input minus connected to 3/4 VrefInt */ +#define LL_COMP_INPUT_MINUS_VREFINT \ + (COMP_CSR_COMP1INSEL_1 | \ + COMP_CSR_COMP1INSEL_0) /*!< Comparator input minus connected to VrefInt */ +#define LL_COMP_INPUT_MINUS_DAC1_CH1 \ + (COMP_CSR_COMP1INSEL_2) /*!< Comparator input minus connected to DAC1 channel 1 \ + (DAC_OUT1) */ +#define LL_COMP_INPUT_MINUS_DAC1_CH2 \ + (COMP_CSR_COMP1INSEL_2 | \ + COMP_CSR_COMP1INSEL_0) /*!< Comparator input minus connected to DAC1 channel 2 \ + (DAC_OUT2) */ +#define LL_COMP_INPUT_MINUS_IO1 \ + (COMP_CSR_COMP1INSEL_2 | \ + COMP_CSR_COMP1INSEL_1) /*!< Comparator input minus connected to IO1 (pin PA0 for \ + COMP1, pin PA2 for COMP2) */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_INPUT_HYSTERESIS Comparator input - Hysteresis + * @{ + */ +#define LL_COMP_HYSTERESIS_NONE ((uint32_t)0x00000000U) /*!< No hysteresis */ +#define LL_COMP_HYSTERESIS_LOW (COMP_CSR_COMP1HYST_0) /*!< Hysteresis level low */ +#define LL_COMP_HYSTERESIS_MEDIUM (COMP_CSR_COMP1HYST_1) /*!< Hysteresis level medium */ +#define LL_COMP_HYSTERESIS_HIGH \ + (COMP_CSR_COMP1HYST_1 | COMP_CSR_COMP1HYST_0) /*!< Hysteresis level high */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_OUTPUT_SELECTION Comparator output - Output selection + * @{ + */ +/* Note: Output redirection is common for COMP1 and COMP2 */ +#define LL_COMP_OUTPUT_NONE \ + ((uint32_t)0x00000000U) /*!< COMP output is not connected to other peripherals \ + (except GPIO and EXTI that are always connected to COMP \ + output) */ +#define LL_COMP_OUTPUT_TIM1_BKIN \ + (COMP_CSR_COMP1OUTSEL_0) /*!< COMP output connected to TIM1 break input (BKIN) */ +#define LL_COMP_OUTPUT_TIM1_IC1 \ + (COMP_CSR_COMP1OUTSEL_1) /*!< COMP output connected to TIM1 input capture 1 */ +#define LL_COMP_OUTPUT_TIM1_OCCLR \ + (COMP_CSR_COMP1OUTSEL_1 | \ + COMP_CSR_COMP1OUTSEL_0) /*!< COMP output connected to TIM1 OCREF clear */ +#define LL_COMP_OUTPUT_TIM2_IC4 \ + (COMP_CSR_COMP1OUTSEL_2) /*!< COMP output connected to TIM2 input capture 4 */ +#define LL_COMP_OUTPUT_TIM2_OCCLR \ + (COMP_CSR_COMP1OUTSEL_2 | \ + COMP_CSR_COMP1OUTSEL_0) /*!< COMP output connected to TIM2 OCREF clear */ +#define LL_COMP_OUTPUT_TIM3_IC1 \ + (COMP_CSR_COMP1OUTSEL_2 | \ + COMP_CSR_COMP1OUTSEL_1) /*!< COMP output connected to TIM3 input capture 1 */ +#define LL_COMP_OUTPUT_TIM3_OCCLR \ + (COMP_CSR_COMP1OUTSEL_2 | COMP_CSR_COMP1OUTSEL_1 | \ + COMP_CSR_COMP1OUTSEL_0) /*!< COMP output connected to TIM3 OCREF clear */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_OUTPUT_POLARITY Comparator output - Output polarity + * @{ + */ +#define LL_COMP_OUTPUTPOL_NONINVERTED \ + ((uint32_t)0x00000000U) /*!< COMP output polarity is not inverted: comparator output \ + is high when the plus (non-inverting) input is at a \ + higher voltage than the minus (inverting) input */ +#define LL_COMP_OUTPUTPOL_INVERTED \ + (COMP_CSR_COMP1POL) /*!< COMP output polarity is inverted: comparator output is low \ + when the plus (non-inverting) input is at a lower voltage \ + than the minus (inverting) input */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_OUTPUT_LEVEL Comparator output - Output level + * @{ + */ +#define LL_COMP_OUTPUT_LEVEL_LOW \ + ((uint32_t)0x00000000U) /*!< Comparator output level low (if the polarity is not \ + inverted, otherwise to be complemented) */ +#define LL_COMP_OUTPUT_LEVEL_HIGH \ + ((uint32_t)0x00000001U) /*!< Comparator output level high (if the polarity is not \ + inverted, otherwise to be complemented) */ +/** + * @} + */ + +/** @defgroup COMP_LL_EC_HW_DELAYS Definitions of COMP hardware constraints delays + * @note Only COMP IP HW delays are defined in COMP LL driver driver, + * not timeout values. + * For details on delays values, refer to descriptions in source code + * above each literal definition. + * @{ + */ + +/* Delay for comparator startup time. */ +/* Note: Delay required to reach propagation delay specification. */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tSTART"). */ +/* Unit: us */ +#define LL_COMP_DELAY_STARTUP_US ((uint32_t)60U) /*!< Delay for COMP startup time */ + +/* Delay for comparator voltage scaler stabilization time */ +/* (voltage from VrefInt, delay based on VrefInt startup time). */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tS_SC"). */ +/* Unit: us */ +#define LL_COMP_DELAY_VOLTAGE_SCALER_STAB_US \ + ((uint32_t)200U) /*!< Delay for COMP voltage scaler stabilization time */ + + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup COMP_LL_Exported_Macros COMP Exported Macros + * @{ + */ +/** @defgroup COMP_LL_EM_WRITE_READ Common write and read registers macro + * @{ + */ + +/** + * @brief Write a value in COMP register + * @param __INSTANCE__ comparator instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_COMP_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in COMP register + * @param __INSTANCE__ comparator instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_COMP_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup COMP_LL_EM_HELPER_MACRO COMP helper macro + * @{ + */ + +/** + * @brief Helper macro to select the COMP common instance + * to which is belonging the selected COMP instance. + * @note COMP common register instance can be used to + * set parameters common to several COMP instances. + * Refer to functions having argument "COMPxy_COMMON" as parameter. + * @param __COMPx__ COMP instance + * @retval COMP common instance or value "0" if there is no COMP common instance. + */ +#define __LL_COMP_COMMON_INSTANCE(__COMPx__) (COMP12_COMMON) + + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup COMP_LL_Exported_Functions COMP Exported Functions + * @{ + */ + + /** @defgroup COMP_LL_EF_Configuration_comparator_common Configuration of COMP + * hierarchical scope: common to several COMP instances + * @{ + */ + + /** + * @brief Set window mode of a pair of comparators instances + * (2 consecutive COMP instances odd and even COMP and COMP). + * @rmtoll CSR WNDWEN LL_COMP_SetCommonWindowMode + * @param COMPxy_COMMON Comparator common instance + * (can be set directly from CMSIS definition or by using helper macro @ref + * __LL_COMP_COMMON_INSTANCE() ) + * @param WindowMode This parameter can be one of the following values: + * @arg @ref LL_COMP_WINDOWMODE_DISABLE + * @arg @ref LL_COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON + * @retval None + */ + __STATIC_INLINE void LL_COMP_SetCommonWindowMode(COMP_Common_TypeDef *COMPxy_COMMON, + uint32_t WindowMode) + { + MODIFY_REG(COMPxy_COMMON->CSR, COMP_CSR_WNDWEN, WindowMode); + } + + /** + * @brief Get window mode of a pair of comparators instances + * (2 consecutive COMP instances odd and even COMP and COMP). + * @rmtoll CSR WNDWEN LL_COMP_GetCommonWindowMode + * @param COMPxy_COMMON Comparator common instance + * (can be set directly from CMSIS definition or by using helper macro @ref + * __LL_COMP_COMMON_INSTANCE() ) + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_WINDOWMODE_DISABLE + * @arg @ref LL_COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON + */ + __STATIC_INLINE uint32_t + LL_COMP_GetCommonWindowMode(COMP_Common_TypeDef *COMPxy_COMMON) + { + return (uint32_t)(READ_BIT(COMPxy_COMMON->CSR, COMP_CSR_WNDWEN)); + } + + /** + * @} + */ + + /** @defgroup COMP_LL_EF_Configuration_comparator_modes Configuration of comparator + * modes + * @{ + */ + + /** + * @brief Set comparator instance operating mode to adjust power and speed. + * @rmtoll CSR COMP1MODE LL_COMP_SetPowerMode\n + * COMP2MODE LL_COMP_SetPowerMode + * @param COMPx Comparator instance + * @param PowerMode This parameter can be one of the following values: + * @arg @ref LL_COMP_POWERMODE_HIGHSPEED + * @arg @ref LL_COMP_POWERMODE_MEDIUMSPEED + * @arg @ref LL_COMP_POWERMODE_LOWPOWER + * @arg @ref LL_COMP_POWERMODE_ULTRALOWPOWER + * @retval None + */ + __STATIC_INLINE void LL_COMP_SetPowerMode(COMP_TypeDef *COMPx, uint32_t PowerMode) + { + MODIFY_REG(COMP->CSR, COMP_CSR_COMP1MODE << __COMP_BITOFFSET_INSTANCE(COMPx), + PowerMode << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Get comparator instance operating mode to adjust power and speed. + * @rmtoll CSR COMP1MODE LL_COMP_GetPowerMode\n + * COMP2MODE LL_COMP_GetPowerMode + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_POWERMODE_HIGHSPEED + * @arg @ref LL_COMP_POWERMODE_MEDIUMSPEED + * @arg @ref LL_COMP_POWERMODE_LOWPOWER + * @arg @ref LL_COMP_POWERMODE_ULTRALOWPOWER + */ + __STATIC_INLINE uint32_t LL_COMP_GetPowerMode(COMP_TypeDef *COMPx) + { + return (uint32_t)(READ_BIT(COMP->CSR, COMP_CSR_COMP1MODE + << __COMP_BITOFFSET_INSTANCE(COMPx)) >> + __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @} + */ + + /** @defgroup COMP_LL_EF_Configuration_comparator_inputs Configuration of comparator + * inputs + * @{ + */ + + /** + * @brief Set comparator inputs minus (inverting) and plus (non-inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CSR COMP1INSEL LL_COMP_ConfigInputs\n + * CSR COMP2INSEL LL_COMP_ConfigInputs\n + * CSR COMP1SW1 LL_COMP_ConfigInputs + * @param COMPx Comparator instance + * @param InputMinus This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_MINUS_1_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_1_2VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_3_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH1 + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH2 + * @arg @ref LL_COMP_INPUT_MINUS_IO1 + * @param InputPlus This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_PLUS_IO1 + * @arg @ref LL_COMP_INPUT_PLUS_DAC1_CH1 (1) + * + * (1) Parameter available only on COMP instance: COMP1. + * @retval None + */ + __STATIC_INLINE void LL_COMP_ConfigInputs(COMP_TypeDef *COMPx, uint32_t InputMinus, + uint32_t InputPlus) + { + /* Note: Connection switch is applicable only to COMP instance COMP1, */ + /* therefore if COMP2 is selected the equivalent bit is */ + /* kept unmodified. */ + MODIFY_REG( + COMP->CSR, + (COMP_CSR_COMP1INSEL | (COMP_CSR_COMP1SW1 * __COMP_IS_INSTANCE_ODD(COMPx))) + << __COMP_BITOFFSET_INSTANCE(COMPx), + (InputMinus | InputPlus) << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Set comparator input plus (non-inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CSR COMP1INSEL LL_COMP_SetInputPlus\n + * CSR COMP2INSEL LL_COMP_SetInputPlus + * @param COMPx Comparator instance + * @param InputPlus This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_PLUS_IO1 + * @arg @ref LL_COMP_INPUT_PLUS_DAC1_CH1 (1) + * + * (1) Parameter available only on COMP instance: COMP1. + * @retval None + */ + __STATIC_INLINE void LL_COMP_SetInputPlus(COMP_TypeDef *COMPx, uint32_t InputPlus) + { + /* Note: Connection switch is applicable only to COMP instance COMP1, */ + /* therefore if COMP2 is selected the equivalent bit is */ + /* kept unmodified. */ + MODIFY_REG(COMP->CSR, + (COMP_CSR_COMP1SW1 * __COMP_IS_INSTANCE_ODD(COMPx)) + << __COMP_BITOFFSET_INSTANCE(COMPx), + InputPlus << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Get comparator input plus (non-inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CSR COMP1INSEL LL_COMP_GetInputPlus\n + * CSR COMP2INSEL LL_COMP_GetInputPlus + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_INPUT_PLUS_IO1 + * @arg @ref LL_COMP_INPUT_PLUS_DAC1_CH1 (1) + * + * (1) Parameter available only on COMP instance: COMP1. + */ + __STATIC_INLINE uint32_t LL_COMP_GetInputPlus(COMP_TypeDef *COMPx) + { + /* Note: Connection switch is applicable only to COMP instance COMP1, */ + /* therefore is COMP2 is selected the returned value will be null. */ + return (uint32_t)(READ_BIT(COMP->CSR, COMP_CSR_COMP1SW1 + << __COMP_BITOFFSET_INSTANCE(COMPx)) >> + __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Set comparator input minus (inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CSR COMP1SW1 LL_COMP_SetInputMinus + * @param COMPx Comparator instance + * @param InputMinus This parameter can be one of the following values: + * @arg @ref LL_COMP_INPUT_MINUS_1_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_1_2VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_3_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH1 + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH2 + * @arg @ref LL_COMP_INPUT_MINUS_IO1 + * @retval None + */ + __STATIC_INLINE void LL_COMP_SetInputMinus(COMP_TypeDef *COMPx, uint32_t InputMinus) + { + MODIFY_REG(COMP->CSR, COMP_CSR_COMP1INSEL << __COMP_BITOFFSET_INSTANCE(COMPx), + InputMinus << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Get comparator input minus (inverting). + * @note In case of comparator input selected to be connected to IO: + * GPIO pins are specific to each comparator instance. + * Refer to description of parameters or to reference manual. + * @rmtoll CSR COMP1SW1 LL_COMP_GetInputMinus + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_INPUT_MINUS_1_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_1_2VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_3_4VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_VREFINT + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH1 + * @arg @ref LL_COMP_INPUT_MINUS_DAC1_CH2 + * @arg @ref LL_COMP_INPUT_MINUS_IO1 + */ + __STATIC_INLINE uint32_t LL_COMP_GetInputMinus(COMP_TypeDef *COMPx) + { + return (uint32_t)(READ_BIT(COMP->CSR, COMP_CSR_COMP1INSEL + << __COMP_BITOFFSET_INSTANCE(COMPx)) >> + __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Set comparator instance hysteresis mode of the input minus (inverting + * input). + * @rmtoll CSR COMP1HYST LL_COMP_SetInputHysteresis\n + * COMP2HYST LL_COMP_SetInputHysteresis + * @param COMPx Comparator instance + * @param InputHysteresis This parameter can be one of the following values: + * @arg @ref LL_COMP_HYSTERESIS_NONE + * @arg @ref LL_COMP_HYSTERESIS_LOW + * @arg @ref LL_COMP_HYSTERESIS_MEDIUM + * @arg @ref LL_COMP_HYSTERESIS_HIGH + * @retval None + */ + __STATIC_INLINE void LL_COMP_SetInputHysteresis(COMP_TypeDef *COMPx, + uint32_t InputHysteresis) + { + MODIFY_REG(COMP->CSR, COMP_CSR_COMP1HYST << __COMP_BITOFFSET_INSTANCE(COMPx), + InputHysteresis << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Get comparator instance hysteresis mode of the minus (inverting) input. + * @rmtoll CSR COMP1HYST LL_COMP_GetInputHysteresis\n + * COMP2HYST LL_COMP_GetInputHysteresis + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_HYSTERESIS_NONE + * @arg @ref LL_COMP_HYSTERESIS_LOW + * @arg @ref LL_COMP_HYSTERESIS_MEDIUM + * @arg @ref LL_COMP_HYSTERESIS_HIGH + */ + __STATIC_INLINE uint32_t LL_COMP_GetInputHysteresis(COMP_TypeDef *COMPx) + { + return (uint32_t)(READ_BIT(COMP->CSR, COMP_CSR_COMP1HYST + << __COMP_BITOFFSET_INSTANCE(COMPx)) >> + __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @} + */ + + /** @defgroup COMP_LL_EF_Configuration_comparator_output Configuration of comparator + * output + * @{ + */ + + /** + * @brief Set comparator output selection. + * @note Availability of parameters of output selection to timer + * depends on timers availability on the selected device. + * @rmtoll CSR COMP1OUTSEL LL_COMP_SetOutputSelection\n + * COMP2OUTSEL LL_COMP_SetOutputSelection + * @param COMPx Comparator instance + * @param OutputSelection This parameter can be one of the following values: + * @arg @ref LL_COMP_OUTPUT_NONE + * @arg @ref LL_COMP_OUTPUT_TIM1_BKIN (1) + * @arg @ref LL_COMP_OUTPUT_TIM1_IC1 (1) + * @arg @ref LL_COMP_OUTPUT_TIM1_OCCLR (1) + * @arg @ref LL_COMP_OUTPUT_TIM2_IC4 (1) + * @arg @ref LL_COMP_OUTPUT_TIM2_OCCLR (1) + * @arg @ref LL_COMP_OUTPUT_TIM3_IC1 (1) + * @arg @ref LL_COMP_OUTPUT_TIM3_OCCLR (1) + * + * (1) Parameter availability depending on timer availability + * on the selected device. + * @retval None + */ + __STATIC_INLINE void LL_COMP_SetOutputSelection(COMP_TypeDef *COMPx, + uint32_t OutputSelection) + { + MODIFY_REG(COMP->CSR, COMP_CSR_COMP1OUTSEL << __COMP_BITOFFSET_INSTANCE(COMPx), + OutputSelection << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Get comparator output selection. + * @note Availability of parameters of output selection to timer + * depends on timers availability on the selected device. + * @rmtoll CSR COMP1OUTSEL LL_COMP_GetOutputSelection\n + * COMP2OUTSEL LL_COMP_GetOutputSelection + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_OUTPUT_NONE + * @arg @ref LL_COMP_OUTPUT_TIM1_BKIN (1) + * @arg @ref LL_COMP_OUTPUT_TIM1_IC1 (1) + * @arg @ref LL_COMP_OUTPUT_TIM1_OCCLR (1) + * @arg @ref LL_COMP_OUTPUT_TIM2_IC4 (1) + * @arg @ref LL_COMP_OUTPUT_TIM2_OCCLR (1) + * @arg @ref LL_COMP_OUTPUT_TIM3_IC1 (1) + * @arg @ref LL_COMP_OUTPUT_TIM3_OCCLR (1) + * + * (1) Parameter availability depending on timer availability + * on the selected device. + */ + __STATIC_INLINE uint32_t LL_COMP_GetOutputSelection(COMP_TypeDef *COMPx) + { + return (uint32_t)(READ_BIT(COMP->CSR, COMP_CSR_COMP1OUTSEL + << __COMP_BITOFFSET_INSTANCE(COMPx)) >> + __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Set comparator instance output polarity. + * @rmtoll CSR COMP1POL LL_COMP_SetOutputPolarity\n + * COMP2POL LL_COMP_SetOutputPolarity + * @param COMPx Comparator instance + * @param OutputPolarity This parameter can be one of the following values: + * @arg @ref LL_COMP_OUTPUTPOL_NONINVERTED + * @arg @ref LL_COMP_OUTPUTPOL_INVERTED + * @retval None + */ + __STATIC_INLINE void LL_COMP_SetOutputPolarity(COMP_TypeDef *COMPx, + uint32_t OutputPolarity) + { + MODIFY_REG(COMP->CSR, COMP_CSR_COMP1POL << __COMP_BITOFFSET_INSTANCE(COMPx), + OutputPolarity << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Get comparator instance output polarity. + * @rmtoll CSR COMP1POL LL_COMP_GetOutputPolarity\n + * COMP2POL LL_COMP_GetOutputPolarity + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_OUTPUTPOL_NONINVERTED + * @arg @ref LL_COMP_OUTPUTPOL_INVERTED + */ + __STATIC_INLINE uint32_t LL_COMP_GetOutputPolarity(COMP_TypeDef *COMPx) + { + return (uint32_t)(READ_BIT(COMP->CSR, COMP_CSR_COMP1POL + << __COMP_BITOFFSET_INSTANCE(COMPx)) >> + __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @} + */ + + /** @defgroup COMP_LL_EF_Operation Operation on comparator instance + * @{ + */ + + /** + * @brief Enable comparator instance. + * @note After enable from off state, comparator requires a delay + * to reach reach propagation delay specification. + * Refer to device datasheet, parameter "tSTART". + * @rmtoll CSR COMP1EN LL_COMP_Enable\n + * CSR COMP2EN LL_COMP_Enable + * @param COMPx Comparator instance + * @retval None + */ + __STATIC_INLINE void LL_COMP_Enable(COMP_TypeDef *COMPx) + { + SET_BIT(COMP->CSR, COMP_CSR_COMP1EN << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Disable comparator instance. + * @rmtoll CSR COMP1EN LL_COMP_Disable\n + * CSR COMP2EN LL_COMP_Disable + * @param COMPx Comparator instance + * @retval None + */ + __STATIC_INLINE void LL_COMP_Disable(COMP_TypeDef *COMPx) + { + CLEAR_BIT(COMP->CSR, COMP_CSR_COMP1EN << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Get comparator enable state + * (0: COMP is disabled, 1: COMP is enabled) + * @rmtoll CSR COMP1EN LL_COMP_IsEnabled\n + * CSR COMP2EN LL_COMP_IsEnabled + * @param COMPx Comparator instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_COMP_IsEnabled(COMP_TypeDef *COMPx) + { + return ( + READ_BIT(COMP->CSR, COMP_CSR_COMP1EN << __COMP_BITOFFSET_INSTANCE(COMPx)) == + COMP_CSR_COMP1EN << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Lock comparator instance. + * @note Once locked, comparator configuration can be accessed in read-only. + * @note The only way to unlock the comparator is a device hardware reset. + * @rmtoll CSR COMP1LOCK LL_COMP_Lock\n + * CSR COMP2LOCK LL_COMP_Lock + * @param COMPx Comparator instance + * @retval None + */ + __STATIC_INLINE void LL_COMP_Lock(COMP_TypeDef *COMPx) + { + SET_BIT(COMP->CSR, COMP_CSR_COMP1LOCK << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Get comparator lock state + * (0: COMP is unlocked, 1: COMP is locked). + * @note Once locked, comparator configuration can be accessed in read-only. + * @note The only way to unlock the comparator is a device hardware reset. + * @rmtoll CSR COMP1LOCK LL_COMP_IsLocked\n + * CSR COMP2LOCK LL_COMP_IsLocked + * @param COMPx Comparator instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_COMP_IsLocked(COMP_TypeDef *COMPx) + { + return ( + READ_BIT(COMP->CSR, COMP_CSR_COMP1LOCK << __COMP_BITOFFSET_INSTANCE(COMPx)) == + COMP_CSR_COMP1LOCK << __COMP_BITOFFSET_INSTANCE(COMPx)); + } + + /** + * @brief Read comparator instance output level. + * @note The comparator output level depends on the selected polarity + * (Refer to function @ref LL_COMP_SetOutputPolarity()). + * If the comparator polarity is not inverted: + * - Comparator output is low when the input plus + * is at a lower voltage than the input minus + * - Comparator output is high when the input plus + * is at a higher voltage than the input minus + * If the comparator polarity is inverted: + * - Comparator output is high when the input plus + * is at a lower voltage than the input minus + * - Comparator output is low when the input plus + * is at a higher voltage than the input minus + * @rmtoll CSR COMP1OUT LL_COMP_ReadOutputLevel\n + * CSR COMP2OUT LL_COMP_ReadOutputLevel + * @param COMPx Comparator instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_COMP_OUTPUT_LEVEL_LOW + * @arg @ref LL_COMP_OUTPUT_LEVEL_HIGH + */ + __STATIC_INLINE uint32_t LL_COMP_ReadOutputLevel(COMP_TypeDef *COMPx) + { + return (uint32_t)(READ_BIT(COMP->CSR, COMP_CSR_COMP1OUT + << __COMP_BITOFFSET_INSTANCE(COMPx)) >> + (__COMP_BITOFFSET_INSTANCE(COMPx) + + LL_COMP_OUTPUT_LEVEL_BITOFFSET_POS)); + } + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup COMP_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + ErrorStatus LL_COMP_DeInit(COMP_TypeDef *COMPx); + ErrorStatus LL_COMP_Init(COMP_TypeDef *COMPx, LL_COMP_InitTypeDef *COMP_InitStruct); + void LL_COMP_StructInit(LL_COMP_InitTypeDef *COMP_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* COMP1 || COMP2 */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_COMP_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_cortex.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_cortex.h new file mode 100644 index 0000000000..0d67ef89d6 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_cortex.h @@ -0,0 +1,328 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_cortex.h + * @author MCD Application Team + * @brief Header file of CORTEX LL module. + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The LL CORTEX driver contains a set of generic APIs that can be + used by user: + (+) SYSTICK configuration used by LL_mDelay and LL_Init1msTick + functions + (+) Low power mode configuration (SCB register of Cortex-MCU) + (+) API to access to MCU info (CPUID register) + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_CORTEX_H +#define __STM32F0xx_LL_CORTEX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + +/** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +/** @defgroup CORTEX_LL CORTEX + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CORTEX_LL_Exported_Constants CORTEX Exported Constants + * @{ + */ + +/** @defgroup CORTEX_LL_EC_CLKSOURCE_HCLK SYSTICK Clock Source + * @{ + */ +#define LL_SYSTICK_CLKSOURCE_HCLK_DIV8 \ + 0x00000000U /*!< AHB clock divided by 8 selected as SysTick clock source.*/ +#define LL_SYSTICK_CLKSOURCE_HCLK \ + SysTick_CTRL_CLKSOURCE_Msk /*!< AHB clock selected as SysTick clock source. */ + /** + * @} + */ + + /** + * @} + */ + + /* Exported macro ------------------------------------------------------------*/ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup CORTEX_LL_Exported_Functions CORTEX Exported Functions + * @{ + */ + + /** @defgroup CORTEX_LL_EF_SYSTICK SYSTICK + * @{ + */ + + /** + * @brief This function checks if the Systick counter flag is active or not. + * @note It can be used in timeout function on application side. + * @rmtoll STK_CTRL COUNTFLAG LL_SYSTICK_IsActiveCounterFlag + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSTICK_IsActiveCounterFlag(void) + { + return ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == + (SysTick_CTRL_COUNTFLAG_Msk)); + } + + /** + * @brief Configures the SysTick clock source + * @rmtoll STK_CTRL CLKSOURCE LL_SYSTICK_SetClkSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK_DIV8 + * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK + * @retval None + */ + __STATIC_INLINE void LL_SYSTICK_SetClkSource(uint32_t Source) + { + if (Source == LL_SYSTICK_CLKSOURCE_HCLK) + { + SET_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK); + } + else + { + CLEAR_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK); + } + } + + /** + * @brief Get the SysTick clock source + * @rmtoll STK_CTRL CLKSOURCE LL_SYSTICK_GetClkSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK_DIV8 + * @arg @ref LL_SYSTICK_CLKSOURCE_HCLK + */ + __STATIC_INLINE uint32_t LL_SYSTICK_GetClkSource(void) + { + return READ_BIT(SysTick->CTRL, LL_SYSTICK_CLKSOURCE_HCLK); + } + + /** + * @brief Enable SysTick exception request + * @rmtoll STK_CTRL TICKINT LL_SYSTICK_EnableIT + * @retval None + */ + __STATIC_INLINE void LL_SYSTICK_EnableIT(void) + { + SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); + } + + /** + * @brief Disable SysTick exception request + * @rmtoll STK_CTRL TICKINT LL_SYSTICK_DisableIT + * @retval None + */ + __STATIC_INLINE void LL_SYSTICK_DisableIT(void) + { + CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk); + } + + /** + * @brief Checks if the SYSTICK interrupt is enabled or disabled. + * @rmtoll STK_CTRL TICKINT LL_SYSTICK_IsEnabledIT + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSTICK_IsEnabledIT(void) + { + return (READ_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk) == + (SysTick_CTRL_TICKINT_Msk)); + } + + /** + * @} + */ + + /** @defgroup CORTEX_LL_EF_LOW_POWER_MODE LOW POWER MODE + * @{ + */ + + /** + * @brief Processor uses sleep as its low power mode + * @rmtoll SCB_SCR SLEEPDEEP LL_LPM_EnableSleep + * @retval None + */ + __STATIC_INLINE void LL_LPM_EnableSleep(void) + { + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + } + + /** + * @brief Processor uses deep sleep as its low power mode + * @rmtoll SCB_SCR SLEEPDEEP LL_LPM_EnableDeepSleep + * @retval None + */ + __STATIC_INLINE void LL_LPM_EnableDeepSleep(void) + { + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + } + + /** + * @brief Configures sleep-on-exit when returning from Handler mode to Thread mode. + * @note Setting this bit to 1 enables an interrupt-driven application to avoid + * returning to an empty main application. + * @rmtoll SCB_SCR SLEEPONEXIT LL_LPM_EnableSleepOnExit + * @retval None + */ + __STATIC_INLINE void LL_LPM_EnableSleepOnExit(void) + { + /* Set SLEEPONEXIT bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk)); + } + + /** + * @brief Do not sleep when returning to Thread mode. + * @rmtoll SCB_SCR SLEEPONEXIT LL_LPM_DisableSleepOnExit + * @retval None + */ + __STATIC_INLINE void LL_LPM_DisableSleepOnExit(void) + { + /* Clear SLEEPONEXIT bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk)); + } + + /** + * @brief Enabled events and all interrupts, including disabled interrupts, can + * wakeup the processor. + * @rmtoll SCB_SCR SEVEONPEND LL_LPM_EnableEventOnPend + * @retval None + */ + __STATIC_INLINE void LL_LPM_EnableEventOnPend(void) + { + /* Set SEVEONPEND bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk)); + } + + /** + * @brief Only enabled interrupts or events can wakeup the processor, disabled + * interrupts are excluded + * @rmtoll SCB_SCR SEVEONPEND LL_LPM_DisableEventOnPend + * @retval None + */ + __STATIC_INLINE void LL_LPM_DisableEventOnPend(void) + { + /* Clear SEVEONPEND bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk)); + } + + /** + * @} + */ + + /** @defgroup CORTEX_LL_EF_MCU_INFO MCU INFO + * @{ + */ + + /** + * @brief Get Implementer code + * @rmtoll SCB_CPUID IMPLEMENTER LL_CPUID_GetImplementer + * @retval Value should be equal to 0x41 for ARM + */ + __STATIC_INLINE uint32_t LL_CPUID_GetImplementer(void) + { + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_IMPLEMENTER_Msk) >> + SCB_CPUID_IMPLEMENTER_Pos); + } + + /** + * @brief Get Variant number (The r value in the rnpn product revision identifier) + * @rmtoll SCB_CPUID VARIANT LL_CPUID_GetVariant + * @retval Value between 0 and 255 (0x0: revision 0) + */ + __STATIC_INLINE uint32_t LL_CPUID_GetVariant(void) + { + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_VARIANT_Msk) >> + SCB_CPUID_VARIANT_Pos); + } + + /** + * @brief Get Architecture number + * @rmtoll SCB_CPUID ARCHITECTURE LL_CPUID_GetArchitecture + * @retval Value should be equal to 0xC for Cortex-M0 devices + */ + __STATIC_INLINE uint32_t LL_CPUID_GetArchitecture(void) + { + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_ARCHITECTURE_Msk) >> + SCB_CPUID_ARCHITECTURE_Pos); + } + + /** + * @brief Get Part number + * @rmtoll SCB_CPUID PARTNO LL_CPUID_GetParNo + * @retval Value should be equal to 0xC20 for Cortex-M0 + */ + __STATIC_INLINE uint32_t LL_CPUID_GetParNo(void) + { + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_PARTNO_Msk) >> + SCB_CPUID_PARTNO_Pos); + } + + /** + * @brief Get Revision number (The p value in the rnpn product revision identifier, + * indicates patch release) + * @rmtoll SCB_CPUID REVISION LL_CPUID_GetRevision + * @retval Value between 0 and 255 (0x1: patch 1) + */ + __STATIC_INLINE uint32_t LL_CPUID_GetRevision(void) + { + return (uint32_t)(READ_BIT(SCB->CPUID, SCB_CPUID_REVISION_Msk) >> + SCB_CPUID_REVISION_Pos); + } + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_CORTEX_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_crs.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_crs.h new file mode 100644 index 0000000000..451b1055dd --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_crs.h @@ -0,0 +1,805 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_crs.h + * @author MCD Application Team + * @brief Header file of CRS LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_CRS_H +#define __STM32F0xx_LL_CRS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(CRS) + +/** @defgroup CRS_LL CRS + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRS_LL_Exported_Constants CRS Exported Constants + * @{ + */ + +/** @defgroup CRS_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_CRS_ReadReg function + * @{ + */ +#define LL_CRS_ISR_SYNCOKF CRS_ISR_SYNCOKF +#define LL_CRS_ISR_SYNCWARNF CRS_ISR_SYNCWARNF +#define LL_CRS_ISR_ERRF CRS_ISR_ERRF +#define LL_CRS_ISR_ESYNCF CRS_ISR_ESYNCF +#define LL_CRS_ISR_SYNCERR CRS_ISR_SYNCERR +#define LL_CRS_ISR_SYNCMISS CRS_ISR_SYNCMISS +#define LL_CRS_ISR_TRIMOVF CRS_ISR_TRIMOVF +/** + * @} + */ + +/** @defgroup CRS_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_CRS_ReadReg and LL_CRS_WriteReg + * functions + * @{ + */ +#define LL_CRS_CR_SYNCOKIE CRS_CR_SYNCOKIE +#define LL_CRS_CR_SYNCWARNIE CRS_CR_SYNCWARNIE +#define LL_CRS_CR_ERRIE CRS_CR_ERRIE +#define LL_CRS_CR_ESYNCIE CRS_CR_ESYNCIE +/** + * @} + */ + +/** @defgroup CRS_LL_EC_SYNC_DIV Synchronization Signal Divider + * @{ + */ +#define LL_CRS_SYNC_DIV_1 ((uint32_t)0x00U) /*!< Synchro Signal not divided (default) */ +#define LL_CRS_SYNC_DIV_2 CRS_CFGR_SYNCDIV_0 /*!< Synchro Signal divided by 2 */ +#define LL_CRS_SYNC_DIV_4 CRS_CFGR_SYNCDIV_1 /*!< Synchro Signal divided by 4 */ +#define LL_CRS_SYNC_DIV_8 \ + (CRS_CFGR_SYNCDIV_1 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 8 */ +#define LL_CRS_SYNC_DIV_16 CRS_CFGR_SYNCDIV_2 /*!< Synchro Signal divided by 16 */ +#define LL_CRS_SYNC_DIV_32 \ + (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 32 */ +#define LL_CRS_SYNC_DIV_64 \ + (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_1) /*!< Synchro Signal divided by 64 */ +#define LL_CRS_SYNC_DIV_128 CRS_CFGR_SYNCDIV /*!< Synchro Signal divided by 128 */ +/** + * @} + */ + +/** @defgroup CRS_LL_EC_SYNC_SOURCE Synchronization Signal Source + * @{ + */ +#define LL_CRS_SYNC_SOURCE_GPIO ((uint32_t)0x00U) /*!< Synchro Signal source GPIO */ +#define LL_CRS_SYNC_SOURCE_LSE CRS_CFGR_SYNCSRC_0 /*!< Synchro Signal source LSE */ +#define LL_CRS_SYNC_SOURCE_USB \ + CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source USB SOF (default)*/ +/** + * @} + */ + +/** @defgroup CRS_LL_EC_SYNC_POLARITY Synchronization Signal Polarity + * @{ + */ +#define LL_CRS_SYNC_POLARITY_RISING \ + ((uint32_t)0x00U) /*!< Synchro Active on rising edge (default) */ +#define LL_CRS_SYNC_POLARITY_FALLING \ + CRS_CFGR_SYNCPOL /*!< Synchro Active on falling edge */ +/** + * @} + */ + +/** @defgroup CRS_LL_EC_FREQERRORDIR Frequency Error Direction + * @{ + */ +#define LL_CRS_FREQ_ERROR_DIR_UP \ + ((uint32_t)0x00U) /*!< Upcounting direction, the actual frequency is above the \ + target */ +#define LL_CRS_FREQ_ERROR_DIR_DOWN \ + ((uint32_t)CRS_ISR_FEDIR) /*!< Downcounting direction, the actual frequency is below \ + the target */ +/** + * @} + */ + +/** @defgroup CRS_LL_EC_DEFAULTVALUES Default Values + * @{ + */ +/** + * @brief Reset value of the RELOAD field + * @note The reset value of the RELOAD field corresponds to a target frequency of 48 MHz + * and a synchronization signal frequency of 1 kHz (SOF signal from USB) + */ +#define LL_CRS_RELOADVALUE_DEFAULT ((uint32_t)0xBB7FU) + +/** + * @brief Reset value of Frequency error limit. + */ +#define LL_CRS_ERRORLIMIT_DEFAULT ((uint32_t)0x22U) + +/** + * @brief Reset value of the HSI48 Calibration field + * @note The default value is 32, which corresponds to the middle of the trimming + * interval. The trimming step is around 67 kHz between two consecutive TRIM steps. A + * higher TRIM value corresponds to a higher output frequency + */ +#define LL_CRS_HSI48CALIBRATION_DEFAULT ((uint32_t)0x20U) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CRS_LL_Exported_Macros CRS Exported Macros + * @{ + */ + +/** @defgroup CRS_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in CRS register + * @param __INSTANCE__ CRS Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_CRS_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in CRS register + * @param __INSTANCE__ CRS Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_CRS_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup CRS_LL_EM_Exported_Macros_Calculate_Reload Exported_Macros_Calculate_Reload + * @{ + */ + +/** + * @brief Macro to calculate reload value to be set in CRS register according to target + * and sync frequencies + * @note The RELOAD value should be selected according to the ratio between + * the target frequency and the frequency of the synchronization source after + * prescaling. It is then decreased by one in order to reach the expected + * synchronization on the zero value. The formula is the following: + * RELOAD = (fTARGET / fSYNC) -1 + * @param __FTARGET__ Target frequency (value in Hz) + * @param __FSYNC__ Synchronization signal frequency (value in Hz) + * @retval Reload value (in Hz) + */ +#define __LL_CRS_CALC_CALCULATE_RELOADVALUE(__FTARGET__, __FSYNC__) \ + (((__FTARGET__) / (__FSYNC__)) - 1U) + + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup CRS_LL_Exported_Functions CRS Exported Functions + * @{ + */ + + /** @defgroup CRS_LL_EF_Configuration Configuration + * @{ + */ + + /** + * @brief Enable Frequency error counter + * @note When this bit is set, the CRS_CFGR register is write-protected and cannot be + * modified + * @rmtoll CR CEN LL_CRS_EnableFreqErrorCounter + * @retval None + */ + __STATIC_INLINE void LL_CRS_EnableFreqErrorCounter(void) + { + SET_BIT(CRS->CR, CRS_CR_CEN); + } + + /** + * @brief Disable Frequency error counter + * @rmtoll CR CEN LL_CRS_DisableFreqErrorCounter + * @retval None + */ + __STATIC_INLINE void LL_CRS_DisableFreqErrorCounter(void) + { + CLEAR_BIT(CRS->CR, CRS_CR_CEN); + } + + /** + * @brief Check if Frequency error counter is enabled or not + * @rmtoll CR CEN LL_CRS_IsEnabledFreqErrorCounter + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsEnabledFreqErrorCounter(void) + { + return (READ_BIT(CRS->CR, CRS_CR_CEN) == (CRS_CR_CEN)); + } + + /** + * @brief Enable Automatic trimming counter + * @rmtoll CR AUTOTRIMEN LL_CRS_EnableAutoTrimming + * @retval None + */ + __STATIC_INLINE void LL_CRS_EnableAutoTrimming(void) + { + SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN); + } + + /** + * @brief Disable Automatic trimming counter + * @rmtoll CR AUTOTRIMEN LL_CRS_DisableAutoTrimming + * @retval None + */ + __STATIC_INLINE void LL_CRS_DisableAutoTrimming(void) + { + CLEAR_BIT(CRS->CR, CRS_CR_AUTOTRIMEN); + } + + /** + * @brief Check if Automatic trimming is enabled or not + * @rmtoll CR AUTOTRIMEN LL_CRS_IsEnabledAutoTrimming + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsEnabledAutoTrimming(void) + { + return (READ_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) == (CRS_CR_AUTOTRIMEN)); + } + + /** + * @brief Set HSI48 oscillator smooth trimming + * @note When the AUTOTRIMEN bit is set, this field is controlled by hardware and is + * read-only + * @rmtoll CR TRIM LL_CRS_SetHSI48SmoothTrimming + * @param Value a number between Min_Data = 0 and Max_Data = 63 + * @note Default value can be set thanks to @ref LL_CRS_HSI48CALIBRATION_DEFAULT + * @retval None + */ + __STATIC_INLINE void LL_CRS_SetHSI48SmoothTrimming(uint32_t Value) + { + MODIFY_REG(CRS->CR, CRS_CR_TRIM, Value << CRS_CR_TRIM_Pos); + } + + /** + * @brief Get HSI48 oscillator smooth trimming + * @rmtoll CR TRIM LL_CRS_GetHSI48SmoothTrimming + * @retval a number between Min_Data = 0 and Max_Data = 63 + */ + __STATIC_INLINE uint32_t LL_CRS_GetHSI48SmoothTrimming(void) + { + return (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos); + } + + /** + * @brief Set counter reload value + * @rmtoll CFGR RELOAD LL_CRS_SetReloadCounter + * @param Value a number between Min_Data = 0 and Max_Data = 0xFFFF + * @note Default value can be set thanks to @ref LL_CRS_RELOADVALUE_DEFAULT + * Otherwise it can be calculated in using macro @ref + * __LL_CRS_CALC_CALCULATE_RELOADVALUE (_FTARGET_, _FSYNC_) + * @retval None + */ + __STATIC_INLINE void LL_CRS_SetReloadCounter(uint32_t Value) + { + MODIFY_REG(CRS->CFGR, CRS_CFGR_RELOAD, Value); + } + + /** + * @brief Get counter reload value + * @rmtoll CFGR RELOAD LL_CRS_GetReloadCounter + * @retval a number between Min_Data = 0 and Max_Data = 0xFFFF + */ + __STATIC_INLINE uint32_t LL_CRS_GetReloadCounter(void) + { + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD)); + } + + /** + * @brief Set frequency error limit + * @rmtoll CFGR FELIM LL_CRS_SetFreqErrorLimit + * @param Value a number between Min_Data = 0 and Max_Data = 255 + * @note Default value can be set thanks to @ref LL_CRS_ERRORLIMIT_DEFAULT + * @retval None + */ + __STATIC_INLINE void LL_CRS_SetFreqErrorLimit(uint32_t Value) + { + MODIFY_REG(CRS->CFGR, CRS_CFGR_FELIM, Value << CRS_CFGR_FELIM_Pos); + } + + /** + * @brief Get frequency error limit + * @rmtoll CFGR FELIM LL_CRS_GetFreqErrorLimit + * @retval A number between Min_Data = 0 and Max_Data = 255 + */ + __STATIC_INLINE uint32_t LL_CRS_GetFreqErrorLimit(void) + { + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_FELIM) >> CRS_CFGR_FELIM_Pos); + } + + /** + * @brief Set division factor for SYNC signal + * @rmtoll CFGR SYNCDIV LL_CRS_SetSyncDivider + * @param Divider This parameter can be one of the following values: + * @arg @ref LL_CRS_SYNC_DIV_1 + * @arg @ref LL_CRS_SYNC_DIV_2 + * @arg @ref LL_CRS_SYNC_DIV_4 + * @arg @ref LL_CRS_SYNC_DIV_8 + * @arg @ref LL_CRS_SYNC_DIV_16 + * @arg @ref LL_CRS_SYNC_DIV_32 + * @arg @ref LL_CRS_SYNC_DIV_64 + * @arg @ref LL_CRS_SYNC_DIV_128 + * @retval None + */ + __STATIC_INLINE void LL_CRS_SetSyncDivider(uint32_t Divider) + { + MODIFY_REG(CRS->CFGR, CRS_CFGR_SYNCDIV, Divider); + } + + /** + * @brief Get division factor for SYNC signal + * @rmtoll CFGR SYNCDIV LL_CRS_GetSyncDivider + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRS_SYNC_DIV_1 + * @arg @ref LL_CRS_SYNC_DIV_2 + * @arg @ref LL_CRS_SYNC_DIV_4 + * @arg @ref LL_CRS_SYNC_DIV_8 + * @arg @ref LL_CRS_SYNC_DIV_16 + * @arg @ref LL_CRS_SYNC_DIV_32 + * @arg @ref LL_CRS_SYNC_DIV_64 + * @arg @ref LL_CRS_SYNC_DIV_128 + */ + __STATIC_INLINE uint32_t LL_CRS_GetSyncDivider(void) + { + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_SYNCDIV)); + } + + /** + * @brief Set SYNC signal source + * @rmtoll CFGR SYNCSRC LL_CRS_SetSyncSignalSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_CRS_SYNC_SOURCE_GPIO + * @arg @ref LL_CRS_SYNC_SOURCE_LSE + * @arg @ref LL_CRS_SYNC_SOURCE_USB + * @retval None + */ + __STATIC_INLINE void LL_CRS_SetSyncSignalSource(uint32_t Source) + { + MODIFY_REG(CRS->CFGR, CRS_CFGR_SYNCSRC, Source); + } + + /** + * @brief Get SYNC signal source + * @rmtoll CFGR SYNCSRC LL_CRS_GetSyncSignalSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRS_SYNC_SOURCE_GPIO + * @arg @ref LL_CRS_SYNC_SOURCE_LSE + * @arg @ref LL_CRS_SYNC_SOURCE_USB + */ + __STATIC_INLINE uint32_t LL_CRS_GetSyncSignalSource(void) + { + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_SYNCSRC)); + } + + /** + * @brief Set input polarity for the SYNC signal source + * @rmtoll CFGR SYNCPOL LL_CRS_SetSyncPolarity + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_CRS_SYNC_POLARITY_RISING + * @arg @ref LL_CRS_SYNC_POLARITY_FALLING + * @retval None + */ + __STATIC_INLINE void LL_CRS_SetSyncPolarity(uint32_t Polarity) + { + MODIFY_REG(CRS->CFGR, CRS_CFGR_SYNCPOL, Polarity); + } + + /** + * @brief Get input polarity for the SYNC signal source + * @rmtoll CFGR SYNCPOL LL_CRS_GetSyncPolarity + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRS_SYNC_POLARITY_RISING + * @arg @ref LL_CRS_SYNC_POLARITY_FALLING + */ + __STATIC_INLINE uint32_t LL_CRS_GetSyncPolarity(void) + { + return (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_SYNCPOL)); + } + + /** + * @brief Configure CRS for the synchronization + * @rmtoll CR TRIM LL_CRS_ConfigSynchronization\n + * CFGR RELOAD LL_CRS_ConfigSynchronization\n + * CFGR FELIM LL_CRS_ConfigSynchronization\n + * CFGR SYNCDIV LL_CRS_ConfigSynchronization\n + * CFGR SYNCSRC LL_CRS_ConfigSynchronization\n + * CFGR SYNCPOL LL_CRS_ConfigSynchronization + * @param HSI48CalibrationValue a number between Min_Data = 0 and Max_Data = 63 + * @param ErrorLimitValue a number between Min_Data = 0 and Max_Data = 0xFFFF + * @param ReloadValue a number between Min_Data = 0 and Max_Data = 255 + * @param Settings This parameter can be a combination of the following values: + * @arg @ref LL_CRS_SYNC_DIV_1 or @ref LL_CRS_SYNC_DIV_2 or @ref + * LL_CRS_SYNC_DIV_4 or @ref LL_CRS_SYNC_DIV_8 or @ref LL_CRS_SYNC_DIV_16 or @ref + * LL_CRS_SYNC_DIV_32 or @ref LL_CRS_SYNC_DIV_64 or @ref LL_CRS_SYNC_DIV_128 + * @arg @ref LL_CRS_SYNC_SOURCE_GPIO or @ref LL_CRS_SYNC_SOURCE_LSE or @ref + * LL_CRS_SYNC_SOURCE_USB + * @arg @ref LL_CRS_SYNC_POLARITY_RISING or @ref LL_CRS_SYNC_POLARITY_FALLING + * @retval None + */ + __STATIC_INLINE void LL_CRS_ConfigSynchronization(uint32_t HSI48CalibrationValue, + uint32_t ErrorLimitValue, + uint32_t ReloadValue, + uint32_t Settings) + { + MODIFY_REG(CRS->CR, CRS_CR_TRIM, HSI48CalibrationValue << CRS_CR_TRIM_Pos); + MODIFY_REG(CRS->CFGR, + CRS_CFGR_RELOAD | CRS_CFGR_FELIM | CRS_CFGR_SYNCDIV | + CRS_CFGR_SYNCSRC | CRS_CFGR_SYNCPOL, + ReloadValue | (ErrorLimitValue << CRS_CFGR_FELIM_Pos) | Settings); + } + + /** + * @} + */ + + /** @defgroup CRS_LL_EF_CRS_Management CRS_Management + * @{ + */ + + /** + * @brief Generate software SYNC event + * @rmtoll CR SWSYNC LL_CRS_GenerateEvent_SWSYNC + * @retval None + */ + __STATIC_INLINE void LL_CRS_GenerateEvent_SWSYNC(void) + { + SET_BIT(CRS->CR, CRS_CR_SWSYNC); + } + + /** + * @brief Get the frequency error direction latched in the time of the last + * SYNC event + * @rmtoll ISR FEDIR LL_CRS_GetFreqErrorDirection + * @retval Returned value can be one of the following values: + * @arg @ref LL_CRS_FREQ_ERROR_DIR_UP + * @arg @ref LL_CRS_FREQ_ERROR_DIR_DOWN + */ + __STATIC_INLINE uint32_t LL_CRS_GetFreqErrorDirection(void) + { + return (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR)); + } + + /** + * @brief Get the frequency error counter value latched in the time of the last SYNC + * event + * @rmtoll ISR FECAP LL_CRS_GetFreqErrorCapture + * @retval A number between Min_Data = 0x0000 and Max_Data = 0xFFFF + */ + __STATIC_INLINE uint32_t LL_CRS_GetFreqErrorCapture(void) + { + return (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos); + } + + /** + * @} + */ + + /** @defgroup CRS_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + + /** + * @brief Check if SYNC event OK signal occurred or not + * @rmtoll ISR SYNCOKF LL_CRS_IsActiveFlag_SYNCOK + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_SYNCOK(void) + { + return (READ_BIT(CRS->ISR, CRS_ISR_SYNCOKF) == (CRS_ISR_SYNCOKF)); + } + + /** + * @brief Check if SYNC warning signal occurred or not + * @rmtoll ISR SYNCWARNF LL_CRS_IsActiveFlag_SYNCWARN + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_SYNCWARN(void) + { + return (READ_BIT(CRS->ISR, CRS_ISR_SYNCWARNF) == (CRS_ISR_SYNCWARNF)); + } + + /** + * @brief Check if Synchronization or trimming error signal occurred or not + * @rmtoll ISR ERRF LL_CRS_IsActiveFlag_ERR + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_ERR(void) + { + return (READ_BIT(CRS->ISR, CRS_ISR_ERRF) == (CRS_ISR_ERRF)); + } + + /** + * @brief Check if Expected SYNC signal occurred or not + * @rmtoll ISR ESYNCF LL_CRS_IsActiveFlag_ESYNC + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_ESYNC(void) + { + return (READ_BIT(CRS->ISR, CRS_ISR_ESYNCF) == (CRS_ISR_ESYNCF)); + } + + /** + * @brief Check if SYNC error signal occurred or not + * @rmtoll ISR SYNCERR LL_CRS_IsActiveFlag_SYNCERR + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_SYNCERR(void) + { + return (READ_BIT(CRS->ISR, CRS_ISR_SYNCERR) == (CRS_ISR_SYNCERR)); + } + + /** + * @brief Check if SYNC missed error signal occurred or not + * @rmtoll ISR SYNCMISS LL_CRS_IsActiveFlag_SYNCMISS + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_SYNCMISS(void) + { + return (READ_BIT(CRS->ISR, CRS_ISR_SYNCMISS) == (CRS_ISR_SYNCMISS)); + } + + /** + * @brief Check if Trimming overflow or underflow occurred or not + * @rmtoll ISR TRIMOVF LL_CRS_IsActiveFlag_TRIMOVF + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsActiveFlag_TRIMOVF(void) + { + return (READ_BIT(CRS->ISR, CRS_ISR_TRIMOVF) == (CRS_ISR_TRIMOVF)); + } + + /** + * @brief Clear the SYNC event OK flag + * @rmtoll ICR SYNCOKC LL_CRS_ClearFlag_SYNCOK + * @retval None + */ + __STATIC_INLINE void LL_CRS_ClearFlag_SYNCOK(void) + { + WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC); + } + + /** + * @brief Clear the SYNC warning flag + * @rmtoll ICR SYNCWARNC LL_CRS_ClearFlag_SYNCWARN + * @retval None + */ + __STATIC_INLINE void LL_CRS_ClearFlag_SYNCWARN(void) + { + WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC); + } + + /** + * @brief Clear TRIMOVF, SYNCMISS and SYNCERR bits and consequently also + * the ERR flag + * @rmtoll ICR ERRC LL_CRS_ClearFlag_ERR + * @retval None + */ + __STATIC_INLINE void LL_CRS_ClearFlag_ERR(void) + { + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); + } + + /** + * @brief Clear Expected SYNC flag + * @rmtoll ICR ESYNCC LL_CRS_ClearFlag_ESYNC + * @retval None + */ + __STATIC_INLINE void LL_CRS_ClearFlag_ESYNC(void) + { + WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC); + } + + /** + * @} + */ + + /** @defgroup CRS_LL_EF_IT_Management IT_Management + * @{ + */ + + /** + * @brief Enable SYNC event OK interrupt + * @rmtoll CR SYNCOKIE LL_CRS_EnableIT_SYNCOK + * @retval None + */ + __STATIC_INLINE void LL_CRS_EnableIT_SYNCOK(void) + { + SET_BIT(CRS->CR, CRS_CR_SYNCOKIE); + } + + /** + * @brief Disable SYNC event OK interrupt + * @rmtoll CR SYNCOKIE LL_CRS_DisableIT_SYNCOK + * @retval None + */ + __STATIC_INLINE void LL_CRS_DisableIT_SYNCOK(void) + { + CLEAR_BIT(CRS->CR, CRS_CR_SYNCOKIE); + } + + /** + * @brief Check if SYNC event OK interrupt is enabled or not + * @rmtoll CR SYNCOKIE LL_CRS_IsEnabledIT_SYNCOK + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsEnabledIT_SYNCOK(void) + { + return (READ_BIT(CRS->CR, CRS_CR_SYNCOKIE) == (CRS_CR_SYNCOKIE)); + } + + /** + * @brief Enable SYNC warning interrupt + * @rmtoll CR SYNCWARNIE LL_CRS_EnableIT_SYNCWARN + * @retval None + */ + __STATIC_INLINE void LL_CRS_EnableIT_SYNCWARN(void) + { + SET_BIT(CRS->CR, CRS_CR_SYNCWARNIE); + } + + /** + * @brief Disable SYNC warning interrupt + * @rmtoll CR SYNCWARNIE LL_CRS_DisableIT_SYNCWARN + * @retval None + */ + __STATIC_INLINE void LL_CRS_DisableIT_SYNCWARN(void) + { + CLEAR_BIT(CRS->CR, CRS_CR_SYNCWARNIE); + } + + /** + * @brief Check if SYNC warning interrupt is enabled or not + * @rmtoll CR SYNCWARNIE LL_CRS_IsEnabledIT_SYNCWARN + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsEnabledIT_SYNCWARN(void) + { + return (READ_BIT(CRS->CR, CRS_CR_SYNCWARNIE) == (CRS_CR_SYNCWARNIE)); + } + + /** + * @brief Enable Synchronization or trimming error interrupt + * @rmtoll CR ERRIE LL_CRS_EnableIT_ERR + * @retval None + */ + __STATIC_INLINE void LL_CRS_EnableIT_ERR(void) + { + SET_BIT(CRS->CR, CRS_CR_ERRIE); + } + + /** + * @brief Disable Synchronization or trimming error interrupt + * @rmtoll CR ERRIE LL_CRS_DisableIT_ERR + * @retval None + */ + __STATIC_INLINE void LL_CRS_DisableIT_ERR(void) + { + CLEAR_BIT(CRS->CR, CRS_CR_ERRIE); + } + + /** + * @brief Check if Synchronization or trimming error interrupt is enabled or not + * @rmtoll CR ERRIE LL_CRS_IsEnabledIT_ERR + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsEnabledIT_ERR(void) + { + return (READ_BIT(CRS->CR, CRS_CR_ERRIE) == (CRS_CR_ERRIE)); + } + + /** + * @brief Enable Expected SYNC interrupt + * @rmtoll CR ESYNCIE LL_CRS_EnableIT_ESYNC + * @retval None + */ + __STATIC_INLINE void LL_CRS_EnableIT_ESYNC(void) + { + SET_BIT(CRS->CR, CRS_CR_ESYNCIE); + } + + /** + * @brief Disable Expected SYNC interrupt + * @rmtoll CR ESYNCIE LL_CRS_DisableIT_ESYNC + * @retval None + */ + __STATIC_INLINE void LL_CRS_DisableIT_ESYNC(void) + { + CLEAR_BIT(CRS->CR, CRS_CR_ESYNCIE); + } + + /** + * @brief Check if Expected SYNC interrupt is enabled or not + * @rmtoll CR ESYNCIE LL_CRS_IsEnabledIT_ESYNC + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_CRS_IsEnabledIT_ESYNC(void) + { + return (READ_BIT(CRS->CR, CRS_CR_ESYNCIE) == (CRS_CR_ESYNCIE)); + } + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup CRS_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + ErrorStatus LL_CRS_DeInit(void); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* defined(CRS) */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_CRS_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_dac.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_dac.h new file mode 100644 index 0000000000..a2429d89dd --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_dac.h @@ -0,0 +1,1583 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_dac.h + * @author MCD Application Team + * @brief Header file of DAC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_DAC_H +#define __STM32F0xx_LL_DAC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(DAC1) + +/** @defgroup DAC_LL DAC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup DAC_LL_Private_Constants DAC Private Constants + * @{ + */ + +/* Internal masks for DAC channels definition */ +/* To select into literal LL_DAC_CHANNEL_x the relevant bits for: */ +/* - channel bits position into register CR */ +/* - channel bits position into register SWTRIG */ +/* - channel register offset of data holding register DHRx */ +/* - channel register offset of data output register DORx */ +#define DAC_CR_CH1_BITOFFSET \ + 0U /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 1 \ + */ +#define DAC_CR_CH2_BITOFFSET \ + 16U /* Position of channel bits into registers CR, MCR, CCR, SHHR, SHRR of channel 2 \ + */ +#define DAC_CR_CHX_BITOFFSET_MASK (DAC_CR_CH1_BITOFFSET | DAC_CR_CH2_BITOFFSET) + +#define DAC_SWTR_CH1 \ + (DAC_SWTRIGR_SWTRIG1) /* Channel bit into register SWTRIGR of channel 1. This bit is \ + into area of LL_DAC_CR_CHx_BITOFFSET but excluded by mask \ + DAC_CR_CHX_BITOFFSET_MASK (done to be enable to trig SW \ + start of both DAC channels simultaneously). */ +#if defined(DAC_CHANNEL2_SUPPORT) +#define DAC_SWTR_CH2 \ + (DAC_SWTRIGR_SWTRIG2) /* Channel bit into register SWTRIGR of channel 2. This bit is \ + into area of LL_DAC_CR_CHx_BITOFFSET but excluded by mask \ + DAC_CR_CHX_BITOFFSET_MASK (done to be enable to trig SW \ + start of both DAC channels simultaneously). */ +#define DAC_SWTR_CHX_MASK (DAC_SWTR_CH1 | DAC_SWTR_CH2) +#else +#define DAC_SWTR_CHX_MASK (DAC_SWTR_CH1) +#endif /* DAC_CHANNEL2_SUPPORT */ + +#define DAC_REG_DHR12R1_REGOFFSET \ + 0x00000000U /* Register DHR12Rx channel 1 taken as reference */ +#define DAC_REG_DHR12L1_REGOFFSET \ + 0x00100000U /* Register offset of DHR12Lx channel 1 versus DHR12Rx channel 1 \ + (shifted left of 20 bits) */ +#define DAC_REG_DHR8R1_REGOFFSET \ + 0x02000000U /* Register offset of DHR8Rx channel 1 versus DHR12Rx channel 1 \ + (shifted left of 24 bits) */ +#if defined(DAC_CHANNEL2_SUPPORT) +#define DAC_REG_DHR12R2_REGOFFSET \ + 0x00030000U /* Register offset of DHR12Rx channel 2 versus DHR12Rx channel 1 \ + (shifted left of 16 bits) */ +#define DAC_REG_DHR12L2_REGOFFSET \ + 0x00400000U /* Register offset of DHR12Lx channel 2 versus DHR12Rx channel 1 \ + (shifted left of 20 bits) */ +#define DAC_REG_DHR8R2_REGOFFSET \ + 0x05000000U /* Register offset of DHR8Rx channel 2 versus DHR12Rx channel 1 \ + (shifted left of 24 bits) */ +#endif /* DAC_CHANNEL2_SUPPORT */ +#define DAC_REG_DHR12RX_REGOFFSET_MASK 0x000F0000U +#define DAC_REG_DHR12LX_REGOFFSET_MASK 0x00F00000U +#define DAC_REG_DHR8RX_REGOFFSET_MASK 0x0F000000U +#define DAC_REG_DHRX_REGOFFSET_MASK \ + (DAC_REG_DHR12RX_REGOFFSET_MASK | DAC_REG_DHR12LX_REGOFFSET_MASK | \ + DAC_REG_DHR8RX_REGOFFSET_MASK) + +#define DAC_REG_DOR1_REGOFFSET \ + 0x00000000U /* Register DORx channel 1 taken as reference */ +#if defined(DAC_CHANNEL2_SUPPORT) +#define DAC_REG_DOR2_REGOFFSET \ + 0x10000000U /* Register offset of DORx channel 1 versus DORx channel 2 (shifted left \ + of 28 bits) */ +#define DAC_REG_DORX_REGOFFSET_MASK (DAC_REG_DOR1_REGOFFSET | DAC_REG_DOR2_REGOFFSET) +#else +#define DAC_REG_DORX_REGOFFSET_MASK (DAC_REG_DOR1_REGOFFSET) +#endif /* DAC_CHANNEL2_SUPPORT */ + +#define DAC_REG_REGOFFSET_MASK_POSBIT0 \ + 0x0000000FU /* Mask of registers offset (DHR12Rx, DHR12Lx, DHR8Rx, DORx, ...) when \ + shifted to position 0 */ + +#define DAC_REG_DHR12RX_REGOFFSET_BITOFFSET_POS \ + 16U /* Position of bits register offset of DHR12Rx channel 1 or 2 versus DHR12Rx \ + channel 1 (shifted left of 16 bits) */ +#define DAC_REG_DHR12LX_REGOFFSET_BITOFFSET_POS \ + 20U /* Position of bits register offset of DHR12Lx channel 1 or 2 versus DHR12Rx \ + channel 1 (shifted left of 20 bits) */ +#define DAC_REG_DHR8RX_REGOFFSET_BITOFFSET_POS \ + 24U /* Position of bits register offset of DHR8Rx channel 1 or 2 versus DHR12Rx \ + channel 1 (shifted left of 24 bits) */ +#define DAC_REG_DORX_REGOFFSET_BITOFFSET_POS \ + 28U /* Position of bits register offset of DORx channel 1 or 2 versus DORx channel 1 \ + (shifted left of 28 bits) */ + +/* DAC registers bits positions */ +#if defined(DAC_CHANNEL2_SUPPORT) +#define DAC_DHR12RD_DACC2DHR_BITOFFSET_POS \ + 16U /* Value equivalent to POSITION_VAL(DAC_DHR12RD_DACC2DHR) */ +#define DAC_DHR12LD_DACC2DHR_BITOFFSET_POS \ + 20U /* Value equivalent to POSITION_VAL(DAC_DHR12LD_DACC2DHR) */ +#define DAC_DHR8RD_DACC2DHR_BITOFFSET_POS \ + 8U /* Value equivalent to POSITION_VAL(DAC_DHR8RD_DACC2DHR) */ +#endif /* DAC_CHANNEL2_SUPPORT */ + +/* Miscellaneous data */ +#define DAC_DIGITAL_SCALE_12BITS \ + 4095U /* Full-scale digital value with a resolution of 12 bits (voltage range \ + determined by analog voltage references Vref+ and Vref-, refer to reference \ + manual) */ + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DAC_LL_Private_Macros DAC Private Macros + * @{ + */ + +/** + * @brief Driver macro reserved for internal use: set a pointer to + * a register from a register basis from which an offset + * is applied. + * @param __REG__ Register basis from which the offset is applied. + * @param __REG_OFFFSET__ Offset to be applied (unit: number of registers). + * @retval Pointer to register address + */ +#define __DAC_PTR_REG_OFFSET(__REG__, __REG_OFFFSET__) \ + ((uint32_t *)((uint32_t)((uint32_t)(&(__REG__)) + ((__REG_OFFFSET__) << 2U)))) + +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup DAC_LL_ES_INIT DAC Exported Init structure + * @{ + */ + + /** + * @brief Structure definition of some features of DAC instance. + */ + typedef struct + { + uint32_t TriggerSource; /*!< Set the conversion trigger source for the selected + DAC channel: internal (SW start) or from external IP + (timer event, external interrupt line). This parameter + can be a value of @ref DAC_LL_EC_TRIGGER_SOURCE + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetTriggerSource(). */ + +#if defined(DAC_CR_WAVE1) + uint32_t + WaveAutoGeneration; /*!< Set the waveform automatic generation mode for the + selected DAC channel. This parameter can be a value of + @ref DAC_LL_EC_WAVE_AUTO_GENERATION_MODE + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetWaveAutoGeneration(). */ + + uint32_t + WaveAutoGenerationConfig; /*!< Set the waveform automatic generation mode for + the selected DAC channel. If waveform automatic + generation mode is set to noise, this parameter + can be a value of @ref + DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS If waveform + automatic generation mode is set to triangle, + this parameter can be a value of @ref + DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE + @note If waveform automatic generation mode is + disabled, this parameter is discarded. + + This feature can be modified afterwards using + unitary function @ref LL_DAC_SetWaveNoiseLFSR() + or @ref LL_DAC_SetWaveTriangleAmplitude(), + depending on the wave automatic generation + selected. */ +#endif + + uint32_t OutputBuffer; /*!< Set the output buffer for the selected DAC channel. + This parameter can be a value of @ref + DAC_LL_EC_OUTPUT_BUFFER + + This feature can be modified afterwards using unitary + function @ref LL_DAC_SetOutputBuffer(). */ + + } LL_DAC_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DAC_LL_Exported_Constants DAC Exported Constants + * @{ + */ + +/** @defgroup DAC_LL_EC_GET_FLAG DAC flags + * @brief Flags defines which can be used with LL_DAC_ReadReg function + * @{ + */ +/* DAC channel 1 flags */ +#define LL_DAC_FLAG_DMAUDR1 (DAC_SR_DMAUDR1) /*!< DAC channel 1 flag DMA underrun */ + +#if defined(DAC_CHANNEL2_SUPPORT) +/* DAC channel 2 flags */ +#define LL_DAC_FLAG_DMAUDR2 (DAC_SR_DMAUDR2) /*!< DAC channel 2 flag DMA underrun */ +#endif /* DAC_CHANNEL2_SUPPORT */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_IT DAC interruptions + * @brief IT defines which can be used with LL_DAC_ReadReg and LL_DAC_WriteReg + * functions + * @{ + */ +#define LL_DAC_IT_DMAUDRIE1 \ + (DAC_CR_DMAUDRIE1) /*!< DAC channel 1 interruption DMA underrun */ +#if defined(DAC_CHANNEL2_SUPPORT) +#define LL_DAC_IT_DMAUDRIE2 \ + (DAC_CR_DMAUDRIE2) /*!< DAC channel 2 interruption DMA underrun */ +#endif /* DAC_CHANNEL2_SUPPORT */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_CHANNEL DAC channels + * @{ + */ +#define LL_DAC_CHANNEL_1 \ + (DAC_REG_DOR1_REGOFFSET | DAC_REG_DHR12R1_REGOFFSET | DAC_REG_DHR12L1_REGOFFSET | \ + DAC_REG_DHR8R1_REGOFFSET | DAC_CR_CH1_BITOFFSET | \ + DAC_SWTR_CH1) /*!< DAC channel 1 */ +#if defined(DAC_CHANNEL2_SUPPORT) +#define LL_DAC_CHANNEL_2 \ + (DAC_REG_DOR2_REGOFFSET | DAC_REG_DHR12R2_REGOFFSET | DAC_REG_DHR12L2_REGOFFSET | \ + DAC_REG_DHR8R2_REGOFFSET | DAC_CR_CH2_BITOFFSET | \ + DAC_SWTR_CH2) /*!< DAC channel 2 */ +#endif /* DAC_CHANNEL2_SUPPORT */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_TRIGGER_SOURCE DAC trigger source + * @{ + */ +#define LL_DAC_TRIG_SOFTWARE \ + (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | \ + DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger internal (SW start) */ +#define LL_DAC_TRIG_EXT_TIM2_TRGO \ + (DAC_CR_TSEL1_2) /*!< DAC channel conversion trigger from external IP: TIM2 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM3_TRGO \ + (DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM3 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM4_TRGO \ + (DAC_CR_TSEL1_2 | \ + DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external IP: TIM4 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM6_TRGO \ + 0x00000000U /*!< DAC channel conversion trigger from external IP: TIM6 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM7_TRGO \ + (DAC_CR_TSEL1_1) /*!< DAC channel conversion trigger from external IP: TIM7 TRGO. */ +#define LL_DAC_TRIG_EXT_TIM15_TRGO \ + (DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0) /*!< DAC channel conversion trigger from external \ + IP: TIM15 TRGO. */ +#define LL_DAC_TRIG_EXT_EXTI_LINE9 \ + (DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1) /*!< DAC channel conversion trigger from external \ + IP: external interrupt line 9. */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_WAVE_AUTO_GENERATION_MODE DAC waveform automatic generation mode + * @{ + */ +#define LL_DAC_WAVE_AUTO_GENERATION_NONE \ + 0x00000000U /*!< DAC channel wave auto generation mode disabled. */ +#define LL_DAC_WAVE_AUTO_GENERATION_NOISE \ + (DAC_CR_WAVE1_0) /*!< DAC channel wave auto generation mode enabled, set generated \ + noise waveform. */ +#define LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE \ + (DAC_CR_WAVE1_1) /*!< DAC channel wave auto generation mode enabled, set generated \ + triangle waveform. */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_WAVE_NOISE_LFSR_UNMASK_BITS DAC wave generation - Noise LFSR + * unmask bits + * @{ + */ +#define LL_DAC_NOISE_LFSR_UNMASK_BIT0 \ + 0x00000000U /*!< Noise wave generation, unmask LFSR bit0, for the selected DAC \ + channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 \ + (DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[1:0], for the selected \ + DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 \ + (DAC_CR_MAMP1_1) /*!< Noise wave generation, unmask LFSR bits[2:0], for the selected \ + DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 \ + (DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[3:0], \ + for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS4_0 \ + (DAC_CR_MAMP1_2) /*!< Noise wave generation, unmask LFSR bits[4:0], for the selected \ + DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS5_0 \ + (DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[5:0], \ + for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS6_0 \ + (DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1) /*!< Noise wave generation, unmask LFSR bits[6:0], \ + for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS7_0 \ + (DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | \ + DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[7:0], for the selected \ + DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS8_0 \ + (DAC_CR_MAMP1_3) /*!< Noise wave generation, unmask LFSR bits[8:0], for the selected \ + DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS9_0 \ + (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[9:0], \ + for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS10_0 \ + (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1) /*!< Noise wave generation, unmask LFSR \ + bits[10:0], for the selected DAC channel */ +#define LL_DAC_NOISE_LFSR_UNMASK_BITS11_0 \ + (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | \ + DAC_CR_MAMP1_0) /*!< Noise wave generation, unmask LFSR bits[11:0], for the \ + selected DAC channel */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_WAVE_TRIANGLE_AMPLITUDE DAC wave generation - Triangle amplitude + * @{ + */ +#define LL_DAC_TRIANGLE_AMPLITUDE_1 \ + 0x00000000U /*!< Triangle wave generation, amplitude of 1 LSB of DAC output range, \ + for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_3 \ + (DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 3 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_7 \ + (DAC_CR_MAMP1_1) /*!< Triangle wave generation, amplitude of 7 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_15 \ + (DAC_CR_MAMP1_1 | \ + DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 15 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_31 \ + (DAC_CR_MAMP1_2) /*!< Triangle wave generation, amplitude of 31 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_63 \ + (DAC_CR_MAMP1_2 | \ + DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 63 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_127 \ + (DAC_CR_MAMP1_2 | \ + DAC_CR_MAMP1_1) /*!< Triangle wave generation, amplitude of 127 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_255 \ + (DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | \ + DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 255 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_511 \ + (DAC_CR_MAMP1_3) /*!< Triangle wave generation, amplitude of 512 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_1023 \ + (DAC_CR_MAMP1_3 | \ + DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 1023 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_2047 \ + (DAC_CR_MAMP1_3 | \ + DAC_CR_MAMP1_1) /*!< Triangle wave generation, amplitude of 2047 LSB of DAC output \ + range, for the selected DAC channel */ +#define LL_DAC_TRIANGLE_AMPLITUDE_4095 \ + (DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | \ + DAC_CR_MAMP1_0) /*!< Triangle wave generation, amplitude of 4095 LSB of DAC output \ + range, for the selected DAC channel */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_OUTPUT_BUFFER DAC channel output buffer + * @{ + */ +#define LL_DAC_OUTPUT_BUFFER_ENABLE \ + 0x00000000U /*!< The selected DAC channel output is buffered: higher drive current \ + capability, but also higher current consumption */ +#define LL_DAC_OUTPUT_BUFFER_DISABLE \ + (DAC_CR_BOFF1) /*!< The selected DAC channel output is not buffered: lower drive \ + current capability, but also lower current consumption */ +/** + * @} + */ + + +/** @defgroup DAC_LL_EC_RESOLUTION DAC channel output resolution + * @{ + */ +#define LL_DAC_RESOLUTION_12B 0x00000000U /*!< DAC channel resolution 12 bits */ +#define LL_DAC_RESOLUTION_8B 0x00000002U /*!< DAC channel resolution 8 bits */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_REGISTERS DAC registers compliant with specific purpose + * @{ + */ +/* List of DAC registers intended to be used (most commonly) with */ +/* DMA transfer. */ +/* Refer to function @ref LL_DAC_DMA_GetRegAddr(). */ +#define LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED \ + DAC_REG_DHR12RX_REGOFFSET_BITOFFSET_POS /*!< DAC channel data holding register 12 \ + bits right aligned */ +#define LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED \ + DAC_REG_DHR12LX_REGOFFSET_BITOFFSET_POS /*!< DAC channel data holding register 12 \ + bits left aligned */ +#define LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED \ + DAC_REG_DHR8RX_REGOFFSET_BITOFFSET_POS /*!< DAC channel data holding register 8 bits \ + right aligned */ +/** + * @} + */ + +/** @defgroup DAC_LL_EC_HW_DELAYS Definitions of DAC hardware constraints delays + * @note Only DAC IP HW delays are defined in DAC LL driver driver, + * not timeout values. + * For details on delays values, refer to descriptions in source code + * above each literal definition. + * @{ + */ + +/* Delay for DAC channel voltage settling time from DAC channel startup */ +/* (transition from disable to enable). */ +/* Note: DAC channel startup time depends on board application environment: */ +/* impedance connected to DAC channel output. */ +/* The delay below is specified under conditions: */ +/* - voltage maximum transition (lowest to highest value) */ +/* - until voltage reaches final value +-1LSB */ +/* - DAC channel output buffer enabled */ +/* - load impedance of 5kOhm (min), 50pF (max) */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tWAKEUP"). */ +/* Unit: us */ +#define LL_DAC_DELAY_STARTUP_VOLTAGE_SETTLING_US \ + 15U /*!< Delay for DAC channel voltage settling time from DAC channel startup \ + (transition from disable to enable) */ + +/* Delay for DAC channel voltage settling time. */ +/* Note: DAC channel startup time depends on board application environment: */ +/* impedance connected to DAC channel output. */ +/* The delay below is specified under conditions: */ +/* - voltage maximum transition (lowest to highest value) */ +/* - until voltage reaches final value +-1LSB */ +/* - DAC channel output buffer enabled */ +/* - load impedance of 5kOhm min, 50pF max */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tSETTLING"). */ +/* Unit: us */ +#define LL_DAC_DELAY_VOLTAGE_SETTLING_US \ + 12U /*!< Delay for DAC channel voltage settling time */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DAC_LL_Exported_Macros DAC Exported Macros + * @{ + */ + +/** @defgroup DAC_LL_EM_WRITE_READ Common write and read registers macros + * @{ + */ + +/** + * @brief Write a value in DAC register + * @param __INSTANCE__ DAC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_DAC_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in DAC register + * @param __INSTANCE__ DAC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_DAC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + +/** + * @} + */ + +/** @defgroup DAC_LL_EM_HELPER_MACRO DAC helper macro + * @{ + */ + +/** + * @brief Helper macro to get DAC channel number in decimal format + * from literals LL_DAC_CHANNEL_x. + * Example: + * __LL_DAC_CHANNEL_TO_DECIMAL_NB(LL_DAC_CHANNEL_1) + * will return decimal number "1". + * @note The input can be a value from functions where a channel + * number is returned. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval 1...2 (value "2" depending on DAC channel 2 availability) + */ +#define __LL_DAC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) ((__CHANNEL__)&DAC_SWTR_CHX_MASK) + +/** + * @brief Helper macro to get DAC channel in literal format LL_DAC_CHANNEL_x + * from number in decimal format. + * Example: + * __LL_DAC_DECIMAL_NB_TO_CHANNEL(1) + * will return a data equivalent to "LL_DAC_CHANNEL_1". + * @note If the input parameter does not correspond to a DAC channel, + * this macro returns value '0'. + * @param __DECIMAL_NB__ 1...2 (value "2" depending on DAC channel 2 availability) + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + */ +#if defined(DAC_CHANNEL2_SUPPORT) +#define __LL_DAC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__) \ + (((__DECIMAL_NB__) == 1U) ? (LL_DAC_CHANNEL_1) \ + : (((__DECIMAL_NB__) == 2U) ? (LL_DAC_CHANNEL_2) : (0))) +#else +#define __LL_DAC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__) \ + (((__DECIMAL_NB__) == 1U) ? (LL_DAC_CHANNEL_1) : (0)) +#endif /* DAC_CHANNEL2_SUPPORT */ + +/** + * @brief Helper macro to define the DAC conversion data full-scale digital + * value corresponding to the selected DAC resolution. + * @note DAC conversion data full-scale corresponds to voltage range + * determined by analog voltage references Vref+ and Vref- + * (refer to reference manual). + * @param __DAC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_DAC_RESOLUTION_12B + * @arg @ref LL_DAC_RESOLUTION_8B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) \ + ((0x00000FFFU) >> ((__DAC_RESOLUTION__) << 1U)) + +/** + * @brief Helper macro to calculate the DAC conversion data (unit: digital + * value) corresponding to a voltage (unit: mVolt). + * @note This helper macro is intended to provide input data in voltage + * rather than digital value, + * to be used with LL DAC functions such as + * @ref LL_DAC_ConvertData12RightAligned(). + * @note Analog reference voltage (Vref+) must be either known from + * user board environment or can be calculated using ADC measurement + * and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE(). + * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit: mV) + * @param __DAC_VOLTAGE__ Voltage to be generated by DAC channel + * (unit: mVolt). + * @param __DAC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_DAC_RESOLUTION_12B + * @arg @ref LL_DAC_RESOLUTION_8B + * @retval DAC conversion data (unit: digital value) + */ +#define __LL_DAC_CALC_VOLTAGE_TO_DATA(__VREFANALOG_VOLTAGE__, __DAC_VOLTAGE__, \ + __DAC_RESOLUTION__) \ + ((__DAC_VOLTAGE__)*__LL_DAC_DIGITAL_SCALE(__DAC_RESOLUTION__) / \ + (__VREFANALOG_VOLTAGE__)) + + /** + * @} + */ + + /** + * @} + */ + + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup DAC_LL_Exported_Functions DAC Exported Functions + * @{ + */ + /** @defgroup DAC_LL_EF_Configuration Configuration of DAC channels + * @{ + */ + + /** + * @brief Set the conversion trigger source for the selected DAC channel. + * @note For conversion trigger source to be effective, DAC trigger + * must be enabled using function @ref LL_DAC_EnableTrigger(). + * @note To set conversion trigger source, DAC channel must be disabled. + * Otherwise, the setting is discarded. + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR TSEL1 LL_DAC_SetTriggerSource\n + * CR TSEL2 LL_DAC_SetTriggerSource + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param TriggerSource This parameter can be one of the following values: + * @arg @ref LL_DAC_TRIG_SOFTWARE + * @arg @ref LL_DAC_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM4_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM6_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM7_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM15_TRGO + * @arg @ref LL_DAC_TRIG_EXT_EXTI_LINE9 + * @retval None + */ + __STATIC_INLINE void LL_DAC_SetTriggerSource(DAC_TypeDef *DACx, uint32_t DAC_Channel, + uint32_t TriggerSource) + { + MODIFY_REG(DACx->CR, DAC_CR_TSEL1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + TriggerSource << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Get the conversion trigger source for the selected DAC channel. + * @note For conversion trigger source to be effective, DAC trigger + * must be enabled using function @ref LL_DAC_EnableTrigger(). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR TSEL1 LL_DAC_GetTriggerSource\n + * CR TSEL2 LL_DAC_GetTriggerSource + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_TRIG_SOFTWARE + * @arg @ref LL_DAC_TRIG_EXT_TIM2_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM3_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM4_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM6_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM7_TRGO + * @arg @ref LL_DAC_TRIG_EXT_TIM15_TRGO + * @arg @ref LL_DAC_TRIG_EXT_EXTI_LINE9 + */ + __STATIC_INLINE uint32_t LL_DAC_GetTriggerSource(DAC_TypeDef *DACx, + uint32_t DAC_Channel) + { + return (uint32_t)(READ_BIT(DACx->CR, + DAC_CR_TSEL1 + << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) >> + (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + +#if defined(DAC_CR_WAVE1) + /** + * @brief Set the waveform automatic generation mode + * for the selected DAC channel. + * @rmtoll CR WAVE1 LL_DAC_SetWaveAutoGeneration\n + * CR WAVE2 LL_DAC_SetWaveAutoGeneration + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param WaveAutoGeneration This parameter can be one of the following values: + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NONE + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NOISE + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE + * @retval None + */ + __STATIC_INLINE void LL_DAC_SetWaveAutoGeneration(DAC_TypeDef *DACx, + uint32_t DAC_Channel, + uint32_t WaveAutoGeneration) + { + MODIFY_REG(DACx->CR, DAC_CR_WAVE1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + WaveAutoGeneration << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Get the waveform automatic generation mode + * for the selected DAC channel. + * @rmtoll CR WAVE1 LL_DAC_GetWaveAutoGeneration\n + * CR WAVE2 LL_DAC_GetWaveAutoGeneration + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NONE + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_NOISE + * @arg @ref LL_DAC_WAVE_AUTO_GENERATION_TRIANGLE + */ + __STATIC_INLINE uint32_t LL_DAC_GetWaveAutoGeneration(DAC_TypeDef *DACx, + uint32_t DAC_Channel) + { + return (uint32_t)(READ_BIT(DACx->CR, + DAC_CR_WAVE1 + << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) >> + (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Set the noise waveform generation for the selected DAC channel: + * Noise mode and parameters LFSR (linear feedback shift register). + * @note For wave generation to be effective, DAC channel + * wave generation mode must be enabled using + * function @ref LL_DAC_SetWaveAutoGeneration(). + * @note This setting can be set when the selected DAC channel is disabled + * (otherwise, the setting operation is ignored). + * @rmtoll CR MAMP1 LL_DAC_SetWaveNoiseLFSR\n + * CR MAMP2 LL_DAC_SetWaveNoiseLFSR + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param NoiseLFSRMask This parameter can be one of the following values: + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BIT0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS4_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS5_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS6_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS7_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS8_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS9_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS10_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS11_0 + * @retval None + */ + __STATIC_INLINE void LL_DAC_SetWaveNoiseLFSR(DAC_TypeDef *DACx, uint32_t DAC_Channel, + uint32_t NoiseLFSRMask) + { + MODIFY_REG(DACx->CR, DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + NoiseLFSRMask << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Set the noise waveform generation for the selected DAC channel: + * Noise mode and parameters LFSR (linear feedback shift register). + * @rmtoll CR MAMP1 LL_DAC_GetWaveNoiseLFSR\n + * CR MAMP2 LL_DAC_GetWaveNoiseLFSR + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BIT0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS1_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS2_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS3_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS4_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS5_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS6_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS7_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS8_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS9_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS10_0 + * @arg @ref LL_DAC_NOISE_LFSR_UNMASK_BITS11_0 + */ + __STATIC_INLINE uint32_t LL_DAC_GetWaveNoiseLFSR(DAC_TypeDef *DACx, + uint32_t DAC_Channel) + { + return (uint32_t)(READ_BIT(DACx->CR, + DAC_CR_MAMP1 + << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) >> + (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Set the triangle waveform generation for the selected DAC channel: + * triangle mode and amplitude. + * @note For wave generation to be effective, DAC channel + * wave generation mode must be enabled using + * function @ref LL_DAC_SetWaveAutoGeneration(). + * @note This setting can be set when the selected DAC channel is disabled + * (otherwise, the setting operation is ignored). + * @rmtoll CR MAMP1 LL_DAC_SetWaveTriangleAmplitude\n + * CR MAMP2 LL_DAC_SetWaveTriangleAmplitude + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param TriangleAmplitude This parameter can be one of the following values: + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_3 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_7 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_15 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_31 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_63 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_127 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_255 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_511 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1023 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_2047 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_4095 + * @retval None + */ + __STATIC_INLINE void LL_DAC_SetWaveTriangleAmplitude(DAC_TypeDef *DACx, + uint32_t DAC_Channel, + uint32_t TriangleAmplitude) + { + MODIFY_REG(DACx->CR, DAC_CR_MAMP1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + TriangleAmplitude << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Set the triangle waveform generation for the selected DAC channel: + * triangle mode and amplitude. + * @rmtoll CR MAMP1 LL_DAC_GetWaveTriangleAmplitude\n + * CR MAMP2 LL_DAC_GetWaveTriangleAmplitude + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_3 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_7 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_15 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_31 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_63 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_127 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_255 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_511 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_1023 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_2047 + * @arg @ref LL_DAC_TRIANGLE_AMPLITUDE_4095 + */ + __STATIC_INLINE uint32_t LL_DAC_GetWaveTriangleAmplitude(DAC_TypeDef *DACx, + uint32_t DAC_Channel) + { + return (uint32_t)(READ_BIT(DACx->CR, + DAC_CR_MAMP1 + << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) >> + (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } +#endif + + /** + * @brief Set the output buffer for the selected DAC channel. + * @rmtoll CR BOFF1 LL_DAC_SetOutputBuffer\n + * CR BOFF2 LL_DAC_SetOutputBuffer + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param OutputBuffer This parameter can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE + * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE + * @retval None + */ + __STATIC_INLINE void LL_DAC_SetOutputBuffer(DAC_TypeDef *DACx, uint32_t DAC_Channel, + uint32_t OutputBuffer) + { + MODIFY_REG(DACx->CR, DAC_CR_BOFF1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK), + OutputBuffer << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Get the output buffer state for the selected DAC channel. + * @rmtoll CR BOFF1 LL_DAC_GetOutputBuffer\n + * CR BOFF2 LL_DAC_GetOutputBuffer + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval Returned value can be one of the following values: + * @arg @ref LL_DAC_OUTPUT_BUFFER_ENABLE + * @arg @ref LL_DAC_OUTPUT_BUFFER_DISABLE + */ + __STATIC_INLINE uint32_t LL_DAC_GetOutputBuffer(DAC_TypeDef *DACx, + uint32_t DAC_Channel) + { + return (uint32_t)(READ_BIT(DACx->CR, + DAC_CR_BOFF1 + << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) >> + (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @} + */ + + /** @defgroup DAC_LL_EF_DMA_Management DMA Management + * @{ + */ + + /** + * @brief Enable DAC DMA transfer request of the selected channel. + * @note To configure DMA source address (peripheral address), + * use function @ref LL_DAC_DMA_GetRegAddr(). + * @rmtoll CR DMAEN1 LL_DAC_EnableDMAReq\n + * CR DMAEN2 LL_DAC_EnableDMAReq + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval None + */ + __STATIC_INLINE void LL_DAC_EnableDMAReq(DAC_TypeDef *DACx, uint32_t DAC_Channel) + { + SET_BIT(DACx->CR, DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Disable DAC DMA transfer request of the selected channel. + * @note To configure DMA source address (peripheral address), + * use function @ref LL_DAC_DMA_GetRegAddr(). + * @rmtoll CR DMAEN1 LL_DAC_DisableDMAReq\n + * CR DMAEN2 LL_DAC_DisableDMAReq + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval None + */ + __STATIC_INLINE void LL_DAC_DisableDMAReq(DAC_TypeDef *DACx, uint32_t DAC_Channel) + { + CLEAR_BIT(DACx->CR, DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Get DAC DMA transfer request state of the selected channel. + * (0: DAC DMA transfer request is disabled, 1: DAC DMA transfer request is + * enabled) + * @rmtoll CR DMAEN1 LL_DAC_IsDMAReqEnabled\n + * CR DMAEN2 LL_DAC_IsDMAReqEnabled + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DAC_IsDMAReqEnabled(DAC_TypeDef *DACx, + uint32_t DAC_Channel) + { + return (READ_BIT(DACx->CR, + DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) == + (DAC_CR_DMAEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))); + } + + /** + * @brief Function to help to configure DMA transfer to DAC: retrieve the + * DAC register address from DAC instance and a list of DAC registers + * intended to be used (most commonly) with DMA transfer. + * @note These DAC registers are data holding registers: + * when DAC conversion is requested, DAC generates a DMA transfer + * request to have data available in DAC data holding registers. + * @note This macro is intended to be used with LL DMA driver, refer to + * function "LL_DMA_ConfigAddresses()". + * Example: + * LL_DMA_ConfigAddresses(DMA1, + * LL_DMA_CHANNEL_1, + * (uint32_t)&< array or variable >, + * LL_DAC_DMA_GetRegAddr(DAC1, LL_DAC_CHANNEL_1, + * LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED), LL_DMA_DIRECTION_MEMORY_TO_PERIPH); + * @rmtoll DHR12R1 DACC1DHR LL_DAC_DMA_GetRegAddr\n + * DHR12L1 DACC1DHR LL_DAC_DMA_GetRegAddr\n + * DHR8R1 DACC1DHR LL_DAC_DMA_GetRegAddr\n + * DHR12R2 DACC2DHR LL_DAC_DMA_GetRegAddr\n + * DHR12L2 DACC2DHR LL_DAC_DMA_GetRegAddr\n + * DHR8R2 DACC2DHR LL_DAC_DMA_GetRegAddr + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param Register This parameter can be one of the following values: + * @arg @ref LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED + * @arg @ref LL_DAC_DMA_REG_DATA_12BITS_LEFT_ALIGNED + * @arg @ref LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED + * @retval DAC register address + */ + __STATIC_INLINE uint32_t LL_DAC_DMA_GetRegAddr(DAC_TypeDef *DACx, + uint32_t DAC_Channel, + uint32_t Register) + { + /* Retrieve address of register DHR12Rx, DHR12Lx or DHR8Rx depending on */ + /* DAC channel selected. */ + return ((uint32_t)(__DAC_PTR_REG_OFFSET( + (DACx)->DHR12R1, + ((DAC_Channel >> Register) & DAC_REG_REGOFFSET_MASK_POSBIT0)))); + } + /** + * @} + */ + + /** @defgroup DAC_LL_EF_Operation Operation on DAC channels + * @{ + */ + + /** + * @brief Enable DAC selected channel. + * @rmtoll CR EN1 LL_DAC_Enable\n + * CR EN2 LL_DAC_Enable + * @note After enable from off state, DAC channel requires a delay + * for output voltage to reach accuracy +/- 1 LSB. + * Refer to device datasheet, parameter "tWAKEUP". + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval None + */ + __STATIC_INLINE void LL_DAC_Enable(DAC_TypeDef *DACx, uint32_t DAC_Channel) + { + SET_BIT(DACx->CR, DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Disable DAC selected channel. + * @rmtoll CR EN1 LL_DAC_Disable\n + * CR EN2 LL_DAC_Disable + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval None + */ + __STATIC_INLINE void LL_DAC_Disable(DAC_TypeDef *DACx, uint32_t DAC_Channel) + { + CLEAR_BIT(DACx->CR, DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Get DAC enable state of the selected channel. + * (0: DAC channel is disabled, 1: DAC channel is enabled) + * @rmtoll CR EN1 LL_DAC_IsEnabled\n + * CR EN2 LL_DAC_IsEnabled + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DAC_IsEnabled(DAC_TypeDef *DACx, uint32_t DAC_Channel) + { + return ( + READ_BIT(DACx->CR, DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) == + (DAC_CR_EN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))); + } + + /** + * @brief Enable DAC trigger of the selected channel. + * @note - If DAC trigger is disabled, DAC conversion is performed + * automatically once the data holding register is updated, + * using functions "LL_DAC_ConvertData{8; 12}{Right; Left} Aligned()": + * @ref LL_DAC_ConvertData12RightAligned(), ... + * - If DAC trigger is enabled, DAC conversion is performed + * only when a hardware of software trigger event is occurring. + * Select trigger source using + * function @ref LL_DAC_SetTriggerSource(). + * @rmtoll CR TEN1 LL_DAC_EnableTrigger\n + * CR TEN2 LL_DAC_EnableTrigger + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval None + */ + __STATIC_INLINE void LL_DAC_EnableTrigger(DAC_TypeDef *DACx, uint32_t DAC_Channel) + { + SET_BIT(DACx->CR, DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Disable DAC trigger of the selected channel. + * @rmtoll CR TEN1 LL_DAC_DisableTrigger\n + * CR TEN2 LL_DAC_DisableTrigger + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval None + */ + __STATIC_INLINE void LL_DAC_DisableTrigger(DAC_TypeDef *DACx, uint32_t DAC_Channel) + { + CLEAR_BIT(DACx->CR, DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)); + } + + /** + * @brief Get DAC trigger state of the selected channel. + * (0: DAC trigger is disabled, 1: DAC trigger is enabled) + * @rmtoll CR TEN1 LL_DAC_IsTriggerEnabled\n + * CR TEN2 LL_DAC_IsTriggerEnabled + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DAC_IsTriggerEnabled(DAC_TypeDef *DACx, + uint32_t DAC_Channel) + { + return (READ_BIT(DACx->CR, + DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK)) == + (DAC_CR_TEN1 << (DAC_Channel & DAC_CR_CHX_BITOFFSET_MASK))); + } + + /** + * @brief Trig DAC conversion by software for the selected DAC channel. + * @note Preliminarily, DAC trigger must be set to software trigger + * using function @ref LL_DAC_SetTriggerSource() + * with parameter "LL_DAC_TRIGGER_SOFTWARE". + * and DAC trigger must be enabled using + * function @ref LL_DAC_EnableTrigger(). + * @note For devices featuring DAC with 2 channels: this function + * can perform a SW start of both DAC channels simultaneously. + * Two channels can be selected as parameter. + * Example: (LL_DAC_CHANNEL_1 | LL_DAC_CHANNEL_2) + * @rmtoll SWTRIGR SWTRIG1 LL_DAC_TrigSWConversion\n + * SWTRIGR SWTRIG2 LL_DAC_TrigSWConversion + * @param DACx DAC instance + * @param DAC_Channel This parameter can a combination of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval None + */ + __STATIC_INLINE void LL_DAC_TrigSWConversion(DAC_TypeDef *DACx, uint32_t DAC_Channel) + { + SET_BIT(DACx->SWTRIGR, (DAC_Channel & DAC_SWTR_CHX_MASK)); + } + + /** + * @brief Set the data to be loaded in the data holding register + * in format 12 bits left alignment (LSB aligned on bit 0), + * for the selected DAC channel. + * @rmtoll DHR12R1 DACC1DHR LL_DAC_ConvertData12RightAligned\n + * DHR12R2 DACC2DHR LL_DAC_ConvertData12RightAligned + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param Data Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ + __STATIC_INLINE void LL_DAC_ConvertData12RightAligned(DAC_TypeDef *DACx, + uint32_t DAC_Channel, + uint32_t Data) + { + __IO uint32_t *preg = __DAC_PTR_REG_OFFSET( + DACx->DHR12R1, (DAC_Channel >> DAC_REG_DHR12RX_REGOFFSET_BITOFFSET_POS) & + DAC_REG_REGOFFSET_MASK_POSBIT0); + + MODIFY_REG(*preg, DAC_DHR12R1_DACC1DHR, Data); + } + + /** + * @brief Set the data to be loaded in the data holding register + * in format 12 bits left alignment (MSB aligned on bit 15), + * for the selected DAC channel. + * @rmtoll DHR12L1 DACC1DHR LL_DAC_ConvertData12LeftAligned\n + * DHR12L2 DACC2DHR LL_DAC_ConvertData12LeftAligned + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param Data Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ + __STATIC_INLINE void LL_DAC_ConvertData12LeftAligned(DAC_TypeDef *DACx, + uint32_t DAC_Channel, + uint32_t Data) + { + __IO uint32_t *preg = __DAC_PTR_REG_OFFSET( + DACx->DHR12R1, (DAC_Channel >> DAC_REG_DHR12LX_REGOFFSET_BITOFFSET_POS) & + DAC_REG_REGOFFSET_MASK_POSBIT0); + + MODIFY_REG(*preg, DAC_DHR12L1_DACC1DHR, Data); + } + + /** + * @brief Set the data to be loaded in the data holding register + * in format 8 bits left alignment (LSB aligned on bit 0), + * for the selected DAC channel. + * @rmtoll DHR8R1 DACC1DHR LL_DAC_ConvertData8RightAligned\n + * DHR8R2 DACC2DHR LL_DAC_ConvertData8RightAligned + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @param Data Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ + __STATIC_INLINE void LL_DAC_ConvertData8RightAligned(DAC_TypeDef *DACx, + uint32_t DAC_Channel, + uint32_t Data) + { + __IO uint32_t *preg = __DAC_PTR_REG_OFFSET( + DACx->DHR12R1, (DAC_Channel >> DAC_REG_DHR8RX_REGOFFSET_BITOFFSET_POS) & + DAC_REG_REGOFFSET_MASK_POSBIT0); + + MODIFY_REG(*preg, DAC_DHR8R1_DACC1DHR, Data); + } + +#if defined(DAC_CHANNEL2_SUPPORT) + /** + * @brief Set the data to be loaded in the data holding register + * in format 12 bits left alignment (LSB aligned on bit 0), + * for both DAC channels. + * @rmtoll DHR12RD DACC1DHR LL_DAC_ConvertDualData12RightAligned\n + * DHR12RD DACC2DHR LL_DAC_ConvertDualData12RightAligned + * @param DACx DAC instance + * @param DataChannel1 Value between Min_Data=0x000 and Max_Data=0xFFF + * @param DataChannel2 Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ + __STATIC_INLINE void LL_DAC_ConvertDualData12RightAligned(DAC_TypeDef *DACx, + uint32_t DataChannel1, + uint32_t DataChannel2) + { + MODIFY_REG(DACx->DHR12RD, (DAC_DHR12RD_DACC2DHR | DAC_DHR12RD_DACC1DHR), + ((DataChannel2 << DAC_DHR12RD_DACC2DHR_BITOFFSET_POS) | DataChannel1)); + } + + /** + * @brief Set the data to be loaded in the data holding register + * in format 12 bits left alignment (MSB aligned on bit 15), + * for both DAC channels. + * @rmtoll DHR12LD DACC1DHR LL_DAC_ConvertDualData12LeftAligned\n + * DHR12LD DACC2DHR LL_DAC_ConvertDualData12LeftAligned + * @param DACx DAC instance + * @param DataChannel1 Value between Min_Data=0x000 and Max_Data=0xFFF + * @param DataChannel2 Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ + __STATIC_INLINE void LL_DAC_ConvertDualData12LeftAligned(DAC_TypeDef *DACx, + uint32_t DataChannel1, + uint32_t DataChannel2) + { + /* Note: Data of DAC channel 2 shift value subtracted of 4 because */ + /* data on 16 bits and DAC channel 2 bits field is on the 12 MSB, */ + /* the 4 LSB must be taken into account for the shift value. */ + MODIFY_REG( + DACx->DHR12LD, (DAC_DHR12LD_DACC2DHR | DAC_DHR12LD_DACC1DHR), + ((DataChannel2 << (DAC_DHR12LD_DACC2DHR_BITOFFSET_POS - 4U)) | DataChannel1)); + } + + /** + * @brief Set the data to be loaded in the data holding register + * in format 8 bits left alignment (LSB aligned on bit 0), + * for both DAC channels. + * @rmtoll DHR8RD DACC1DHR LL_DAC_ConvertDualData8RightAligned\n + * DHR8RD DACC2DHR LL_DAC_ConvertDualData8RightAligned + * @param DACx DAC instance + * @param DataChannel1 Value between Min_Data=0x00 and Max_Data=0xFF + * @param DataChannel2 Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ + __STATIC_INLINE void LL_DAC_ConvertDualData8RightAligned(DAC_TypeDef *DACx, + uint32_t DataChannel1, + uint32_t DataChannel2) + { + MODIFY_REG(DACx->DHR8RD, (DAC_DHR8RD_DACC2DHR | DAC_DHR8RD_DACC1DHR), + ((DataChannel2 << DAC_DHR8RD_DACC2DHR_BITOFFSET_POS) | DataChannel1)); + } + +#endif /* DAC_CHANNEL2_SUPPORT */ + /** + * @brief Retrieve output data currently generated for the selected DAC channel. + * @note Whatever alignment and resolution settings + * (using functions "LL_DAC_ConvertData{8; 12}{Right; Left} Aligned()": + * @ref LL_DAC_ConvertData12RightAligned(), ...), + * output data format is 12 bits right aligned (LSB aligned on bit 0). + * @rmtoll DOR1 DACC1DOR LL_DAC_RetrieveOutputData\n + * DOR2 DACC2DOR LL_DAC_RetrieveOutputData + * @param DACx DAC instance + * @param DAC_Channel This parameter can be one of the following values: + * @arg @ref LL_DAC_CHANNEL_1 + * @arg @ref LL_DAC_CHANNEL_2 (1) + * + * (1) On this STM32 series, parameter not available on all devices. + * Refer to device datasheet for channels availability. + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ + __STATIC_INLINE uint32_t LL_DAC_RetrieveOutputData(DAC_TypeDef *DACx, + uint32_t DAC_Channel) + { + __IO uint32_t *preg = __DAC_PTR_REG_OFFSET( + DACx->DOR1, (DAC_Channel >> DAC_REG_DORX_REGOFFSET_BITOFFSET_POS) & + DAC_REG_REGOFFSET_MASK_POSBIT0); + + return (uint16_t)READ_BIT(*preg, DAC_DOR1_DACC1DOR); + } + + /** + * @} + */ + + /** @defgroup DAC_LL_EF_FLAG_Management FLAG Management + * @{ + */ + /** + * @brief Get DAC underrun flag for DAC channel 1 + * @rmtoll SR DMAUDR1 LL_DAC_IsActiveFlag_DMAUDR1 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DMAUDR1(DAC_TypeDef *DACx) + { + return (READ_BIT(DACx->SR, LL_DAC_FLAG_DMAUDR1) == (LL_DAC_FLAG_DMAUDR1)); + } + +#if defined(DAC_CHANNEL2_SUPPORT) + /** + * @brief Get DAC underrun flag for DAC channel 2 + * @rmtoll SR DMAUDR2 LL_DAC_IsActiveFlag_DMAUDR2 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DAC_IsActiveFlag_DMAUDR2(DAC_TypeDef *DACx) + { + return (READ_BIT(DACx->SR, LL_DAC_FLAG_DMAUDR2) == (LL_DAC_FLAG_DMAUDR2)); + } +#endif /* DAC_CHANNEL2_SUPPORT */ + + /** + * @brief Clear DAC underrun flag for DAC channel 1 + * @rmtoll SR DMAUDR1 LL_DAC_ClearFlag_DMAUDR1 + * @param DACx DAC instance + * @retval None + */ + __STATIC_INLINE void LL_DAC_ClearFlag_DMAUDR1(DAC_TypeDef *DACx) + { + WRITE_REG(DACx->SR, LL_DAC_FLAG_DMAUDR1); + } + +#if defined(DAC_CHANNEL2_SUPPORT) + /** + * @brief Clear DAC underrun flag for DAC channel 2 + * @rmtoll SR DMAUDR2 LL_DAC_ClearFlag_DMAUDR2 + * @param DACx DAC instance + * @retval None + */ + __STATIC_INLINE void LL_DAC_ClearFlag_DMAUDR2(DAC_TypeDef *DACx) + { + WRITE_REG(DACx->SR, LL_DAC_FLAG_DMAUDR2); + } +#endif /* DAC_CHANNEL2_SUPPORT */ + + /** + * @} + */ + + /** @defgroup DAC_LL_EF_IT_Management IT management + * @{ + */ + + /** + * @brief Enable DMA underrun interrupt for DAC channel 1 + * @rmtoll CR DMAUDRIE1 LL_DAC_EnableIT_DMAUDR1 + * @param DACx DAC instance + * @retval None + */ + __STATIC_INLINE void LL_DAC_EnableIT_DMAUDR1(DAC_TypeDef *DACx) + { + SET_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1); + } + +#if defined(DAC_CHANNEL2_SUPPORT) + /** + * @brief Enable DMA underrun interrupt for DAC channel 2 + * @rmtoll CR DMAUDRIE2 LL_DAC_EnableIT_DMAUDR2 + * @param DACx DAC instance + * @retval None + */ + __STATIC_INLINE void LL_DAC_EnableIT_DMAUDR2(DAC_TypeDef *DACx) + { + SET_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2); + } +#endif /* DAC_CHANNEL2_SUPPORT */ + + /** + * @brief Disable DMA underrun interrupt for DAC channel 1 + * @rmtoll CR DMAUDRIE1 LL_DAC_DisableIT_DMAUDR1 + * @param DACx DAC instance + * @retval None + */ + __STATIC_INLINE void LL_DAC_DisableIT_DMAUDR1(DAC_TypeDef *DACx) + { + CLEAR_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1); + } + +#if defined(DAC_CHANNEL2_SUPPORT) + /** + * @brief Disable DMA underrun interrupt for DAC channel 2 + * @rmtoll CR DMAUDRIE2 LL_DAC_DisableIT_DMAUDR2 + * @param DACx DAC instance + * @retval None + */ + __STATIC_INLINE void LL_DAC_DisableIT_DMAUDR2(DAC_TypeDef *DACx) + { + CLEAR_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2); + } +#endif /* DAC_CHANNEL2_SUPPORT */ + + /** + * @brief Get DMA underrun interrupt for DAC channel 1 + * @rmtoll CR DMAUDRIE1 LL_DAC_IsEnabledIT_DMAUDR1 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DAC_IsEnabledIT_DMAUDR1(DAC_TypeDef *DACx) + { + return (READ_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE1) == (LL_DAC_IT_DMAUDRIE1)); + } + +#if defined(DAC_CHANNEL2_SUPPORT) + /** + * @brief Get DMA underrun interrupt for DAC channel 2 + * @rmtoll CR DMAUDRIE2 LL_DAC_IsEnabledIT_DMAUDR2 + * @param DACx DAC instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DAC_IsEnabledIT_DMAUDR2(DAC_TypeDef *DACx) + { + return (READ_BIT(DACx->CR, LL_DAC_IT_DMAUDRIE2) == (LL_DAC_IT_DMAUDRIE2)); + } +#endif /* DAC_CHANNEL2_SUPPORT */ + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup DAC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + ErrorStatus LL_DAC_DeInit(DAC_TypeDef *DACx); + ErrorStatus LL_DAC_Init(DAC_TypeDef *DACx, uint32_t DAC_Channel, + LL_DAC_InitTypeDef *DAC_InitStruct); + void LL_DAC_StructInit(LL_DAC_InitTypeDef *DAC_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* DAC1 */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_DAC_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_dma.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_dma.h new file mode 100644 index 0000000000..3b5ad38c69 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_dma.h @@ -0,0 +1,2527 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_dma.h + * @author MCD Application Team + * @brief Header file of DMA LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_DMA_H +#define __STM32F0xx_LL_DMA_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(DMA1) || defined(DMA2) + + /** @defgroup DMA_LL DMA + * @{ + */ + + /* Private types -------------------------------------------------------------*/ + /* Private variables ---------------------------------------------------------*/ + /** @defgroup DMA_LL_Private_Variables DMA Private Variables + * @{ + */ + /* Array used to get the DMA channel register offset versus channel index + * LL_DMA_CHANNEL_x */ + static const uint8_t CHANNEL_OFFSET_TAB[] = { + (uint8_t)(DMA1_Channel1_BASE - DMA1_BASE), + (uint8_t)(DMA1_Channel2_BASE - DMA1_BASE), + (uint8_t)(DMA1_Channel3_BASE - DMA1_BASE), + (uint8_t)(DMA1_Channel4_BASE - DMA1_BASE), + (uint8_t)(DMA1_Channel5_BASE - DMA1_BASE), +#if defined(DMA1_Channel6) + (uint8_t)(DMA1_Channel6_BASE - DMA1_BASE), +#endif /*DMA1_Channel6*/ +#if defined(DMA1_Channel7) + (uint8_t)(DMA1_Channel7_BASE - DMA1_BASE) +#endif /*DMA1_Channel7*/ + }; +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup DMA_LL_Private_Constants DMA Private Constants + * @{ + */ +/* Define used to get CSELR register offset */ +#define DMA_CSELR_OFFSET (uint32_t)(DMA1_CSELR_BASE - DMA1_BASE) + +/* Defines used for the bit position in the register and perform offsets */ +#define DMA_POSITION_CSELR_CXS ((Channel - 1U) * 4U) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup DMA_LL_Private_Macros DMA Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup DMA_LL_ES_INIT DMA Exported Init structure + * @{ + */ + typedef struct + { + uint32_t PeriphOrM2MSrcAddress; /*!< Specifies the peripheral base address for DMA + transfer or as Source base address in case of + memory to memory transfer direction. + + This parameter must be a value between + Min_Data = 0 and Max_Data = 0xFFFFFFFF. */ + + uint32_t MemoryOrM2MDstAddress; /*!< Specifies the memory base address for DMA + transfer or as Destination base address in case + of memory to memory transfer direction. + + This parameter must be a value between + Min_Data = 0 and Max_Data = 0xFFFFFFFF. */ + + uint32_t + Direction; /*!< Specifies if the data will be transferred from memory to + peripheral, from memory to memory or from peripheral to memory. + This parameter can be a value of @ref DMA_LL_EC_DIRECTION + + This feature can be modified afterwards using unitary function + @ref LL_DMA_SetDataTransferDirection(). */ + + uint32_t + Mode; /*!< Specifies the normal or circular operation mode. + This parameter can be a value of @ref DMA_LL_EC_MODE + @note: The circular buffer mode cannot be used if the memory to + memory data transfer direction is configured on the selected Channel + + This feature can be modified afterwards using unitary function @ref + LL_DMA_SetMode(). */ + + uint32_t + PeriphOrM2MSrcIncMode; /*!< Specifies whether the Peripheral address or Source + address in case of memory to memory transfer + direction is incremented or not. This parameter can + be a value of @ref DMA_LL_EC_PERIPH + + This feature can be modified afterwards using + unitary function @ref LL_DMA_SetPeriphIncMode(). */ + + uint32_t + MemoryOrM2MDstIncMode; /*!< Specifies whether the Memory address or + Destination address in case of memory to memory + transfer direction is incremented or not. This + parameter can be a value of @ref DMA_LL_EC_MEMORY + + This feature can be modified afterwards using + unitary function @ref LL_DMA_SetMemoryIncMode(). */ + + uint32_t + PeriphOrM2MSrcDataSize; /*!< Specifies the Peripheral data size alignment or + Source data size alignment (byte, half word, word) + in case of memory to memory transfer direction. + This parameter can be a value of @ref + DMA_LL_EC_PDATAALIGN + + This feature can be modified afterwards using + unitary function @ref LL_DMA_SetPeriphSize(). */ + + uint32_t + MemoryOrM2MDstDataSize; /*!< Specifies the Memory data size alignment or + Destination data size alignment (byte, half word, + word) in case of memory to memory transfer + direction. This parameter can be a value of @ref + DMA_LL_EC_MDATAALIGN + + This feature can be modified afterwards using + unitary function @ref LL_DMA_SetMemorySize(). */ + + uint32_t NbData; /*!< Specifies the number of data to transfer, in data unit. + The data unit is equal to the source buffer configuration + set in PeripheralSize or MemorySize parameters depending in + the transfer direction. This parameter must be a value between + Min_Data = 0 and Max_Data = 0x0000FFFF + + This feature can be modified afterwards using unitary + function @ref LL_DMA_SetDataLength(). */ +#if (defined(DMA1_CSELR_DEFAULT) || defined(DMA2_CSELR_DEFAULT)) + + uint32_t + PeriphRequest; /*!< Specifies the peripheral request. + This parameter can be a value of @ref DMA_LL_EC_REQUEST + + This feature can be modified afterwards using unitary + function @ref LL_DMA_SetPeriphRequest(). */ +#endif + + uint32_t Priority; /*!< Specifies the channel priority level. + This parameter can be a value of @ref DMA_LL_EC_PRIORITY + + This feature can be modified afterwards using unitary + function @ref LL_DMA_SetChannelPriorityLevel(). */ + + } LL_DMA_InitTypeDef; +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DMA_LL_Exported_Constants DMA Exported Constants + * @{ + */ +/** @defgroup DMA_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_DMA_WriteReg function + * @{ + */ +#define LL_DMA_IFCR_CGIF1 DMA_IFCR_CGIF1 /*!< Channel 1 global flag */ +#define LL_DMA_IFCR_CTCIF1 DMA_IFCR_CTCIF1 /*!< Channel 1 transfer complete flag */ +#define LL_DMA_IFCR_CHTIF1 DMA_IFCR_CHTIF1 /*!< Channel 1 half transfer flag */ +#define LL_DMA_IFCR_CTEIF1 DMA_IFCR_CTEIF1 /*!< Channel 1 transfer error flag */ +#define LL_DMA_IFCR_CGIF2 DMA_IFCR_CGIF2 /*!< Channel 2 global flag */ +#define LL_DMA_IFCR_CTCIF2 DMA_IFCR_CTCIF2 /*!< Channel 2 transfer complete flag */ +#define LL_DMA_IFCR_CHTIF2 DMA_IFCR_CHTIF2 /*!< Channel 2 half transfer flag */ +#define LL_DMA_IFCR_CTEIF2 DMA_IFCR_CTEIF2 /*!< Channel 2 transfer error flag */ +#define LL_DMA_IFCR_CGIF3 DMA_IFCR_CGIF3 /*!< Channel 3 global flag */ +#define LL_DMA_IFCR_CTCIF3 DMA_IFCR_CTCIF3 /*!< Channel 3 transfer complete flag */ +#define LL_DMA_IFCR_CHTIF3 DMA_IFCR_CHTIF3 /*!< Channel 3 half transfer flag */ +#define LL_DMA_IFCR_CTEIF3 DMA_IFCR_CTEIF3 /*!< Channel 3 transfer error flag */ +#define LL_DMA_IFCR_CGIF4 DMA_IFCR_CGIF4 /*!< Channel 4 global flag */ +#define LL_DMA_IFCR_CTCIF4 DMA_IFCR_CTCIF4 /*!< Channel 4 transfer complete flag */ +#define LL_DMA_IFCR_CHTIF4 DMA_IFCR_CHTIF4 /*!< Channel 4 half transfer flag */ +#define LL_DMA_IFCR_CTEIF4 DMA_IFCR_CTEIF4 /*!< Channel 4 transfer error flag */ +#define LL_DMA_IFCR_CGIF5 DMA_IFCR_CGIF5 /*!< Channel 5 global flag */ +#define LL_DMA_IFCR_CTCIF5 DMA_IFCR_CTCIF5 /*!< Channel 5 transfer complete flag */ +#define LL_DMA_IFCR_CHTIF5 DMA_IFCR_CHTIF5 /*!< Channel 5 half transfer flag */ +#define LL_DMA_IFCR_CTEIF5 DMA_IFCR_CTEIF5 /*!< Channel 5 transfer error flag */ +#if defined(DMA1_Channel6) +#define LL_DMA_IFCR_CGIF6 DMA_IFCR_CGIF6 /*!< Channel 6 global flag */ +#define LL_DMA_IFCR_CTCIF6 DMA_IFCR_CTCIF6 /*!< Channel 6 transfer complete flag */ +#define LL_DMA_IFCR_CHTIF6 DMA_IFCR_CHTIF6 /*!< Channel 6 half transfer flag */ +#define LL_DMA_IFCR_CTEIF6 DMA_IFCR_CTEIF6 /*!< Channel 6 transfer error flag */ +#endif +#if defined(DMA1_Channel7) +#define LL_DMA_IFCR_CGIF7 DMA_IFCR_CGIF7 /*!< Channel 7 global flag */ +#define LL_DMA_IFCR_CTCIF7 DMA_IFCR_CTCIF7 /*!< Channel 7 transfer complete flag */ +#define LL_DMA_IFCR_CHTIF7 DMA_IFCR_CHTIF7 /*!< Channel 7 half transfer flag */ +#define LL_DMA_IFCR_CTEIF7 DMA_IFCR_CTEIF7 /*!< Channel 7 transfer error flag */ +#endif +/** + * @} + */ + +/** @defgroup DMA_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_DMA_ReadReg function + * @{ + */ +#define LL_DMA_ISR_GIF1 DMA_ISR_GIF1 /*!< Channel 1 global flag */ +#define LL_DMA_ISR_TCIF1 DMA_ISR_TCIF1 /*!< Channel 1 transfer complete flag */ +#define LL_DMA_ISR_HTIF1 DMA_ISR_HTIF1 /*!< Channel 1 half transfer flag */ +#define LL_DMA_ISR_TEIF1 DMA_ISR_TEIF1 /*!< Channel 1 transfer error flag */ +#define LL_DMA_ISR_GIF2 DMA_ISR_GIF2 /*!< Channel 2 global flag */ +#define LL_DMA_ISR_TCIF2 DMA_ISR_TCIF2 /*!< Channel 2 transfer complete flag */ +#define LL_DMA_ISR_HTIF2 DMA_ISR_HTIF2 /*!< Channel 2 half transfer flag */ +#define LL_DMA_ISR_TEIF2 DMA_ISR_TEIF2 /*!< Channel 2 transfer error flag */ +#define LL_DMA_ISR_GIF3 DMA_ISR_GIF3 /*!< Channel 3 global flag */ +#define LL_DMA_ISR_TCIF3 DMA_ISR_TCIF3 /*!< Channel 3 transfer complete flag */ +#define LL_DMA_ISR_HTIF3 DMA_ISR_HTIF3 /*!< Channel 3 half transfer flag */ +#define LL_DMA_ISR_TEIF3 DMA_ISR_TEIF3 /*!< Channel 3 transfer error flag */ +#define LL_DMA_ISR_GIF4 DMA_ISR_GIF4 /*!< Channel 4 global flag */ +#define LL_DMA_ISR_TCIF4 DMA_ISR_TCIF4 /*!< Channel 4 transfer complete flag */ +#define LL_DMA_ISR_HTIF4 DMA_ISR_HTIF4 /*!< Channel 4 half transfer flag */ +#define LL_DMA_ISR_TEIF4 DMA_ISR_TEIF4 /*!< Channel 4 transfer error flag */ +#define LL_DMA_ISR_GIF5 DMA_ISR_GIF5 /*!< Channel 5 global flag */ +#define LL_DMA_ISR_TCIF5 DMA_ISR_TCIF5 /*!< Channel 5 transfer complete flag */ +#define LL_DMA_ISR_HTIF5 DMA_ISR_HTIF5 /*!< Channel 5 half transfer flag */ +#define LL_DMA_ISR_TEIF5 DMA_ISR_TEIF5 /*!< Channel 5 transfer error flag */ +#if defined(DMA1_Channel6) +#define LL_DMA_ISR_GIF6 DMA_ISR_GIF6 /*!< Channel 6 global flag */ +#define LL_DMA_ISR_TCIF6 DMA_ISR_TCIF6 /*!< Channel 6 transfer complete flag */ +#define LL_DMA_ISR_HTIF6 DMA_ISR_HTIF6 /*!< Channel 6 half transfer flag */ +#define LL_DMA_ISR_TEIF6 DMA_ISR_TEIF6 /*!< Channel 6 transfer error flag */ +#endif +#if defined(DMA1_Channel7) +#define LL_DMA_ISR_GIF7 DMA_ISR_GIF7 /*!< Channel 7 global flag */ +#define LL_DMA_ISR_TCIF7 DMA_ISR_TCIF7 /*!< Channel 7 transfer complete flag */ +#define LL_DMA_ISR_HTIF7 DMA_ISR_HTIF7 /*!< Channel 7 half transfer flag */ +#define LL_DMA_ISR_TEIF7 DMA_ISR_TEIF7 /*!< Channel 7 transfer error flag */ +#endif +/** + * @} + */ + +/** @defgroup DMA_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_DMA_ReadReg and LL_DMA_WriteReg + * functions + * @{ + */ +#define LL_DMA_CCR_TCIE DMA_CCR_TCIE /*!< Transfer complete interrupt */ +#define LL_DMA_CCR_HTIE DMA_CCR_HTIE /*!< Half Transfer interrupt */ +#define LL_DMA_CCR_TEIE DMA_CCR_TEIE /*!< Transfer error interrupt */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_CHANNEL CHANNEL + * @{ + */ +#define LL_DMA_CHANNEL_1 0x00000001U /*!< DMA Channel 1 */ +#define LL_DMA_CHANNEL_2 0x00000002U /*!< DMA Channel 2 */ +#define LL_DMA_CHANNEL_3 0x00000003U /*!< DMA Channel 3 */ +#define LL_DMA_CHANNEL_4 0x00000004U /*!< DMA Channel 4 */ +#define LL_DMA_CHANNEL_5 0x00000005U /*!< DMA Channel 5 */ +#if defined(DMA1_Channel6) +#define LL_DMA_CHANNEL_6 0x00000006U /*!< DMA Channel 6 */ +#endif +#if defined(DMA1_Channel7) +#define LL_DMA_CHANNEL_7 0x00000007U /*!< DMA Channel 7 */ +#endif +#if defined(USE_FULL_LL_DRIVER) +#define LL_DMA_CHANNEL_ALL \ + 0xFFFF0000U /*!< DMA Channel all (used only for function @ref LL_DMA_DeInit(). */ +#endif /*USE_FULL_LL_DRIVER*/ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_DIRECTION Transfer Direction + * @{ + */ +#define LL_DMA_DIRECTION_PERIPH_TO_MEMORY \ + 0x00000000U /*!< Peripheral to memory direction */ +#define LL_DMA_DIRECTION_MEMORY_TO_PERIPH \ + DMA_CCR_DIR /*!< Memory to peripheral direction */ +#define LL_DMA_DIRECTION_MEMORY_TO_MEMORY \ + DMA_CCR_MEM2MEM /*!< Memory to memory direction */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_MODE Transfer mode + * @{ + */ +#define LL_DMA_MODE_NORMAL 0x00000000U /*!< Normal Mode */ +#define LL_DMA_MODE_CIRCULAR DMA_CCR_CIRC /*!< Circular Mode */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_PERIPH Peripheral increment mode + * @{ + */ +#define LL_DMA_PERIPH_INCREMENT DMA_CCR_PINC /*!< Peripheral increment mode Enable */ +#define LL_DMA_PERIPH_NOINCREMENT 0x00000000U /*!< Peripheral increment mode Disable */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_MEMORY Memory increment mode + * @{ + */ +#define LL_DMA_MEMORY_INCREMENT DMA_CCR_MINC /*!< Memory increment mode Enable */ +#define LL_DMA_MEMORY_NOINCREMENT 0x00000000U /*!< Memory increment mode Disable */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_PDATAALIGN Peripheral data alignment + * @{ + */ +#define LL_DMA_PDATAALIGN_BYTE 0x00000000U /*!< Peripheral data alignment : Byte */ +#define LL_DMA_PDATAALIGN_HALFWORD \ + DMA_CCR_PSIZE_0 /*!< Peripheral data alignment : HalfWord */ +#define LL_DMA_PDATAALIGN_WORD \ + DMA_CCR_PSIZE_1 /*!< Peripheral data alignment : Word */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_MDATAALIGN Memory data alignment + * @{ + */ +#define LL_DMA_MDATAALIGN_BYTE 0x00000000U /*!< Memory data alignment : Byte */ +#define LL_DMA_MDATAALIGN_HALFWORD \ + DMA_CCR_MSIZE_0 /*!< Memory data alignment : HalfWord */ +#define LL_DMA_MDATAALIGN_WORD DMA_CCR_MSIZE_1 /*!< Memory data alignment : Word */ +/** + * @} + */ + +/** @defgroup DMA_LL_EC_PRIORITY Transfer Priority level + * @{ + */ +#define LL_DMA_PRIORITY_LOW 0x00000000U /*!< Priority level : Low */ +#define LL_DMA_PRIORITY_MEDIUM DMA_CCR_PL_0 /*!< Priority level : Medium */ +#define LL_DMA_PRIORITY_HIGH DMA_CCR_PL_1 /*!< Priority level : High */ +#define LL_DMA_PRIORITY_VERYHIGH DMA_CCR_PL /*!< Priority level : Very_High */ + /** + * @} + */ + +#if (defined(DMA1_CSELR_DEFAULT) || defined(DMA2_CSELR_DEFAULT)) +/** @defgroup DMA_LL_EC_REQUEST Transfer peripheral request + * @{ + */ +#define LL_DMA_REQUEST_0 0x00000000U /*!< DMA peripheral request 0 */ +#define LL_DMA_REQUEST_1 0x00000001U /*!< DMA peripheral request 1 */ +#define LL_DMA_REQUEST_2 0x00000002U /*!< DMA peripheral request 2 */ +#define LL_DMA_REQUEST_3 0x00000003U /*!< DMA peripheral request 3 */ +#define LL_DMA_REQUEST_4 0x00000004U /*!< DMA peripheral request 4 */ +#define LL_DMA_REQUEST_5 0x00000005U /*!< DMA peripheral request 5 */ +#define LL_DMA_REQUEST_6 0x00000006U /*!< DMA peripheral request 6 */ +#define LL_DMA_REQUEST_7 0x00000007U /*!< DMA peripheral request 7 */ +#define LL_DMA_REQUEST_8 0x00000008U /*!< DMA peripheral request 8 */ +#define LL_DMA_REQUEST_9 0x00000009U /*!< DMA peripheral request 9 */ +#define LL_DMA_REQUEST_10 0x0000000AU /*!< DMA peripheral request 10 */ +#define LL_DMA_REQUEST_11 0x0000000BU /*!< DMA peripheral request 11 */ +#define LL_DMA_REQUEST_12 0x0000000CU /*!< DMA peripheral request 12 */ +#define LL_DMA_REQUEST_13 0x0000000DU /*!< DMA peripheral request 13 */ +#define LL_DMA_REQUEST_14 0x0000000EU /*!< DMA peripheral request 14 */ +#define LL_DMA_REQUEST_15 0x0000000FU /*!< DMA peripheral request 15 */ +/** + * @} + */ +#endif + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DMA_LL_Exported_Macros DMA Exported Macros + * @{ + */ + +/** @defgroup DMA_LL_EM_WRITE_READ Common Write and read registers macros + * @{ + */ +/** + * @brief Write a value in DMA register + * @param __INSTANCE__ DMA Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_DMA_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in DMA register + * @param __INSTANCE__ DMA Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_DMA_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup DMA_LL_EM_CONVERT_DMAxCHANNELy Convert DMAxChannely + * @{ + */ +/** + * @brief Convert DMAx_Channely into DMAx + * @param __CHANNEL_INSTANCE__ DMAx_Channely + * @retval DMAx + */ +#if defined(DMA2) +#define __LL_DMA_GET_INSTANCE(__CHANNEL_INSTANCE__) \ + (((uint32_t)(__CHANNEL_INSTANCE__) > ((uint32_t)DMA1_Channel7)) ? DMA2 : DMA1) +#else +#define __LL_DMA_GET_INSTANCE(__CHANNEL_INSTANCE__) (DMA1) +#endif + +/** + * @brief Convert DMAx_Channely into LL_DMA_CHANNEL_y + * @param __CHANNEL_INSTANCE__ DMAx_Channely + * @retval LL_DMA_CHANNEL_y + */ +#if defined(DMA2) +#if defined(DMA2_Channel6) && defined(DMA2_Channel7) +#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \ + (((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel1)) \ + ? LL_DMA_CHANNEL_1 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) \ + ? LL_DMA_CHANNEL_2 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel2)) \ + ? LL_DMA_CHANNEL_2 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) \ + ? LL_DMA_CHANNEL_3 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel3)) \ + ? LL_DMA_CHANNEL_3 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) \ + ? LL_DMA_CHANNEL_4 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel4)) \ + ? LL_DMA_CHANNEL_4 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel5)) \ + ? LL_DMA_CHANNEL_5 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel5)) \ + ? LL_DMA_CHANNEL_5 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel6)) \ + ? LL_DMA_CHANNEL_6 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel6)) \ + ? LL_DMA_CHANNEL_6 \ + : LL_DMA_CHANNEL_7) +#else +#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \ + (((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel1)) \ + ? LL_DMA_CHANNEL_1 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) \ + ? LL_DMA_CHANNEL_2 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel2)) \ + ? LL_DMA_CHANNEL_2 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) \ + ? LL_DMA_CHANNEL_3 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel3)) \ + ? LL_DMA_CHANNEL_3 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) \ + ? LL_DMA_CHANNEL_4 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel4)) \ + ? LL_DMA_CHANNEL_4 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel5)) \ + ? LL_DMA_CHANNEL_5 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA2_Channel5)) \ + ? LL_DMA_CHANNEL_5 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel6)) \ + ? LL_DMA_CHANNEL_6 \ + : LL_DMA_CHANNEL_7) +#endif +#else +#if defined(DMA1_Channel6) && defined(DMA1_Channel7) +#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \ + (((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) \ + ? LL_DMA_CHANNEL_2 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) \ + ? LL_DMA_CHANNEL_3 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) \ + ? LL_DMA_CHANNEL_4 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel5)) \ + ? LL_DMA_CHANNEL_5 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel6)) \ + ? LL_DMA_CHANNEL_6 \ + : LL_DMA_CHANNEL_7) +#elif defined(DMA1_Channel6) +#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \ + (((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) \ + ? LL_DMA_CHANNEL_2 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) \ + ? LL_DMA_CHANNEL_3 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) \ + ? LL_DMA_CHANNEL_4 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel5)) \ + ? LL_DMA_CHANNEL_5 \ + : LL_DMA_CHANNEL_6) +#else +#define __LL_DMA_GET_CHANNEL(__CHANNEL_INSTANCE__) \ + (((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel1)) ? LL_DMA_CHANNEL_1 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel2)) \ + ? LL_DMA_CHANNEL_2 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel3)) \ + ? LL_DMA_CHANNEL_3 \ + : ((uint32_t)(__CHANNEL_INSTANCE__) == ((uint32_t)DMA1_Channel4)) \ + ? LL_DMA_CHANNEL_4 \ + : LL_DMA_CHANNEL_5) +#endif /* DMA1_Channel6 && DMA1_Channel7 */ +#endif + +/** + * @brief Convert DMA Instance DMAx and LL_DMA_CHANNEL_y into DMAx_Channely + * @param __DMA_INSTANCE__ DMAx + * @param __CHANNEL__ LL_DMA_CHANNEL_y + * @retval DMAx_Channely + */ +#if defined(DMA2) +#if defined(DMA2_Channel6) && defined(DMA2_Channel7) +#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \ + ((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? DMA1_Channel1 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? DMA2_Channel1 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? DMA1_Channel2 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? DMA2_Channel2 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? DMA1_Channel3 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? DMA2_Channel3 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? DMA1_Channel4 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? DMA2_Channel4 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? DMA1_Channel5 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? DMA2_Channel5 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) \ + ? DMA1_Channel6 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) \ + ? DMA2_Channel6 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_7))) \ + ? DMA1_Channel7 \ + : DMA2_Channel7) +#else +#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \ + ((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? DMA1_Channel1 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? DMA2_Channel1 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? DMA1_Channel2 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? DMA2_Channel2 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? DMA1_Channel3 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? DMA2_Channel3 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? DMA1_Channel4 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? DMA2_Channel4 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? DMA1_Channel5 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA2)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? DMA2_Channel5 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) \ + ? DMA1_Channel6 \ + : DMA1_Channel7) +#endif +#else +#if defined(DMA1_Channel6) && defined(DMA1_Channel7) +#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \ + ((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? DMA1_Channel1 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? DMA1_Channel2 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? DMA1_Channel3 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? DMA1_Channel4 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? DMA1_Channel5 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_6))) \ + ? DMA1_Channel6 \ + : DMA1_Channel7) +#elif defined(DMA1_Channel6) +#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \ + ((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? DMA1_Channel1 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? DMA1_Channel2 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? DMA1_Channel3 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? DMA1_Channel4 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_5))) \ + ? DMA1_Channel5 \ + : DMA1_Channel6) +#else +#define __LL_DMA_GET_CHANNEL_INSTANCE(__DMA_INSTANCE__, __CHANNEL__) \ + ((((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_1))) \ + ? DMA1_Channel1 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_2))) \ + ? DMA1_Channel2 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_3))) \ + ? DMA1_Channel3 \ + : (((uint32_t)(__DMA_INSTANCE__) == ((uint32_t)DMA1)) && \ + ((uint32_t)(__CHANNEL__) == ((uint32_t)LL_DMA_CHANNEL_4))) \ + ? DMA1_Channel4 \ + : DMA1_Channel5) +#endif /* DMA1_Channel6 && DMA1_Channel7 */ +#endif + + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup DMA_LL_Exported_Functions DMA Exported Functions + * @{ + */ + + /** @defgroup DMA_LL_EF_Configuration Configuration + * @{ + */ + /** + * @brief Enable DMA channel. + * @rmtoll CCR EN LL_DMA_EnableChannel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ + __STATIC_INLINE void LL_DMA_EnableChannel(DMA_TypeDef *DMAx, uint32_t Channel) + { + SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_EN); + } + + /** + * @brief Disable DMA channel. + * @rmtoll CCR EN LL_DMA_DisableChannel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ + __STATIC_INLINE void LL_DMA_DisableChannel(DMA_TypeDef *DMAx, uint32_t Channel) + { + CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_EN); + } + + /** + * @brief Check if DMA channel is enabled or disabled. + * @rmtoll CCR EN LL_DMA_IsEnabledChannel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsEnabledChannel(DMA_TypeDef *DMAx, uint32_t Channel) + { + return ( + READ_BIT(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_EN) == (DMA_CCR_EN)); + } + + /** + * @brief Configure all parameters link to DMA transfer. + * @rmtoll CCR DIR LL_DMA_ConfigTransfer\n + * CCR MEM2MEM LL_DMA_ConfigTransfer\n + * CCR CIRC LL_DMA_ConfigTransfer\n + * CCR PINC LL_DMA_ConfigTransfer\n + * CCR MINC LL_DMA_ConfigTransfer\n + * CCR PSIZE LL_DMA_ConfigTransfer\n + * CCR MSIZE LL_DMA_ConfigTransfer\n + * CCR PL LL_DMA_ConfigTransfer + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Configuration This parameter must be a combination of all the following + * values: + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY or @ref + * LL_DMA_DIRECTION_MEMORY_TO_PERIPH or @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + * @arg @ref LL_DMA_MODE_NORMAL or @ref LL_DMA_MODE_CIRCULAR + * @arg @ref LL_DMA_PERIPH_INCREMENT or @ref LL_DMA_PERIPH_NOINCREMENT + * @arg @ref LL_DMA_MEMORY_INCREMENT or @ref LL_DMA_MEMORY_NOINCREMENT + * @arg @ref LL_DMA_PDATAALIGN_BYTE or @ref LL_DMA_PDATAALIGN_HALFWORD or @ref + * LL_DMA_PDATAALIGN_WORD + * @arg @ref LL_DMA_MDATAALIGN_BYTE or @ref LL_DMA_MDATAALIGN_HALFWORD or @ref + * LL_DMA_MDATAALIGN_WORD + * @arg @ref LL_DMA_PRIORITY_LOW or @ref LL_DMA_PRIORITY_MEDIUM or @ref + * LL_DMA_PRIORITY_HIGH or @ref LL_DMA_PRIORITY_VERYHIGH + * @retval None + */ + __STATIC_INLINE void LL_DMA_ConfigTransfer(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t Configuration) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_DIR | DMA_CCR_MEM2MEM | DMA_CCR_CIRC | DMA_CCR_PINC | + DMA_CCR_MINC | DMA_CCR_PSIZE | DMA_CCR_MSIZE | DMA_CCR_PL, + Configuration); + } + + /** + * @brief Set Data transfer direction (read from peripheral or from memory). + * @rmtoll CCR DIR LL_DMA_SetDataTransferDirection\n + * CCR MEM2MEM LL_DMA_SetDataTransferDirection + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetDataTransferDirection(DMA_TypeDef *DMAx, + uint32_t Channel, + uint32_t Direction) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_DIR | DMA_CCR_MEM2MEM, Direction); + } + + /** + * @brief Get Data transfer direction (read from peripheral or from memory). + * @rmtoll CCR DIR LL_DMA_GetDataTransferDirection\n + * CCR MEM2MEM LL_DMA_GetDataTransferDirection + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + */ + __STATIC_INLINE uint32_t LL_DMA_GetDataTransferDirection(DMA_TypeDef *DMAx, + uint32_t Channel) + { + return (READ_BIT( + ((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_DIR | DMA_CCR_MEM2MEM)); + } + + /** + * @brief Set DMA mode circular or normal. + * @note The circular buffer mode cannot be used if the memory-to-memory + * data transfer is configured on the selected Channel. + * @rmtoll CCR CIRC LL_DMA_SetMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_DMA_MODE_NORMAL + * @arg @ref LL_DMA_MODE_CIRCULAR + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetMode(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t Mode) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_CIRC, Mode); + } + + /** + * @brief Get DMA mode circular or normal. + * @rmtoll CCR CIRC LL_DMA_GetMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_MODE_NORMAL + * @arg @ref LL_DMA_MODE_CIRCULAR + */ + __STATIC_INLINE uint32_t LL_DMA_GetMode(DMA_TypeDef *DMAx, uint32_t Channel) + { + return (READ_BIT( + ((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_CIRC)); + } + + /** + * @brief Set Peripheral increment mode. + * @rmtoll CCR PINC LL_DMA_SetPeriphIncMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param PeriphOrM2MSrcIncMode This parameter can be one of the following values: + * @arg @ref LL_DMA_PERIPH_INCREMENT + * @arg @ref LL_DMA_PERIPH_NOINCREMENT + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetPeriphIncMode(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t PeriphOrM2MSrcIncMode) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_PINC, PeriphOrM2MSrcIncMode); + } + + /** + * @brief Get Peripheral increment mode. + * @rmtoll CCR PINC LL_DMA_GetPeriphIncMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_PERIPH_INCREMENT + * @arg @ref LL_DMA_PERIPH_NOINCREMENT + */ + __STATIC_INLINE uint32_t LL_DMA_GetPeriphIncMode(DMA_TypeDef *DMAx, uint32_t Channel) + { + return (READ_BIT( + ((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_PINC)); + } + + /** + * @brief Set Memory increment mode. + * @rmtoll CCR MINC LL_DMA_SetMemoryIncMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param MemoryOrM2MDstIncMode This parameter can be one of the following values: + * @arg @ref LL_DMA_MEMORY_INCREMENT + * @arg @ref LL_DMA_MEMORY_NOINCREMENT + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetMemoryIncMode(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t MemoryOrM2MDstIncMode) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_MINC, MemoryOrM2MDstIncMode); + } + + /** + * @brief Get Memory increment mode. + * @rmtoll CCR MINC LL_DMA_GetMemoryIncMode + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_MEMORY_INCREMENT + * @arg @ref LL_DMA_MEMORY_NOINCREMENT + */ + __STATIC_INLINE uint32_t LL_DMA_GetMemoryIncMode(DMA_TypeDef *DMAx, uint32_t Channel) + { + return (READ_BIT( + ((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_MINC)); + } + + /** + * @brief Set Peripheral size. + * @rmtoll CCR PSIZE LL_DMA_SetPeriphSize + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param PeriphOrM2MSrcDataSize This parameter can be one of the following values: + * @arg @ref LL_DMA_PDATAALIGN_BYTE + * @arg @ref LL_DMA_PDATAALIGN_HALFWORD + * @arg @ref LL_DMA_PDATAALIGN_WORD + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetPeriphSize(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t PeriphOrM2MSrcDataSize) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_PSIZE, PeriphOrM2MSrcDataSize); + } + + /** + * @brief Get Peripheral size. + * @rmtoll CCR PSIZE LL_DMA_GetPeriphSize + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_PDATAALIGN_BYTE + * @arg @ref LL_DMA_PDATAALIGN_HALFWORD + * @arg @ref LL_DMA_PDATAALIGN_WORD + */ + __STATIC_INLINE uint32_t LL_DMA_GetPeriphSize(DMA_TypeDef *DMAx, uint32_t Channel) + { + return (READ_BIT( + ((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_PSIZE)); + } + + /** + * @brief Set Memory size. + * @rmtoll CCR MSIZE LL_DMA_SetMemorySize + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param MemoryOrM2MDstDataSize This parameter can be one of the following values: + * @arg @ref LL_DMA_MDATAALIGN_BYTE + * @arg @ref LL_DMA_MDATAALIGN_HALFWORD + * @arg @ref LL_DMA_MDATAALIGN_WORD + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetMemorySize(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t MemoryOrM2MDstDataSize) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_MSIZE, MemoryOrM2MDstDataSize); + } + + /** + * @brief Get Memory size. + * @rmtoll CCR MSIZE LL_DMA_GetMemorySize + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_MDATAALIGN_BYTE + * @arg @ref LL_DMA_MDATAALIGN_HALFWORD + * @arg @ref LL_DMA_MDATAALIGN_WORD + */ + __STATIC_INLINE uint32_t LL_DMA_GetMemorySize(DMA_TypeDef *DMAx, uint32_t Channel) + { + return (READ_BIT( + ((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_MSIZE)); + } + + /** + * @brief Set Channel priority level. + * @rmtoll CCR PL LL_DMA_SetChannelPriorityLevel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param Priority This parameter can be one of the following values: + * @arg @ref LL_DMA_PRIORITY_LOW + * @arg @ref LL_DMA_PRIORITY_MEDIUM + * @arg @ref LL_DMA_PRIORITY_HIGH + * @arg @ref LL_DMA_PRIORITY_VERYHIGH + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetChannelPriorityLevel(DMA_TypeDef *DMAx, + uint32_t Channel, + uint32_t Priority) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_PL, Priority); + } + + /** + * @brief Get Channel priority level. + * @rmtoll CCR PL LL_DMA_GetChannelPriorityLevel + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_PRIORITY_LOW + * @arg @ref LL_DMA_PRIORITY_MEDIUM + * @arg @ref LL_DMA_PRIORITY_HIGH + * @arg @ref LL_DMA_PRIORITY_VERYHIGH + */ + __STATIC_INLINE uint32_t LL_DMA_GetChannelPriorityLevel(DMA_TypeDef *DMAx, + uint32_t Channel) + { + return (READ_BIT( + ((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_PL)); + } + + /** + * @brief Set Number of data to transfer. + * @note This action has no effect if + * channel is enabled. + * @rmtoll CNDTR NDT LL_DMA_SetDataLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param NbData Between Min_Data = 0 and Max_Data = 0x0000FFFF + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetDataLength(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t NbData) + { + MODIFY_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CNDTR, + DMA_CNDTR_NDT, NbData); + } + + /** + * @brief Get Number of data to transfer. + * @note Once the channel is enabled, the return value indicate the + * remaining bytes to be transmitted. + * @rmtoll CNDTR NDT LL_DMA_GetDataLength + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ + __STATIC_INLINE uint32_t LL_DMA_GetDataLength(DMA_TypeDef *DMAx, uint32_t Channel) + { + return (READ_BIT( + ((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CNDTR, + DMA_CNDTR_NDT)); + } + + /** + * @brief Configure the Source and Destination addresses. + * @note This API must not be called when the DMA channel is enabled. + * @note Each IP using DMA provides an API to get directly the register address + * (LL_PPP_DMA_GetRegAddr). + * @rmtoll CPAR PA LL_DMA_ConfigAddresses\n + * CMAR MA LL_DMA_ConfigAddresses + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param SrcAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @param DstAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_DMA_DIRECTION_PERIPH_TO_MEMORY + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_PERIPH + * @arg @ref LL_DMA_DIRECTION_MEMORY_TO_MEMORY + * @retval None + */ + __STATIC_INLINE void LL_DMA_ConfigAddresses(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t SrcAddress, uint32_t DstAddress, + uint32_t Direction) + { + /* Direction Memory to Periph */ + if (Direction == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) + { + WRITE_REG(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CMAR, + SrcAddress); + WRITE_REG(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CPAR, + DstAddress); + } + /* Direction Periph to Memory and Memory to Memory */ + else + { + WRITE_REG(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CPAR, + SrcAddress); + WRITE_REG(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CMAR, + DstAddress); + } + } + + /** + * @brief Set the Memory address. + * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or + * LL_DMA_DIRECTION_MEMORY_TO_PERIPH only. + * @note This API must not be called when the DMA channel is enabled. + * @rmtoll CMAR MA LL_DMA_SetMemoryAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetMemoryAddress(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t MemoryAddress) + { + WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CMAR, + MemoryAddress); + } + + /** + * @brief Set the Peripheral address. + * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or + * LL_DMA_DIRECTION_MEMORY_TO_PERIPH only. + * @note This API must not be called when the DMA channel is enabled. + * @rmtoll CPAR PA LL_DMA_SetPeriphAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param PeriphAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetPeriphAddress(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t PeriphAddress) + { + WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CPAR, + PeriphAddress); + } + + /** + * @brief Get Memory address. + * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or + * LL_DMA_DIRECTION_MEMORY_TO_PERIPH only. + * @rmtoll CMAR MA LL_DMA_GetMemoryAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ + __STATIC_INLINE uint32_t LL_DMA_GetMemoryAddress(DMA_TypeDef *DMAx, uint32_t Channel) + { + return ( + READ_REG(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CMAR)); + } + + /** + * @brief Get Peripheral address. + * @note Interface used for direction LL_DMA_DIRECTION_PERIPH_TO_MEMORY or + * LL_DMA_DIRECTION_MEMORY_TO_PERIPH only. + * @rmtoll CPAR PA LL_DMA_GetPeriphAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ + __STATIC_INLINE uint32_t LL_DMA_GetPeriphAddress(DMA_TypeDef *DMAx, uint32_t Channel) + { + return ( + READ_REG(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CPAR)); + } + + /** + * @brief Set the Memory to Memory Source address. + * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only. + * @note This API must not be called when the DMA channel is enabled. + * @rmtoll CPAR PA LL_DMA_SetM2MSrcAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetM2MSrcAddress(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t MemoryAddress) + { + WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CPAR, + MemoryAddress); + } + + /** + * @brief Set the Memory to Memory Destination address. + * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only. + * @note This API must not be called when the DMA channel is enabled. + * @rmtoll CMAR MA LL_DMA_SetM2MDstAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param MemoryAddress Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetM2MDstAddress(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t MemoryAddress) + { + WRITE_REG(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CMAR, + MemoryAddress); + } + + /** + * @brief Get the Memory to Memory Source address. + * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only. + * @rmtoll CPAR PA LL_DMA_GetM2MSrcAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ + __STATIC_INLINE uint32_t LL_DMA_GetM2MSrcAddress(DMA_TypeDef *DMAx, uint32_t Channel) + { + return ( + READ_REG(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CPAR)); + } + + /** + * @brief Get the Memory to Memory Destination address. + * @note Interface used for direction LL_DMA_DIRECTION_MEMORY_TO_MEMORY only. + * @rmtoll CMAR MA LL_DMA_GetM2MDstAddress + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Between Min_Data = 0 and Max_Data = 0xFFFFFFFF + */ + __STATIC_INLINE uint32_t LL_DMA_GetM2MDstAddress(DMA_TypeDef *DMAx, uint32_t Channel) + { + return ( + READ_REG(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CMAR)); + } + +#if (defined(DMA1_CSELR_DEFAULT) || defined(DMA2_CSELR_DEFAULT)) + /** + * @brief Set DMA request for DMA instance on Channel x. + * @note Please refer to Reference Manual to get the available mapping of Request + * value link to Channel Selection. + * @rmtoll CSELR C1S LL_DMA_SetPeriphRequest\n + * CSELR C2S LL_DMA_SetPeriphRequest\n + * CSELR C3S LL_DMA_SetPeriphRequest\n + * CSELR C4S LL_DMA_SetPeriphRequest\n + * CSELR C5S LL_DMA_SetPeriphRequest\n + * CSELR C6S LL_DMA_SetPeriphRequest\n + * CSELR C7S LL_DMA_SetPeriphRequest + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @param PeriphRequest This parameter can be one of the following values: + * @arg @ref LL_DMA_REQUEST_0 + * @arg @ref LL_DMA_REQUEST_1 + * @arg @ref LL_DMA_REQUEST_2 + * @arg @ref LL_DMA_REQUEST_3 + * @arg @ref LL_DMA_REQUEST_4 + * @arg @ref LL_DMA_REQUEST_5 + * @arg @ref LL_DMA_REQUEST_6 + * @arg @ref LL_DMA_REQUEST_7 + * @arg @ref LL_DMA_REQUEST_8 + * @arg @ref LL_DMA_REQUEST_9 + * @arg @ref LL_DMA_REQUEST_10 + * @arg @ref LL_DMA_REQUEST_11 + * @arg @ref LL_DMA_REQUEST_12 + * @arg @ref LL_DMA_REQUEST_13 + * @arg @ref LL_DMA_REQUEST_14 + * @arg @ref LL_DMA_REQUEST_15 + * @retval None + */ + __STATIC_INLINE void LL_DMA_SetPeriphRequest(DMA_TypeDef *DMAx, uint32_t Channel, + uint32_t PeriphRequest) + { + MODIFY_REG(DMAx->CSELR, DMA_CSELR_C1S << ((Channel - 1U) * 4U), + PeriphRequest << DMA_POSITION_CSELR_CXS); + } + + /** + * @brief Get DMA request for DMA instance on Channel x. + * @rmtoll CSELR C1S LL_DMA_GetPeriphRequest\n + * CSELR C2S LL_DMA_GetPeriphRequest\n + * CSELR C3S LL_DMA_GetPeriphRequest\n + * CSELR C4S LL_DMA_GetPeriphRequest\n + * CSELR C5S LL_DMA_GetPeriphRequest\n + * CSELR C6S LL_DMA_GetPeriphRequest\n + * CSELR C7S LL_DMA_GetPeriphRequest + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_DMA_REQUEST_0 + * @arg @ref LL_DMA_REQUEST_1 + * @arg @ref LL_DMA_REQUEST_2 + * @arg @ref LL_DMA_REQUEST_3 + * @arg @ref LL_DMA_REQUEST_4 + * @arg @ref LL_DMA_REQUEST_5 + * @arg @ref LL_DMA_REQUEST_6 + * @arg @ref LL_DMA_REQUEST_7 + * @arg @ref LL_DMA_REQUEST_8 + * @arg @ref LL_DMA_REQUEST_9 + * @arg @ref LL_DMA_REQUEST_10 + * @arg @ref LL_DMA_REQUEST_11 + * @arg @ref LL_DMA_REQUEST_12 + * @arg @ref LL_DMA_REQUEST_13 + * @arg @ref LL_DMA_REQUEST_14 + * @arg @ref LL_DMA_REQUEST_15 + */ + __STATIC_INLINE uint32_t LL_DMA_GetPeriphRequest(DMA_TypeDef *DMAx, uint32_t Channel) + { + return (READ_BIT(DMAx->CSELR, DMA_CSELR_C1S << ((Channel - 1U) * 4U)) >> + DMA_POSITION_CSELR_CXS); + } +#endif + + /** + * @} + */ + + /** @defgroup DMA_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + + /** + * @brief Get Channel 1 global interrupt flag. + * @rmtoll ISR GIF1 LL_DMA_IsActiveFlag_GI1 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI1(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_GIF1) == (DMA_ISR_GIF1)); + } + + /** + * @brief Get Channel 2 global interrupt flag. + * @rmtoll ISR GIF2 LL_DMA_IsActiveFlag_GI2 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI2(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_GIF2) == (DMA_ISR_GIF2)); + } + + /** + * @brief Get Channel 3 global interrupt flag. + * @rmtoll ISR GIF3 LL_DMA_IsActiveFlag_GI3 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI3(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_GIF3) == (DMA_ISR_GIF3)); + } + + /** + * @brief Get Channel 4 global interrupt flag. + * @rmtoll ISR GIF4 LL_DMA_IsActiveFlag_GI4 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI4(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_GIF4) == (DMA_ISR_GIF4)); + } + + /** + * @brief Get Channel 5 global interrupt flag. + * @rmtoll ISR GIF5 LL_DMA_IsActiveFlag_GI5 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI5(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_GIF5) == (DMA_ISR_GIF5)); + } + +#if defined(DMA1_Channel6) + /** + * @brief Get Channel 6 global interrupt flag. + * @rmtoll ISR GIF6 LL_DMA_IsActiveFlag_GI6 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI6(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_GIF6) == (DMA_ISR_GIF6)); + } +#endif + +#if defined(DMA1_Channel7) + /** + * @brief Get Channel 7 global interrupt flag. + * @rmtoll ISR GIF7 LL_DMA_IsActiveFlag_GI7 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_GI7(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_GIF7) == (DMA_ISR_GIF7)); + } +#endif + + /** + * @brief Get Channel 1 transfer complete flag. + * @rmtoll ISR TCIF1 LL_DMA_IsActiveFlag_TC1 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC1(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF1) == (DMA_ISR_TCIF1)); + } + + /** + * @brief Get Channel 2 transfer complete flag. + * @rmtoll ISR TCIF2 LL_DMA_IsActiveFlag_TC2 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC2(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF2) == (DMA_ISR_TCIF2)); + } + + /** + * @brief Get Channel 3 transfer complete flag. + * @rmtoll ISR TCIF3 LL_DMA_IsActiveFlag_TC3 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC3(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF3) == (DMA_ISR_TCIF3)); + } + + /** + * @brief Get Channel 4 transfer complete flag. + * @rmtoll ISR TCIF4 LL_DMA_IsActiveFlag_TC4 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC4(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF4) == (DMA_ISR_TCIF4)); + } + + /** + * @brief Get Channel 5 transfer complete flag. + * @rmtoll ISR TCIF5 LL_DMA_IsActiveFlag_TC5 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC5(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF5) == (DMA_ISR_TCIF5)); + } + +#if defined(DMA1_Channel6) + /** + * @brief Get Channel 6 transfer complete flag. + * @rmtoll ISR TCIF6 LL_DMA_IsActiveFlag_TC6 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC6(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF6) == (DMA_ISR_TCIF6)); + } +#endif + +#if defined(DMA1_Channel7) + /** + * @brief Get Channel 7 transfer complete flag. + * @rmtoll ISR TCIF7 LL_DMA_IsActiveFlag_TC7 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TC7(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TCIF7) == (DMA_ISR_TCIF7)); + } +#endif + + /** + * @brief Get Channel 1 half transfer flag. + * @rmtoll ISR HTIF1 LL_DMA_IsActiveFlag_HT1 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT1(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF1) == (DMA_ISR_HTIF1)); + } + + /** + * @brief Get Channel 2 half transfer flag. + * @rmtoll ISR HTIF2 LL_DMA_IsActiveFlag_HT2 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT2(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF2) == (DMA_ISR_HTIF2)); + } + + /** + * @brief Get Channel 3 half transfer flag. + * @rmtoll ISR HTIF3 LL_DMA_IsActiveFlag_HT3 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT3(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF3) == (DMA_ISR_HTIF3)); + } + + /** + * @brief Get Channel 4 half transfer flag. + * @rmtoll ISR HTIF4 LL_DMA_IsActiveFlag_HT4 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT4(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF4) == (DMA_ISR_HTIF4)); + } + + /** + * @brief Get Channel 5 half transfer flag. + * @rmtoll ISR HTIF5 LL_DMA_IsActiveFlag_HT5 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT5(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF5) == (DMA_ISR_HTIF5)); + } + +#if defined(DMA1_Channel6) + /** + * @brief Get Channel 6 half transfer flag. + * @rmtoll ISR HTIF6 LL_DMA_IsActiveFlag_HT6 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT6(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF6) == (DMA_ISR_HTIF6)); + } +#endif + +#if defined(DMA1_Channel7) + /** + * @brief Get Channel 7 half transfer flag. + * @rmtoll ISR HTIF7 LL_DMA_IsActiveFlag_HT7 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_HT7(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_HTIF7) == (DMA_ISR_HTIF7)); + } +#endif + + /** + * @brief Get Channel 1 transfer error flag. + * @rmtoll ISR TEIF1 LL_DMA_IsActiveFlag_TE1 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE1(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF1) == (DMA_ISR_TEIF1)); + } + + /** + * @brief Get Channel 2 transfer error flag. + * @rmtoll ISR TEIF2 LL_DMA_IsActiveFlag_TE2 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE2(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF2) == (DMA_ISR_TEIF2)); + } + + /** + * @brief Get Channel 3 transfer error flag. + * @rmtoll ISR TEIF3 LL_DMA_IsActiveFlag_TE3 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE3(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF3) == (DMA_ISR_TEIF3)); + } + + /** + * @brief Get Channel 4 transfer error flag. + * @rmtoll ISR TEIF4 LL_DMA_IsActiveFlag_TE4 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE4(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF4) == (DMA_ISR_TEIF4)); + } + + /** + * @brief Get Channel 5 transfer error flag. + * @rmtoll ISR TEIF5 LL_DMA_IsActiveFlag_TE5 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE5(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF5) == (DMA_ISR_TEIF5)); + } + +#if defined(DMA1_Channel6) + /** + * @brief Get Channel 6 transfer error flag. + * @rmtoll ISR TEIF6 LL_DMA_IsActiveFlag_TE6 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE6(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF6) == (DMA_ISR_TEIF6)); + } +#endif + +#if defined(DMA1_Channel7) + /** + * @brief Get Channel 7 transfer error flag. + * @rmtoll ISR TEIF7 LL_DMA_IsActiveFlag_TE7 + * @param DMAx DMAx Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsActiveFlag_TE7(DMA_TypeDef *DMAx) + { + return (READ_BIT(DMAx->ISR, DMA_ISR_TEIF7) == (DMA_ISR_TEIF7)); + } +#endif + + /** + * @brief Clear Channel 1 global interrupt flag. + * @note Do not Clear Channel 1 global interrupt flag when the channel in ON. + Instead clear specific flags transfer complete, half transfer & transfer + error flag with LL_DMA_ClearFlag_TC1, LL_DMA_ClearFlag_HT1, + LL_DMA_ClearFlag_TE1. bug id 2.4.1 in Product Errata Sheet. + * @rmtoll IFCR CGIF1 LL_DMA_ClearFlag_GI1 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_GI1(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF1); + } + + /** + * @brief Clear Channel 2 global interrupt flag. + * @note Do not Clear Channel 2 global interrupt flag when the channel in ON. + Instead clear specific flags transfer complete, half transfer & transfer + error flag with LL_DMA_ClearFlag_TC2, LL_DMA_ClearFlag_HT2, + LL_DMA_ClearFlag_TE2. bug id 2.4.1 in Product Errata Sheet. + * @rmtoll IFCR CGIF2 LL_DMA_ClearFlag_GI2 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_GI2(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF2); + } + + /** + * @brief Clear Channel 3 global interrupt flag. + * @note Do not Clear Channel 3 global interrupt flag when the channel in ON. + Instead clear specific flags transfer complete, half transfer & transfer + error flag with LL_DMA_ClearFlag_TC3, LL_DMA_ClearFlag_HT3, + LL_DMA_ClearFlag_TE3. bug id 2.4.1 in Product Errata Sheet. + * @rmtoll IFCR CGIF3 LL_DMA_ClearFlag_GI3 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_GI3(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF3); + } + + /** + * @brief Clear Channel 4 global interrupt flag. + * @note Do not Clear Channel 4 global interrupt flag when the channel in ON. + Instead clear specific flags transfer complete, half transfer & transfer + error flag with LL_DMA_ClearFlag_TC4, LL_DMA_ClearFlag_HT4, + LL_DMA_ClearFlag_TE4. bug id 2.4.1 in Product Errata Sheet. + * @rmtoll IFCR CGIF4 LL_DMA_ClearFlag_GI4 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_GI4(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF4); + } + + /** + * @brief Clear Channel 5 global interrupt flag. + * @note Do not Clear Channel 5 global interrupt flag when the channel in ON. + Instead clear specific flags transfer complete, half transfer & transfer + error flag with LL_DMA_ClearFlag_TC5, LL_DMA_ClearFlag_HT5, + LL_DMA_ClearFlag_TE5. bug id 2.4.1 in Product Errata Sheet. + * @rmtoll IFCR CGIF5 LL_DMA_ClearFlag_GI5 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_GI5(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF5); + } + +#if defined(DMA1_Channel6) + /** + * @brief Clear Channel 6 global interrupt flag. + * @note Do not Clear Channel 6 global interrupt flag when the channel in ON. + Instead clear specific flags transfer complete, half transfer & transfer + error flag with LL_DMA_ClearFlag_TC6, LL_DMA_ClearFlag_HT6, + LL_DMA_ClearFlag_TE6. bug id 2.4.1 in Product Errata Sheet. + * @rmtoll IFCR CGIF6 LL_DMA_ClearFlag_GI6 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_GI6(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF6); + } +#endif + +#if defined(DMA1_Channel7) + /** + * @brief Clear Channel 7 global interrupt flag. + * @note Do not Clear Channel 7 global interrupt flag when the channel in ON. + Instead clear specific flags transfer complete, half transfer & transfer + error flag with LL_DMA_ClearFlag_TC7, LL_DMA_ClearFlag_HT7, + LL_DMA_ClearFlag_TE7. bug id 2.4.1 in Product Errata Sheet. + * @rmtoll IFCR CGIF7 LL_DMA_ClearFlag_GI7 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_GI7(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CGIF7); + } +#endif + + /** + * @brief Clear Channel 1 transfer complete flag. + * @rmtoll IFCR CTCIF1 LL_DMA_ClearFlag_TC1 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TC1(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF1); + } + + /** + * @brief Clear Channel 2 transfer complete flag. + * @rmtoll IFCR CTCIF2 LL_DMA_ClearFlag_TC2 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TC2(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF2); + } + + /** + * @brief Clear Channel 3 transfer complete flag. + * @rmtoll IFCR CTCIF3 LL_DMA_ClearFlag_TC3 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TC3(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF3); + } + + /** + * @brief Clear Channel 4 transfer complete flag. + * @rmtoll IFCR CTCIF4 LL_DMA_ClearFlag_TC4 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TC4(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF4); + } + + /** + * @brief Clear Channel 5 transfer complete flag. + * @rmtoll IFCR CTCIF5 LL_DMA_ClearFlag_TC5 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TC5(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF5); + } + +#if defined(DMA1_Channel6) + /** + * @brief Clear Channel 6 transfer complete flag. + * @rmtoll IFCR CTCIF6 LL_DMA_ClearFlag_TC6 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TC6(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF6); + } +#endif + +#if defined(DMA1_Channel7) + /** + * @brief Clear Channel 7 transfer complete flag. + * @rmtoll IFCR CTCIF7 LL_DMA_ClearFlag_TC7 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TC7(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTCIF7); + } +#endif + + /** + * @brief Clear Channel 1 half transfer flag. + * @rmtoll IFCR CHTIF1 LL_DMA_ClearFlag_HT1 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_HT1(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF1); + } + + /** + * @brief Clear Channel 2 half transfer flag. + * @rmtoll IFCR CHTIF2 LL_DMA_ClearFlag_HT2 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_HT2(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF2); + } + + /** + * @brief Clear Channel 3 half transfer flag. + * @rmtoll IFCR CHTIF3 LL_DMA_ClearFlag_HT3 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_HT3(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF3); + } + + /** + * @brief Clear Channel 4 half transfer flag. + * @rmtoll IFCR CHTIF4 LL_DMA_ClearFlag_HT4 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_HT4(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF4); + } + + /** + * @brief Clear Channel 5 half transfer flag. + * @rmtoll IFCR CHTIF5 LL_DMA_ClearFlag_HT5 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_HT5(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF5); + } + +#if defined(DMA1_Channel6) + /** + * @brief Clear Channel 6 half transfer flag. + * @rmtoll IFCR CHTIF6 LL_DMA_ClearFlag_HT6 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_HT6(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF6); + } +#endif + +#if defined(DMA1_Channel7) + /** + * @brief Clear Channel 7 half transfer flag. + * @rmtoll IFCR CHTIF7 LL_DMA_ClearFlag_HT7 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_HT7(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CHTIF7); + } +#endif + + /** + * @brief Clear Channel 1 transfer error flag. + * @rmtoll IFCR CTEIF1 LL_DMA_ClearFlag_TE1 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TE1(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF1); + } + + /** + * @brief Clear Channel 2 transfer error flag. + * @rmtoll IFCR CTEIF2 LL_DMA_ClearFlag_TE2 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TE2(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF2); + } + + /** + * @brief Clear Channel 3 transfer error flag. + * @rmtoll IFCR CTEIF3 LL_DMA_ClearFlag_TE3 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TE3(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF3); + } + + /** + * @brief Clear Channel 4 transfer error flag. + * @rmtoll IFCR CTEIF4 LL_DMA_ClearFlag_TE4 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TE4(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF4); + } + + /** + * @brief Clear Channel 5 transfer error flag. + * @rmtoll IFCR CTEIF5 LL_DMA_ClearFlag_TE5 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TE5(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF5); + } + +#if defined(DMA1_Channel6) + /** + * @brief Clear Channel 6 transfer error flag. + * @rmtoll IFCR CTEIF6 LL_DMA_ClearFlag_TE6 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TE6(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF6); + } +#endif + +#if defined(DMA1_Channel7) + /** + * @brief Clear Channel 7 transfer error flag. + * @rmtoll IFCR CTEIF7 LL_DMA_ClearFlag_TE7 + * @param DMAx DMAx Instance + * @retval None + */ + __STATIC_INLINE void LL_DMA_ClearFlag_TE7(DMA_TypeDef *DMAx) + { + WRITE_REG(DMAx->IFCR, DMA_IFCR_CTEIF7); + } +#endif + + /** + * @} + */ + + /** @defgroup DMA_LL_EF_IT_Management IT_Management + * @{ + */ + /** + * @brief Enable Transfer complete interrupt. + * @rmtoll CCR TCIE LL_DMA_EnableIT_TC + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ + __STATIC_INLINE void LL_DMA_EnableIT_TC(DMA_TypeDef *DMAx, uint32_t Channel) + { + SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_TCIE); + } + + /** + * @brief Enable Half transfer interrupt. + * @rmtoll CCR HTIE LL_DMA_EnableIT_HT + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ + __STATIC_INLINE void LL_DMA_EnableIT_HT(DMA_TypeDef *DMAx, uint32_t Channel) + { + SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_HTIE); + } + + /** + * @brief Enable Transfer error interrupt. + * @rmtoll CCR TEIE LL_DMA_EnableIT_TE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ + __STATIC_INLINE void LL_DMA_EnableIT_TE(DMA_TypeDef *DMAx, uint32_t Channel) + { + SET_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_TEIE); + } + + /** + * @brief Disable Transfer complete interrupt. + * @rmtoll CCR TCIE LL_DMA_DisableIT_TC + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ + __STATIC_INLINE void LL_DMA_DisableIT_TC(DMA_TypeDef *DMAx, uint32_t Channel) + { + CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_TCIE); + } + + /** + * @brief Disable Half transfer interrupt. + * @rmtoll CCR HTIE LL_DMA_DisableIT_HT + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ + __STATIC_INLINE void LL_DMA_DisableIT_HT(DMA_TypeDef *DMAx, uint32_t Channel) + { + CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_HTIE); + } + + /** + * @brief Disable Transfer error interrupt. + * @rmtoll CCR TEIE LL_DMA_DisableIT_TE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval None + */ + __STATIC_INLINE void LL_DMA_DisableIT_TE(DMA_TypeDef *DMAx, uint32_t Channel) + { + CLEAR_BIT(((DMA_Channel_TypeDef *)((uint32_t)((uint32_t)DMAx + + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_TEIE); + } + + /** + * @brief Check if Transfer complete Interrupt is enabled. + * @rmtoll CCR TCIE LL_DMA_IsEnabledIT_TC + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_TC(DMA_TypeDef *DMAx, uint32_t Channel) + { + return ( + READ_BIT(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_TCIE) == (DMA_CCR_TCIE)); + } + + /** + * @brief Check if Half transfer Interrupt is enabled. + * @rmtoll CCR HTIE LL_DMA_IsEnabledIT_HT + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_HT(DMA_TypeDef *DMAx, uint32_t Channel) + { + return ( + READ_BIT(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_HTIE) == (DMA_CCR_HTIE)); + } + + /** + * @brief Check if Transfer error Interrupt is enabled. + * @rmtoll CCR TEIE LL_DMA_IsEnabledIT_TE + * @param DMAx DMAx Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_DMA_CHANNEL_1 + * @arg @ref LL_DMA_CHANNEL_2 + * @arg @ref LL_DMA_CHANNEL_3 + * @arg @ref LL_DMA_CHANNEL_4 + * @arg @ref LL_DMA_CHANNEL_5 + * @arg @ref LL_DMA_CHANNEL_6 + * @arg @ref LL_DMA_CHANNEL_7 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_DMA_IsEnabledIT_TE(DMA_TypeDef *DMAx, uint32_t Channel) + { + return ( + READ_BIT(((DMA_Channel_TypeDef *)(( + uint32_t)((uint32_t)DMAx + CHANNEL_OFFSET_TAB[Channel - 1U]))) + ->CCR, + DMA_CCR_TEIE) == (DMA_CCR_TEIE)); + } + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup DMA_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, + LL_DMA_InitTypeDef *DMA_InitStruct); + uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel); + void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* DMA1 || DMA2 */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_DMA_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_exti.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_exti.h new file mode 100644 index 0000000000..81c00f7bba --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_exti.h @@ -0,0 +1,1013 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_exti.h + * @author MCD Application Team + * @brief Header file of EXTI LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_EXTI_H +#define __STM32F0xx_LL_EXTI_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(EXTI) + +/** @defgroup EXTI_LL EXTI + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private Macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup EXTI_LL_Private_Macros EXTI Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup EXTI_LL_ES_INIT EXTI Exported Init structure + * @{ + */ + typedef struct + { + uint32_t Line_0_31; /*!< Specifies the EXTI lines to be enabled or disabled for + Lines in range 0 to 31 This parameter can be any + combination of @ref EXTI_LL_EC_LINE */ + + FunctionalState + LineCommand; /*!< Specifies the new state of the selected EXTI lines. + This parameter can be set either to ENABLE or DISABLE */ + + uint8_t Mode; /*!< Specifies the mode for the EXTI lines. + This parameter can be a value of @ref EXTI_LL_EC_MODE. */ + + uint8_t Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines. + This parameter can be a value of @ref EXTI_LL_EC_TRIGGER. */ + } LL_EXTI_InitTypeDef; + +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup EXTI_LL_Exported_Constants EXTI Exported Constants + * @{ + */ + +/** @defgroup EXTI_LL_EC_LINE LINE + * @{ + */ +#define LL_EXTI_LINE_0 EXTI_IMR_IM0 /*!< Extended line 0 */ +#define LL_EXTI_LINE_1 EXTI_IMR_IM1 /*!< Extended line 1 */ +#define LL_EXTI_LINE_2 EXTI_IMR_IM2 /*!< Extended line 2 */ +#define LL_EXTI_LINE_3 EXTI_IMR_IM3 /*!< Extended line 3 */ +#define LL_EXTI_LINE_4 EXTI_IMR_IM4 /*!< Extended line 4 */ +#define LL_EXTI_LINE_5 EXTI_IMR_IM5 /*!< Extended line 5 */ +#define LL_EXTI_LINE_6 EXTI_IMR_IM6 /*!< Extended line 6 */ +#define LL_EXTI_LINE_7 EXTI_IMR_IM7 /*!< Extended line 7 */ +#define LL_EXTI_LINE_8 EXTI_IMR_IM8 /*!< Extended line 8 */ +#define LL_EXTI_LINE_9 EXTI_IMR_IM9 /*!< Extended line 9 */ +#define LL_EXTI_LINE_10 EXTI_IMR_IM10 /*!< Extended line 10 */ +#define LL_EXTI_LINE_11 EXTI_IMR_IM11 /*!< Extended line 11 */ +#define LL_EXTI_LINE_12 EXTI_IMR_IM12 /*!< Extended line 12 */ +#define LL_EXTI_LINE_13 EXTI_IMR_IM13 /*!< Extended line 13 */ +#define LL_EXTI_LINE_14 EXTI_IMR_IM14 /*!< Extended line 14 */ +#define LL_EXTI_LINE_15 EXTI_IMR_IM15 /*!< Extended line 15 */ +#if defined(EXTI_IMR_IM16) +#define LL_EXTI_LINE_16 EXTI_IMR_IM16 /*!< Extended line 16 */ +#endif +#define LL_EXTI_LINE_17 EXTI_IMR_IM17 /*!< Extended line 17 */ +#if defined(EXTI_IMR_IM18) +#define LL_EXTI_LINE_18 EXTI_IMR_IM18 /*!< Extended line 18 */ +#endif +#define LL_EXTI_LINE_19 EXTI_IMR_IM19 /*!< Extended line 19 */ +#if defined(EXTI_IMR_IM20) +#define LL_EXTI_LINE_20 EXTI_IMR_IM20 /*!< Extended line 20 */ +#endif +#if defined(EXTI_IMR_IM21) +#define LL_EXTI_LINE_21 EXTI_IMR_IM21 /*!< Extended line 21 */ +#endif +#if defined(EXTI_IMR_IM22) +#define LL_EXTI_LINE_22 EXTI_IMR_IM22 /*!< Extended line 22 */ +#endif +#define LL_EXTI_LINE_23 EXTI_IMR_IM23 /*!< Extended line 23 */ +#if defined(EXTI_IMR_IM24) +#define LL_EXTI_LINE_24 EXTI_IMR_IM24 /*!< Extended line 24 */ +#endif +#if defined(EXTI_IMR_IM25) +#define LL_EXTI_LINE_25 EXTI_IMR_IM25 /*!< Extended line 25 */ +#endif +#if defined(EXTI_IMR_IM26) +#define LL_EXTI_LINE_26 EXTI_IMR_IM26 /*!< Extended line 26 */ +#endif +#if defined(EXTI_IMR_IM27) +#define LL_EXTI_LINE_27 EXTI_IMR_IM27 /*!< Extended line 27 */ +#endif +#if defined(EXTI_IMR_IM28) +#define LL_EXTI_LINE_28 EXTI_IMR_IM28 /*!< Extended line 28 */ +#endif +#if defined(EXTI_IMR_IM29) +#define LL_EXTI_LINE_29 EXTI_IMR_IM29 /*!< Extended line 29 */ +#endif +#if defined(EXTI_IMR_IM30) +#define LL_EXTI_LINE_30 EXTI_IMR_IM30 /*!< Extended line 30 */ +#endif +#if defined(EXTI_IMR_IM31) +#define LL_EXTI_LINE_31 EXTI_IMR_IM31 /*!< Extended line 31 */ +#endif +#define LL_EXTI_LINE_ALL_0_31 EXTI_IMR_IM /*!< All Extended line not reserved*/ + + +#define LL_EXTI_LINE_ALL (0xFFFFFFFFU) /*!< All Extended line */ + +#if defined(USE_FULL_LL_DRIVER) +#define LL_EXTI_LINE_NONE (0x00000000U) /*!< None Extended line */ +#endif /*USE_FULL_LL_DRIVER*/ + +/** + * @} + */ +#if defined(USE_FULL_LL_DRIVER) + +/** @defgroup EXTI_LL_EC_MODE Mode + * @{ + */ +#define LL_EXTI_MODE_IT ((uint8_t)0x00U) /*!< Interrupt Mode */ +#define LL_EXTI_MODE_EVENT ((uint8_t)0x01U) /*!< Event Mode */ +#define LL_EXTI_MODE_IT_EVENT ((uint8_t)0x02U) /*!< Interrupt & Event Mode */ +/** + * @} + */ + +/** @defgroup EXTI_LL_EC_TRIGGER Edge Trigger + * @{ + */ +#define LL_EXTI_TRIGGER_NONE ((uint8_t)0x00U) /*!< No Trigger Mode */ +#define LL_EXTI_TRIGGER_RISING ((uint8_t)0x01U) /*!< Trigger Rising Mode */ +#define LL_EXTI_TRIGGER_FALLING ((uint8_t)0x02U) /*!< Trigger Falling Mode */ +#define LL_EXTI_TRIGGER_RISING_FALLING \ + ((uint8_t)0x03U) /*!< Trigger Rising & Falling Mode */ + + /** + * @} + */ + + +#endif /*USE_FULL_LL_DRIVER*/ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EXTI_LL_Exported_Macros EXTI Exported Macros + * @{ + */ + +/** @defgroup EXTI_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in EXTI register + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_EXTI_WriteReg(__REG__, __VALUE__) WRITE_REG(EXTI->__REG__, (__VALUE__)) + +/** + * @brief Read a value in EXTI register + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_EXTI_ReadReg(__REG__) READ_REG(EXTI->__REG__) + /** + * @} + */ + + + /** + * @} + */ + + + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup EXTI_LL_Exported_Functions EXTI Exported Functions + * @{ + */ + /** @defgroup EXTI_LL_EF_IT_Management IT_Management + * @{ + */ + + /** + * @brief Enable ExtiLine Interrupt request for Lines in range 0 to 31 + * @note The reset value for the direct or internal lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @rmtoll IMR IMx LL_EXTI_EnableIT_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine) + { + SET_BIT(EXTI->IMR, ExtiLine); + } + + /** + * @brief Disable ExtiLine Interrupt request for Lines in range 0 to 31 + * @note The reset value for the direct or internal lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @rmtoll IMR IMx LL_EXTI_DisableIT_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine) + { + CLEAR_BIT(EXTI->IMR, ExtiLine); + } + + + /** + * @brief Indicate if ExtiLine Interrupt request is enabled for Lines in range 0 to + * 31 + * @note The reset value for the direct or internal lines (see RM) + * is set to 1 in order to enable the interrupt by default. + * Bits are set automatically at Power on. + * @rmtoll IMR IMx LL_EXTI_IsEnabledIT_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_EXTI_IsEnabledIT_0_31(uint32_t ExtiLine) + { + return (READ_BIT(EXTI->IMR, ExtiLine) == (ExtiLine)); + } + + + /** + * @} + */ + + /** @defgroup EXTI_LL_EF_Event_Management Event_Management + * @{ + */ + + /** + * @brief Enable ExtiLine Event request for Lines in range 0 to 31 + * @rmtoll EMR EMx LL_EXTI_EnableEvent_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_EnableEvent_0_31(uint32_t ExtiLine) + { + SET_BIT(EXTI->EMR, ExtiLine); + } + + + /** + * @brief Disable ExtiLine Event request for Lines in range 0 to 31 + * @rmtoll EMR EMx LL_EXTI_DisableEvent_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_DisableEvent_0_31(uint32_t ExtiLine) + { + CLEAR_BIT(EXTI->EMR, ExtiLine); + } + + + /** + * @brief Indicate if ExtiLine Event request is enabled for Lines in range 0 to 31 + * @rmtoll EMR EMx LL_EXTI_IsEnabledEvent_0_31 + * @param ExtiLine This parameter can be one of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_17 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_23 + * @arg @ref LL_EXTI_LINE_24 + * @arg @ref LL_EXTI_LINE_25 + * @arg @ref LL_EXTI_LINE_26 + * @arg @ref LL_EXTI_LINE_27 + * @arg @ref LL_EXTI_LINE_28 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @arg @ref LL_EXTI_LINE_ALL_0_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_EXTI_IsEnabledEvent_0_31(uint32_t ExtiLine) + { + return (READ_BIT(EXTI->EMR, ExtiLine) == (ExtiLine)); + } + + + /** + * @} + */ + + /** @defgroup EXTI_LL_EF_Rising_Trigger_Management Rising_Trigger_Management + * @{ + */ + + /** + * @brief Enable ExtiLine Rising Edge Trigger for Lines in range 0 to 31 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a rising edge on a configurable interrupt + * line occurs during a write operation in the EXTI_RTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll RTSR RTx LL_EXTI_EnableRisingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine) + { + SET_BIT(EXTI->RTSR, ExtiLine); + } + + + /** + * @brief Disable ExtiLine Rising Edge Trigger for Lines in range 0 to 31 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a rising edge on a configurable interrupt + * line occurs during a write operation in the EXTI_RTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll RTSR RTx LL_EXTI_DisableRisingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine) + { + CLEAR_BIT(EXTI->RTSR, ExtiLine); + } + + + /** + * @brief Check if rising edge trigger is enabled for Lines in range 0 to 31 + * @rmtoll RTSR RTx LL_EXTI_IsEnabledRisingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_EXTI_IsEnabledRisingTrig_0_31(uint32_t ExtiLine) + { + return (READ_BIT(EXTI->RTSR, ExtiLine) == (ExtiLine)); + } + + + /** + * @} + */ + + /** @defgroup EXTI_LL_EF_Falling_Trigger_Management Falling_Trigger_Management + * @{ + */ + + /** + * @brief Enable ExtiLine Falling Edge Trigger for Lines in range 0 to 31 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a falling edge on a configurable interrupt + * line occurs during a write operation in the EXTI_FTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for + * the same interrupt line. In this case, both generate a trigger + * condition. + * @rmtoll FTSR FTx LL_EXTI_EnableFallingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine) + { + SET_BIT(EXTI->FTSR, ExtiLine); + } + + + /** + * @brief Disable ExtiLine Falling Edge Trigger for Lines in range 0 to 31 + * @note The configurable wakeup lines are edge-triggered. No glitch must be + * generated on these lines. If a Falling edge on a configurable interrupt + * line occurs during a write operation in the EXTI_FTSR register, the + * pending bit is not set. + * Rising and falling edge triggers can be set for the same interrupt line. + * In this case, both generate a trigger condition. + * @rmtoll FTSR FTx LL_EXTI_DisableFallingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine) + { + CLEAR_BIT(EXTI->FTSR, ExtiLine); + } + + + /** + * @brief Check if falling edge trigger is enabled for Lines in range 0 to 31 + * @rmtoll FTSR FTx LL_EXTI_IsEnabledFallingTrig_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_EXTI_IsEnabledFallingTrig_0_31(uint32_t ExtiLine) + { + return (READ_BIT(EXTI->FTSR, ExtiLine) == (ExtiLine)); + } + + + /** + * @} + */ + + /** @defgroup EXTI_LL_EF_Software_Interrupt_Management Software_Interrupt_Management + * @{ + */ + + /** + * @brief Generate a software Interrupt Event for Lines in range 0 to 31 + * @note If the interrupt is enabled on this line in the EXTI_IMR, writing a 1 to + * this bit when it is at '0' sets the corresponding pending bit in EXTI_PR + * resulting in an interrupt request generation. + * This bit is cleared by clearing the corresponding bit in the EXTI_PR + * register (by writing a 1 into the bit) + * @rmtoll SWIER SWIx LL_EXTI_GenerateSWI_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_GenerateSWI_0_31(uint32_t ExtiLine) + { + SET_BIT(EXTI->SWIER, ExtiLine); + } + + + /** + * @} + */ + + /** @defgroup EXTI_LL_EF_Flag_Management Flag_Management + * @{ + */ + + /** + * @brief Check if the ExtLine Flag is set or not for Lines in range 0 to 31 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR PIFx LL_EXTI_IsActiveFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_EXTI_IsActiveFlag_0_31(uint32_t ExtiLine) + { + return (READ_BIT(EXTI->PR, ExtiLine) == (ExtiLine)); + } + + + /** + * @brief Read ExtLine Combination Flag for Lines in range 0 to 31 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR PIFx LL_EXTI_ReadFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval @note This bit is set when the selected edge event arrives on the interrupt + */ + __STATIC_INLINE uint32_t LL_EXTI_ReadFlag_0_31(uint32_t ExtiLine) + { + return (uint32_t)(READ_BIT(EXTI->PR, ExtiLine)); + } + + + /** + * @brief Clear ExtLine Flags for Lines in range 0 to 31 + * @note This bit is set when the selected edge event arrives on the interrupt + * line. This bit is cleared by writing a 1 to the bit. + * @rmtoll PR PIFx LL_EXTI_ClearFlag_0_31 + * @param ExtiLine This parameter can be a combination of the following values: + * @arg @ref LL_EXTI_LINE_0 + * @arg @ref LL_EXTI_LINE_1 + * @arg @ref LL_EXTI_LINE_2 + * @arg @ref LL_EXTI_LINE_3 + * @arg @ref LL_EXTI_LINE_4 + * @arg @ref LL_EXTI_LINE_5 + * @arg @ref LL_EXTI_LINE_6 + * @arg @ref LL_EXTI_LINE_7 + * @arg @ref LL_EXTI_LINE_8 + * @arg @ref LL_EXTI_LINE_9 + * @arg @ref LL_EXTI_LINE_10 + * @arg @ref LL_EXTI_LINE_11 + * @arg @ref LL_EXTI_LINE_12 + * @arg @ref LL_EXTI_LINE_13 + * @arg @ref LL_EXTI_LINE_14 + * @arg @ref LL_EXTI_LINE_15 + * @arg @ref LL_EXTI_LINE_16 + * @arg @ref LL_EXTI_LINE_18 + * @arg @ref LL_EXTI_LINE_19 + * @arg @ref LL_EXTI_LINE_20 + * @arg @ref LL_EXTI_LINE_21 + * @arg @ref LL_EXTI_LINE_22 + * @arg @ref LL_EXTI_LINE_29 + * @arg @ref LL_EXTI_LINE_30 + * @arg @ref LL_EXTI_LINE_31 + * @note Please check each device line mapping for EXTI Line availability + * @retval None + */ + __STATIC_INLINE void LL_EXTI_ClearFlag_0_31(uint32_t ExtiLine) + { + WRITE_REG(EXTI->PR, ExtiLine); + } + + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup EXTI_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct); + uint32_t LL_EXTI_DeInit(void); + void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct); + + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* EXTI */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_EXTI_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_gpio.c b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_gpio.c new file mode 100644 index 0000000000..6ce64274e0 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_gpio.c @@ -0,0 +1,279 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_gpio.c + * @author MCD Application Team + * @brief GPIO LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_ll_gpio.h" + +#include "stm32f0xx_ll_bus.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif + +/** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(GPIOA) || defined(GPIOB) || defined(GPIOC) || defined(GPIOD) || \ + defined(GPIOE) || defined(GPIOF) + +/** @addtogroup GPIO_LL + * @{ + */ +/** MISRA C:2012 deviation rule has been granted for following rules: + * Rule-12.2 - Medium: RHS argument is in interval [0,INF] which is out of + * range of the shift operator in following API : + * LL_GPIO_Init + * LL_GPIO_DeInit + * LL_GPIO_SetPinMode + * LL_GPIO_GetPinMode + * LL_GPIO_SetPinSpeed + * LL_GPIO_GetPinSpeed + * LL_GPIO_SetPinPull + * LL_GPIO_GetPinPull + * LL_GPIO_GetAFPin_0_7 + * LL_GPIO_SetAFPin_0_7 + * LL_GPIO_SetAFPin_8_15 + * LL_GPIO_GetAFPin_8_15 + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup GPIO_LL_Private_Macros + * @{ + */ +#define IS_LL_GPIO_PIN(__VALUE__) \ + (((0x00u) < (__VALUE__)) && ((__VALUE__) <= (LL_GPIO_PIN_ALL))) + +#define IS_LL_GPIO_MODE(__VALUE__) \ + (((__VALUE__) == LL_GPIO_MODE_INPUT) || ((__VALUE__) == LL_GPIO_MODE_OUTPUT) || \ + ((__VALUE__) == LL_GPIO_MODE_ALTERNATE) || ((__VALUE__) == LL_GPIO_MODE_ANALOG)) + +#define IS_LL_GPIO_OUTPUT_TYPE(__VALUE__) \ + (((__VALUE__) == LL_GPIO_OUTPUT_PUSHPULL) || \ + ((__VALUE__) == LL_GPIO_OUTPUT_OPENDRAIN)) + +#define IS_LL_GPIO_SPEED(__VALUE__) \ + (((__VALUE__) == LL_GPIO_SPEED_FREQ_LOW) || \ + ((__VALUE__) == LL_GPIO_SPEED_FREQ_MEDIUM) || \ + ((__VALUE__) == LL_GPIO_SPEED_FREQ_HIGH)) + +#define IS_LL_GPIO_PULL(__VALUE__) \ + (((__VALUE__) == LL_GPIO_PULL_NO) || ((__VALUE__) == LL_GPIO_PULL_UP) || \ + ((__VALUE__) == LL_GPIO_PULL_DOWN)) + +#define IS_LL_GPIO_ALTERNATE(__VALUE__) \ + (((__VALUE__) == LL_GPIO_AF_0) || ((__VALUE__) == LL_GPIO_AF_1) || \ + ((__VALUE__) == LL_GPIO_AF_2) || ((__VALUE__) == LL_GPIO_AF_3) || \ + ((__VALUE__) == LL_GPIO_AF_4) || ((__VALUE__) == LL_GPIO_AF_5) || \ + ((__VALUE__) == LL_GPIO_AF_6) || ((__VALUE__) == LL_GPIO_AF_7)) +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup GPIO_LL_Exported_Functions + * @{ + */ + +/** @addtogroup GPIO_LL_EF_Init + * @{ + */ + +/** + * @brief De-initialize GPIO registers (Registers restored to their default values). + * @param GPIOx GPIO Port + * @retval An ErrorStatus enumeration value: + * - SUCCESS: GPIO registers are de-initialized + * - ERROR: Wrong GPIO Port + */ +ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx) +{ + ErrorStatus status = SUCCESS; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + + /* Force and Release reset on clock of GPIOx Port */ + if (GPIOx == GPIOA) + { + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPIOA); + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPIOA); + } + else if (GPIOx == GPIOB) + { + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPIOB); + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPIOB); + } + else if (GPIOx == GPIOC) + { + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPIOC); + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPIOC); + } +#if defined(GPIOD) + else if (GPIOx == GPIOD) + { + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPIOD); + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPIOD); + } +#endif /* GPIOD */ +#if defined(GPIOE) + else if (GPIOx == GPIOE) + { + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPIOE); + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPIOE); + } +#endif /* GPIOE */ +#if defined(GPIOF) + else if (GPIOx == GPIOF) + { + LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_GPIOF); + LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_GPIOF); + } +#endif /* GPIOF */ + else + { + status = ERROR; + } + + return (status); +} + +/** + * @brief Initialize GPIO registers according to the specified parameters in + * GPIO_InitStruct. + * @param GPIOx GPIO Port + * @param GPIO_InitStruct pointer to a @ref LL_GPIO_InitTypeDef structure + * that contains the configuration information for the specified GPIO peripheral. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content + * - ERROR: Not applicable + */ +ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct) +{ + uint32_t pinpos; + uint32_t currentpin; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin)); + assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode)); + assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull)); + + /* ------------------------- Configure the port pins ---------------- */ + /* Initialize pinpos on first pin set */ + pinpos = 0; + + /* Configure the port pins */ + while (((GPIO_InitStruct->Pin) >> pinpos) != 0x00u) + { + /* Get current io position */ + currentpin = (GPIO_InitStruct->Pin) & (0x00000001uL << pinpos); + + if (currentpin != 0x00u) + { + if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || + (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE)) + { + /* Check Speed mode parameters */ + assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed)); + + /* Speed mode configuration */ + LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed); + + /* Check Output mode parameters */ + assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType)); + + /* Output mode configuration*/ + LL_GPIO_SetPinOutputType(GPIOx, GPIO_InitStruct->Pin, + GPIO_InitStruct->OutputType); + } + + /* Pull-up Pull down resistor configuration*/ + LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull); + + if (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE) + { + /* Check Alternate parameter */ + assert_param(IS_LL_GPIO_ALTERNATE(GPIO_InitStruct->Alternate)); + + /* Speed mode configuration */ + if (currentpin < LL_GPIO_PIN_8) + { + LL_GPIO_SetAFPin_0_7(GPIOx, currentpin, GPIO_InitStruct->Alternate); + } + else + { + LL_GPIO_SetAFPin_8_15(GPIOx, currentpin, GPIO_InitStruct->Alternate); + } + } + + /* Pin Mode configuration */ + LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode); + } + pinpos++; + } + + return (SUCCESS); +} + +/** + * @brief Set each @ref LL_GPIO_InitTypeDef field to default value. + * @param GPIO_InitStruct pointer to a @ref LL_GPIO_InitTypeDef structure + * whose fields will be set to default values. + * @retval None + */ + +void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct) +{ + /* Reset GPIO init structure parameters values */ + GPIO_InitStruct->Pin = LL_GPIO_PIN_ALL; + GPIO_InitStruct->Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct->Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct->OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct->Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct->Alternate = LL_GPIO_AF_0; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || \ + defined (GPIOE) || defined (GPIOF) */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_gpio.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_gpio.h new file mode 100644 index 0000000000..1b6a2c03fe --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_gpio.h @@ -0,0 +1,981 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_gpio.h + * @author MCD Application Team + * @brief Header file of GPIO LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_GPIO_H +#define __STM32F0xx_LL_GPIO_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(GPIOA) || defined(GPIOB) || defined(GPIOC) || defined(GPIOD) || \ + defined(GPIOE) || defined(GPIOF) + +/** @defgroup GPIO_LL GPIO + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup GPIO_LL_Private_Macros GPIO Private Macros + * @{ + */ + +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup GPIO_LL_ES_INIT GPIO Exported Init structures + * @{ + */ + + /** + * @brief LL GPIO Init Structure definition + */ + typedef struct + { + uint32_t Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_LL_EC_PIN */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_MODE. + + GPIO HW configuration can be modified afterwards using unitary + function @ref LL_GPIO_SetPinMode().*/ + + uint32_t Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_SPEED. + + GPIO HW configuration can be modified afterwards using + unitary function @ref LL_GPIO_SetPinSpeed().*/ + + uint32_t + OutputType; /*!< Specifies the operating output type for the selected pins. + This parameter can be a value of @ref GPIO_LL_EC_OUTPUT. + + GPIO HW configuration can be modified afterwards using + unitary function @ref LL_GPIO_SetPinOutputType().*/ + + uint32_t Pull; /*!< Specifies the operating Pull-up/Pull down for the selected + pins. This parameter can be a value of @ref GPIO_LL_EC_PULL. + + GPIO HW configuration can be modified afterwards using unitary + function @ref LL_GPIO_SetPinPull().*/ + + uint32_t Alternate; /*!< Specifies the Peripheral to be connected to the selected + pins. This parameter can be a value of @ref GPIO_LL_EC_AF. + + GPIO HW configuration can be modified afterwards using + unitary function @ref LL_GPIO_SetAFPin_0_7() and + LL_GPIO_SetAFPin_8_15().*/ + } LL_GPIO_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIO_LL_Exported_Constants GPIO Exported Constants + * @{ + */ + +/** @defgroup GPIO_LL_EC_PIN PIN + * @{ + */ +#define LL_GPIO_PIN_0 GPIO_BSRR_BS_0 /*!< Select pin 0 */ +#define LL_GPIO_PIN_1 GPIO_BSRR_BS_1 /*!< Select pin 1 */ +#define LL_GPIO_PIN_2 GPIO_BSRR_BS_2 /*!< Select pin 2 */ +#define LL_GPIO_PIN_3 GPIO_BSRR_BS_3 /*!< Select pin 3 */ +#define LL_GPIO_PIN_4 GPIO_BSRR_BS_4 /*!< Select pin 4 */ +#define LL_GPIO_PIN_5 GPIO_BSRR_BS_5 /*!< Select pin 5 */ +#define LL_GPIO_PIN_6 GPIO_BSRR_BS_6 /*!< Select pin 6 */ +#define LL_GPIO_PIN_7 GPIO_BSRR_BS_7 /*!< Select pin 7 */ +#define LL_GPIO_PIN_8 GPIO_BSRR_BS_8 /*!< Select pin 8 */ +#define LL_GPIO_PIN_9 GPIO_BSRR_BS_9 /*!< Select pin 9 */ +#define LL_GPIO_PIN_10 GPIO_BSRR_BS_10 /*!< Select pin 10 */ +#define LL_GPIO_PIN_11 GPIO_BSRR_BS_11 /*!< Select pin 11 */ +#define LL_GPIO_PIN_12 GPIO_BSRR_BS_12 /*!< Select pin 12 */ +#define LL_GPIO_PIN_13 GPIO_BSRR_BS_13 /*!< Select pin 13 */ +#define LL_GPIO_PIN_14 GPIO_BSRR_BS_14 /*!< Select pin 14 */ +#define LL_GPIO_PIN_15 GPIO_BSRR_BS_15 /*!< Select pin 15 */ +#define LL_GPIO_PIN_ALL \ + (GPIO_BSRR_BS_0 | GPIO_BSRR_BS_1 | GPIO_BSRR_BS_2 | GPIO_BSRR_BS_3 | \ + GPIO_BSRR_BS_4 | GPIO_BSRR_BS_5 | GPIO_BSRR_BS_6 | GPIO_BSRR_BS_7 | \ + GPIO_BSRR_BS_8 | GPIO_BSRR_BS_9 | GPIO_BSRR_BS_10 | GPIO_BSRR_BS_11 | \ + GPIO_BSRR_BS_12 | GPIO_BSRR_BS_13 | GPIO_BSRR_BS_14 | \ + GPIO_BSRR_BS_15) /*!< Select all pins */ +/** + * @} + */ + +/** @defgroup GPIO_LL_EC_MODE Mode + * @{ + */ +#define LL_GPIO_MODE_INPUT (0x00000000U) /*!< Select input mode */ +#define LL_GPIO_MODE_OUTPUT GPIO_MODER_MODER0_0 /*!< Select output mode */ +#define LL_GPIO_MODE_ALTERNATE \ + GPIO_MODER_MODER0_1 /*!< Select alternate function mode \ + */ +#define LL_GPIO_MODE_ANALOG GPIO_MODER_MODER0 /*!< Select analog mode */ +/** + * @} + */ + +/** @defgroup GPIO_LL_EC_OUTPUT Output Type + * @{ + */ +#define LL_GPIO_OUTPUT_PUSHPULL (0x00000000U) /*!< Select push-pull as output type */ +#define LL_GPIO_OUTPUT_OPENDRAIN \ + GPIO_OTYPER_OT_0 /*!< Select open-drain as output type \ + */ +/** + * @} + */ + +/** @defgroup GPIO_LL_EC_SPEED Output Speed + * @{ + */ +#define LL_GPIO_SPEED_FREQ_LOW (0x00000000U) /*!< Select I/O low output speed */ +#define LL_GPIO_SPEED_FREQ_MEDIUM \ + GPIO_OSPEEDR_OSPEEDR0_0 /*!< Select I/O medium output speed */ +#define LL_GPIO_SPEED_FREQ_HIGH \ + GPIO_OSPEEDR_OSPEEDR0 /*!< Select I/O high output speed */ +/** + * @} + */ +#define LL_GPIO_SPEED_LOW LL_GPIO_SPEED_FREQ_LOW +#define LL_GPIO_SPEED_MEDIUM LL_GPIO_SPEED_FREQ_MEDIUM +#define LL_GPIO_SPEED_HIGH LL_GPIO_SPEED_FREQ_HIGH + +/** @defgroup GPIO_LL_EC_PULL Pull Up Pull Down + * @{ + */ +#define LL_GPIO_PULL_NO (0x00000000U) /*!< Select I/O no pull */ +#define LL_GPIO_PULL_UP GPIO_PUPDR_PUPDR0_0 /*!< Select I/O pull up */ +#define LL_GPIO_PULL_DOWN GPIO_PUPDR_PUPDR0_1 /*!< Select I/O pull down */ +/** + * @} + */ + +/** @defgroup GPIO_LL_EC_AF Alternate Function + * @{ + */ +#define LL_GPIO_AF_0 (0x0000000U) /*!< Select alternate function 0 */ +#define LL_GPIO_AF_1 (0x0000001U) /*!< Select alternate function 1 */ +#define LL_GPIO_AF_2 (0x0000002U) /*!< Select alternate function 2 */ +#define LL_GPIO_AF_3 (0x0000003U) /*!< Select alternate function 3 */ +#define LL_GPIO_AF_4 (0x0000004U) /*!< Select alternate function 4 */ +#define LL_GPIO_AF_5 (0x0000005U) /*!< Select alternate function 5 */ +#define LL_GPIO_AF_6 (0x0000006U) /*!< Select alternate function 6 */ +#define LL_GPIO_AF_7 (0x0000007U) /*!< Select alternate function 7 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_LL_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** @defgroup GPIO_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in GPIO register + * @param __INSTANCE__ GPIO Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_GPIO_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in GPIO register + * @param __INSTANCE__ GPIO Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_GPIO_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup GPIO_LL_Exported_Functions GPIO Exported Functions + * @{ + */ + + /** @defgroup GPIO_LL_EF_Port_Configuration Port Configuration + * @{ + */ + + /** + * @brief Configure gpio mode for a dedicated pin on dedicated port. + * @note I/O mode can be Input mode, General purpose output, Alternate function mode + * or Analog. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll MODER MODEy LL_GPIO_SetPinMode + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_GPIO_MODE_INPUT + * @arg @ref LL_GPIO_MODE_OUTPUT + * @arg @ref LL_GPIO_MODE_ALTERNATE + * @arg @ref LL_GPIO_MODE_ANALOG + * @retval None + */ + __STATIC_INLINE void LL_GPIO_SetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin, + uint32_t Mode) + { + MODIFY_REG(GPIOx->MODER, ((Pin * Pin) * GPIO_MODER_MODER0), ((Pin * Pin) * Mode)); + } + + /** + * @brief Return gpio mode for a dedicated pin on dedicated port. + * @note I/O mode can be Input mode, General purpose output, Alternate function mode + * or Analog. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll MODER MODEy LL_GPIO_GetPinMode + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_MODE_INPUT + * @arg @ref LL_GPIO_MODE_OUTPUT + * @arg @ref LL_GPIO_MODE_ALTERNATE + * @arg @ref LL_GPIO_MODE_ANALOG + */ + __STATIC_INLINE uint32_t LL_GPIO_GetPinMode(GPIO_TypeDef *GPIOx, uint32_t Pin) + { + return (uint32_t)(READ_BIT(GPIOx->MODER, ((Pin * Pin) * GPIO_MODER_MODER0)) / + (Pin * Pin)); + } + + /** + * @brief Configure gpio output type for several pins on dedicated port. + * @note Output type as to be set when gpio pin is in output or + * alternate modes. Possible type are Push-pull or Open-drain. + * @rmtoll OTYPER OTy LL_GPIO_SetPinOutputType + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @param OutputType This parameter can be one of the following values: + * @arg @ref LL_GPIO_OUTPUT_PUSHPULL + * @arg @ref LL_GPIO_OUTPUT_OPENDRAIN + * @retval None + */ + __STATIC_INLINE void LL_GPIO_SetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t PinMask, + uint32_t OutputType) + { + MODIFY_REG(GPIOx->OTYPER, PinMask, (PinMask * OutputType)); + } + + /** + * @brief Return gpio output type for several pins on dedicated port. + * @note Output type as to be set when gpio pin is in output or + * alternate modes. Possible type are Push-pull or Open-drain. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll OTYPER OTy LL_GPIO_GetPinOutputType + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_OUTPUT_PUSHPULL + * @arg @ref LL_GPIO_OUTPUT_OPENDRAIN + */ + __STATIC_INLINE uint32_t LL_GPIO_GetPinOutputType(GPIO_TypeDef *GPIOx, uint32_t Pin) + { + return (uint32_t)(READ_BIT(GPIOx->OTYPER, Pin) / Pin); + } + + /** + * @brief Configure gpio speed for a dedicated pin on dedicated port. + * @note I/O speed can be Low, Medium, Fast or High speed. + * @note Warning: only one pin can be passed as parameter. + * @note Refer to datasheet for frequency specifications and the power + * supply and load conditions for each speed. + * @rmtoll OSPEEDR OSPEEDy LL_GPIO_SetPinSpeed + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param Speed This parameter can be one of the following values: + * @arg @ref LL_GPIO_SPEED_FREQ_LOW + * @arg @ref LL_GPIO_SPEED_FREQ_MEDIUM + * @arg @ref LL_GPIO_SPEED_FREQ_HIGH + * @retval None + */ + __STATIC_INLINE void LL_GPIO_SetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin, + uint32_t Speed) + { + MODIFY_REG(GPIOx->OSPEEDR, ((Pin * Pin) * GPIO_OSPEEDR_OSPEEDR0), + ((Pin * Pin) * Speed)); + } + + /** + * @brief Return gpio speed for a dedicated pin on dedicated port. + * @note I/O speed can be Low, Medium, Fast or High speed. + * @note Warning: only one pin can be passed as parameter. + * @note Refer to datasheet for frequency specifications and the power + * supply and load conditions for each speed. + * @rmtoll OSPEEDR OSPEEDy LL_GPIO_GetPinSpeed + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_SPEED_FREQ_LOW + * @arg @ref LL_GPIO_SPEED_FREQ_MEDIUM + * @arg @ref LL_GPIO_SPEED_FREQ_HIGH + */ + __STATIC_INLINE uint32_t LL_GPIO_GetPinSpeed(GPIO_TypeDef *GPIOx, uint32_t Pin) + { + return ( + uint32_t)(READ_BIT(GPIOx->OSPEEDR, ((Pin * Pin) * GPIO_OSPEEDR_OSPEEDR0)) / + (Pin * Pin)); + } + + /** + * @brief Configure gpio pull-up or pull-down for a dedicated pin on a dedicated + * port. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll PUPDR PUPDy LL_GPIO_SetPinPull + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param Pull This parameter can be one of the following values: + * @arg @ref LL_GPIO_PULL_NO + * @arg @ref LL_GPIO_PULL_UP + * @arg @ref LL_GPIO_PULL_DOWN + * @retval None + */ + __STATIC_INLINE void LL_GPIO_SetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin, + uint32_t Pull) + { + MODIFY_REG(GPIOx->PUPDR, ((Pin * Pin) * GPIO_PUPDR_PUPDR0), ((Pin * Pin) * Pull)); + } + + /** + * @brief Return gpio pull-up or pull-down for a dedicated pin on a dedicated port + * @note Warning: only one pin can be passed as parameter. + * @rmtoll PUPDR PUPDy LL_GPIO_GetPinPull + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_PULL_NO + * @arg @ref LL_GPIO_PULL_UP + * @arg @ref LL_GPIO_PULL_DOWN + */ + __STATIC_INLINE uint32_t LL_GPIO_GetPinPull(GPIO_TypeDef *GPIOx, uint32_t Pin) + { + return (uint32_t)(READ_BIT(GPIOx->PUPDR, ((Pin * Pin) * GPIO_PUPDR_PUPDR0)) / + (Pin * Pin)); + } + + /** + * @brief Configure gpio alternate function of a dedicated pin from 0 to 7 for a + * dedicated port. + * @note Possible values are from AF0 to AF7 depending on target. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll AFRL AFSELy LL_GPIO_SetAFPin_0_7 + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @param Alternate This parameter can be one of the following values: + * @arg @ref LL_GPIO_AF_0 + * @arg @ref LL_GPIO_AF_1 + * @arg @ref LL_GPIO_AF_2 + * @arg @ref LL_GPIO_AF_3 + * @arg @ref LL_GPIO_AF_4 + * @arg @ref LL_GPIO_AF_5 + * @arg @ref LL_GPIO_AF_6 + * @arg @ref LL_GPIO_AF_7 + * @retval None + */ + __STATIC_INLINE void LL_GPIO_SetAFPin_0_7(GPIO_TypeDef *GPIOx, uint32_t Pin, + uint32_t Alternate) + { + MODIFY_REG(GPIOx->AFR[0], ((((Pin * Pin) * Pin) * Pin) * GPIO_AFRL_AFSEL0), + ((((Pin * Pin) * Pin) * Pin) * Alternate)); + } + + /** + * @brief Return gpio alternate function of a dedicated pin from 0 to 7 for a + * dedicated port. + * @rmtoll AFRL AFSELy LL_GPIO_GetAFPin_0_7 + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_AF_0 + * @arg @ref LL_GPIO_AF_1 + * @arg @ref LL_GPIO_AF_2 + * @arg @ref LL_GPIO_AF_3 + * @arg @ref LL_GPIO_AF_4 + * @arg @ref LL_GPIO_AF_5 + * @arg @ref LL_GPIO_AF_6 + * @arg @ref LL_GPIO_AF_7 + */ + __STATIC_INLINE uint32_t LL_GPIO_GetAFPin_0_7(GPIO_TypeDef *GPIOx, uint32_t Pin) + { + return (uint32_t)(READ_BIT(GPIOx->AFR[0], + ((((Pin * Pin) * Pin) * Pin) * GPIO_AFRL_AFSEL0)) / + (((Pin * Pin) * Pin) * Pin)); + } + + /** + * @brief Configure gpio alternate function of a dedicated pin from 8 to 15 for a + * dedicated port. + * @note Possible values are from AF0 to AF7 depending on target. + * @note Warning: only one pin can be passed as parameter. + * @rmtoll AFRH AFSELy LL_GPIO_SetAFPin_8_15 + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @param Alternate This parameter can be one of the following values: + * @arg @ref LL_GPIO_AF_0 + * @arg @ref LL_GPIO_AF_1 + * @arg @ref LL_GPIO_AF_2 + * @arg @ref LL_GPIO_AF_3 + * @arg @ref LL_GPIO_AF_4 + * @arg @ref LL_GPIO_AF_5 + * @arg @ref LL_GPIO_AF_6 + * @arg @ref LL_GPIO_AF_7 + * @retval None + */ + __STATIC_INLINE void LL_GPIO_SetAFPin_8_15(GPIO_TypeDef *GPIOx, uint32_t Pin, + uint32_t Alternate) + { + MODIFY_REG( + GPIOx->AFR[1], + (((((Pin >> 8U) * (Pin >> 8U)) * (Pin >> 8U)) * (Pin >> 8U)) * + GPIO_AFRH_AFSEL8), + (((((Pin >> 8U) * (Pin >> 8U)) * (Pin >> 8U)) * (Pin >> 8U)) * Alternate)); + } + + /** + * @brief Return gpio alternate function of a dedicated pin from 8 to 15 for a + * dedicated port. + * @note Possible values are from AF0 to AF7 depending on target. + * @rmtoll AFRH AFSELy LL_GPIO_GetAFPin_8_15 + * @param GPIOx GPIO Port + * @param Pin This parameter can be one of the following values: + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_GPIO_AF_0 + * @arg @ref LL_GPIO_AF_1 + * @arg @ref LL_GPIO_AF_2 + * @arg @ref LL_GPIO_AF_3 + * @arg @ref LL_GPIO_AF_4 + * @arg @ref LL_GPIO_AF_5 + * @arg @ref LL_GPIO_AF_6 + * @arg @ref LL_GPIO_AF_7 + */ + __STATIC_INLINE uint32_t LL_GPIO_GetAFPin_8_15(GPIO_TypeDef *GPIOx, uint32_t Pin) + { + return (uint32_t)(READ_BIT(GPIOx->AFR[1], + (((((Pin >> 8U) * (Pin >> 8U)) * (Pin >> 8U)) * + (Pin >> 8U)) * + GPIO_AFRH_AFSEL8)) / + ((((Pin >> 8U) * (Pin >> 8U)) * (Pin >> 8U)) * (Pin >> 8U))); + } + + + /** + * @brief Lock configuration of several pins for a dedicated port. + * @note When the lock sequence has been applied on a port bit, the + * value of this port bit can no longer be modified until the + * next reset. + * @note Each lock bit freezes a specific configuration register + * (control and alternate function registers). + * @rmtoll LCKR LCKK LL_GPIO_LockPin + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ + __STATIC_INLINE void LL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) + { + __IO uint32_t temp; + WRITE_REG(GPIOx->LCKR, GPIO_LCKR_LCKK | PinMask); + WRITE_REG(GPIOx->LCKR, PinMask); + WRITE_REG(GPIOx->LCKR, GPIO_LCKR_LCKK | PinMask); + temp = READ_REG(GPIOx->LCKR); + (void)temp; + } + + /** + * @brief Return 1 if all pins passed as parameter, of a dedicated port, are locked. + * else Return 0. + * @rmtoll LCKR LCKy LL_GPIO_IsPinLocked + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_GPIO_IsPinLocked(GPIO_TypeDef *GPIOx, uint32_t PinMask) + { + return (READ_BIT(GPIOx->LCKR, PinMask) == (PinMask)); + } + + /** + * @brief Return 1 if one of the pin of a dedicated port is locked. else return 0. + * @rmtoll LCKR LCKK LL_GPIO_IsAnyPinLocked + * @param GPIOx GPIO Port + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_GPIO_IsAnyPinLocked(GPIO_TypeDef *GPIOx) + { + return (READ_BIT(GPIOx->LCKR, GPIO_LCKR_LCKK) == (GPIO_LCKR_LCKK)); + } + + /** + * @} + */ + + /** @defgroup GPIO_LL_EF_Data_Access Data Access + * @{ + */ + + /** + * @brief Return full input data register value for a dedicated port. + * @rmtoll IDR IDy LL_GPIO_ReadInputPort + * @param GPIOx GPIO Port + * @retval Input data register value of port + */ + __STATIC_INLINE uint32_t LL_GPIO_ReadInputPort(GPIO_TypeDef *GPIOx) + { + return (uint32_t)(READ_REG(GPIOx->IDR)); + } + + /** + * @brief Return if input data level for several pins of dedicated port is high or + * low. + * @rmtoll IDR IDy LL_GPIO_IsInputPinSet + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_GPIO_IsInputPinSet(GPIO_TypeDef *GPIOx, uint32_t PinMask) + { + return (READ_BIT(GPIOx->IDR, PinMask) == (PinMask)); + } + + /** + * @brief Write output data register for the port. + * @rmtoll ODR ODy LL_GPIO_WriteOutputPort + * @param GPIOx GPIO Port + * @param PortValue Level value for each pin of the port + * @retval None + */ + __STATIC_INLINE void LL_GPIO_WriteOutputPort(GPIO_TypeDef *GPIOx, uint32_t PortValue) + { + WRITE_REG(GPIOx->ODR, PortValue); + } + + /** + * @brief Return full output data register value for a dedicated port. + * @rmtoll ODR ODy LL_GPIO_ReadOutputPort + * @param GPIOx GPIO Port + * @retval Output data register value of port + */ + __STATIC_INLINE uint32_t LL_GPIO_ReadOutputPort(GPIO_TypeDef *GPIOx) + { + return (uint32_t)(READ_REG(GPIOx->ODR)); + } + + /** + * @brief Return if input data level for several pins of dedicated port is high or + * low. + * @rmtoll ODR ODy LL_GPIO_IsOutputPinSet + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_GPIO_IsOutputPinSet(GPIO_TypeDef *GPIOx, uint32_t PinMask) + { + return (READ_BIT(GPIOx->ODR, PinMask) == (PinMask)); + } + + /** + * @brief Set several pins to high level on dedicated gpio port. + * @rmtoll BSRR BSy LL_GPIO_SetOutputPin + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ + __STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) + { + WRITE_REG(GPIOx->BSRR, PinMask); + } + + /** + * @brief Set several pins to low level on dedicated gpio port. + * @rmtoll BRR BRy LL_GPIO_ResetOutputPin + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ + __STATIC_INLINE void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask) + { + WRITE_REG(GPIOx->BRR, PinMask); + } + + /** + * @brief Toggle data value for several pin of dedicated port. + * @rmtoll ODR ODy LL_GPIO_TogglePin + * @param GPIOx GPIO Port + * @param PinMask This parameter can be a combination of the following values: + * @arg @ref LL_GPIO_PIN_0 + * @arg @ref LL_GPIO_PIN_1 + * @arg @ref LL_GPIO_PIN_2 + * @arg @ref LL_GPIO_PIN_3 + * @arg @ref LL_GPIO_PIN_4 + * @arg @ref LL_GPIO_PIN_5 + * @arg @ref LL_GPIO_PIN_6 + * @arg @ref LL_GPIO_PIN_7 + * @arg @ref LL_GPIO_PIN_8 + * @arg @ref LL_GPIO_PIN_9 + * @arg @ref LL_GPIO_PIN_10 + * @arg @ref LL_GPIO_PIN_11 + * @arg @ref LL_GPIO_PIN_12 + * @arg @ref LL_GPIO_PIN_13 + * @arg @ref LL_GPIO_PIN_14 + * @arg @ref LL_GPIO_PIN_15 + * @arg @ref LL_GPIO_PIN_ALL + * @retval None + */ + __STATIC_INLINE void LL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint32_t PinMask) + { + uint32_t odr = READ_REG(GPIOx->ODR); + WRITE_REG(GPIOx->BSRR, ((odr & PinMask) << 16u) | (~odr & PinMask)); + } + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup GPIO_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx); + ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct); + void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* defined (GPIOA) || defined (GPIOB) || defined (GPIOC) || defined (GPIOD) || \ + defined (GPIOE) || defined (GPIOF) */ + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_GPIO_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_pwr.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_pwr.h new file mode 100644 index 0000000000..935c73824a --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_pwr.h @@ -0,0 +1,557 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_pwr.h + * @author MCD Application Team + * @brief Header file of PWR LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_PWR_H +#define __STM32F0xx_LL_PWR_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(PWR) + +/** @defgroup PWR_LL PWR + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PWR_LL_Exported_Constants PWR Exported Constants + * @{ + */ + +/** @defgroup PWR_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_PWR_WriteReg function + * @{ + */ +#define LL_PWR_CR_CSBF PWR_CR_CSBF /*!< Clear standby flag */ +#define LL_PWR_CR_CWUF PWR_CR_CWUF /*!< Clear wakeup flag */ +/** + * @} + */ + +/** @defgroup PWR_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_PWR_ReadReg function + * @{ + */ +#define LL_PWR_CSR_WUF PWR_CSR_WUF /*!< Wakeup flag */ +#define LL_PWR_CSR_SBF PWR_CSR_SBF /*!< Standby flag */ +#if defined(PWR_PVD_SUPPORT) +#define LL_PWR_CSR_PVDO PWR_CSR_PVDO /*!< Power voltage detector output flag */ +#endif /* PWR_PVD_SUPPORT */ +#if defined(PWR_CSR_VREFINTRDYF) +#define LL_PWR_CSR_VREFINTRDYF PWR_CSR_VREFINTRDYF /*!< VREFINT ready flag */ +#endif /* PWR_CSR_VREFINTRDYF */ +#define LL_PWR_CSR_EWUP1 PWR_CSR_EWUP1 /*!< Enable WKUP pin 1 */ +#define LL_PWR_CSR_EWUP2 PWR_CSR_EWUP2 /*!< Enable WKUP pin 2 */ +#if defined(PWR_CSR_EWUP3) +#define LL_PWR_CSR_EWUP3 PWR_CSR_EWUP3 /*!< Enable WKUP pin 3 */ +#endif /* PWR_CSR_EWUP3 */ +#if defined(PWR_CSR_EWUP4) +#define LL_PWR_CSR_EWUP4 PWR_CSR_EWUP4 /*!< Enable WKUP pin 4 */ +#endif /* PWR_CSR_EWUP4 */ +#if defined(PWR_CSR_EWUP5) +#define LL_PWR_CSR_EWUP5 PWR_CSR_EWUP5 /*!< Enable WKUP pin 5 */ +#endif /* PWR_CSR_EWUP5 */ +#if defined(PWR_CSR_EWUP6) +#define LL_PWR_CSR_EWUP6 PWR_CSR_EWUP6 /*!< Enable WKUP pin 6 */ +#endif /* PWR_CSR_EWUP6 */ +#if defined(PWR_CSR_EWUP7) +#define LL_PWR_CSR_EWUP7 PWR_CSR_EWUP7 /*!< Enable WKUP pin 7 */ +#endif /* PWR_CSR_EWUP7 */ +#if defined(PWR_CSR_EWUP8) +#define LL_PWR_CSR_EWUP8 PWR_CSR_EWUP8 /*!< Enable WKUP pin 8 */ +#endif /* PWR_CSR_EWUP8 */ +/** + * @} + */ + + +/** @defgroup PWR_LL_EC_MODE_PWR Mode Power + * @{ + */ +#define LL_PWR_MODE_STOP_MAINREGU \ + 0x00000000U /*!< Enter Stop mode when the CPU enters deepsleep */ +#define LL_PWR_MODE_STOP_LPREGU \ + (PWR_CR_LPDS) /*!< Enter Stop mode (with low power Regulator ON) when the CPU enters \ + deepsleep */ +#define LL_PWR_MODE_STANDBY \ + (PWR_CR_PDDS) /*!< Enter Standby mode when the CPU enters deepsleep */ + /** + * @} + */ + +#if defined(PWR_CR_LPDS) +/** @defgroup PWR_LL_EC_REGU_MODE_DS_MODE Regulator Mode In Deep Sleep Mode + * @{ + */ +#define LL_PWR_REGU_DSMODE_MAIN \ + 0x00000000U /*!< Voltage Regulator in main mode during deepsleep mode */ +#define LL_PWR_REGU_DSMODE_LOW_POWER \ + (PWR_CR_LPDS) /*!< Voltage Regulator in low-power mode during deepsleep mode */ +/** + * @} + */ +#endif /* PWR_CR_LPDS */ + +#if defined(PWR_PVD_SUPPORT) +/** @defgroup PWR_LL_EC_PVDLEVEL Power Voltage Detector Level + * @{ + */ +#define LL_PWR_PVDLEVEL_0 (PWR_CR_PLS_LEV0) /*!< Voltage threshold 0 */ +#define LL_PWR_PVDLEVEL_1 (PWR_CR_PLS_LEV1) /*!< Voltage threshold 1 */ +#define LL_PWR_PVDLEVEL_2 (PWR_CR_PLS_LEV2) /*!< Voltage threshold 2 */ +#define LL_PWR_PVDLEVEL_3 (PWR_CR_PLS_LEV3) /*!< Voltage threshold 3 */ +#define LL_PWR_PVDLEVEL_4 (PWR_CR_PLS_LEV4) /*!< Voltage threshold 4 */ +#define LL_PWR_PVDLEVEL_5 (PWR_CR_PLS_LEV5) /*!< Voltage threshold 5 */ +#define LL_PWR_PVDLEVEL_6 (PWR_CR_PLS_LEV6) /*!< Voltage threshold 6 */ +#define LL_PWR_PVDLEVEL_7 (PWR_CR_PLS_LEV7) /*!< Voltage threshold 7 */ +/** + * @} + */ +#endif /* PWR_PVD_SUPPORT */ +/** @defgroup PWR_LL_EC_WAKEUP_PIN Wakeup Pins + * @{ + */ +#define LL_PWR_WAKEUP_PIN1 (PWR_CSR_EWUP1) /*!< WKUP pin 1 : PA0 */ +#define LL_PWR_WAKEUP_PIN2 (PWR_CSR_EWUP2) /*!< WKUP pin 2 : PC13 */ +#if defined(PWR_CSR_EWUP3) +#define LL_PWR_WAKEUP_PIN3 \ + (PWR_CSR_EWUP3) /*!< WKUP pin 3 : PE6 or PA2 according to device */ +#endif /* PWR_CSR_EWUP3 */ +#if defined(PWR_CSR_EWUP4) +#define LL_PWR_WAKEUP_PIN4 (PWR_CSR_EWUP4) /*!< WKUP pin 4 : PA2 */ +#endif /* PWR_CSR_EWUP4 */ +#if defined(PWR_CSR_EWUP5) +#define LL_PWR_WAKEUP_PIN5 (PWR_CSR_EWUP5) /*!< WKUP pin 5 : PC5 */ +#endif /* PWR_CSR_EWUP5 */ +#if defined(PWR_CSR_EWUP6) +#define LL_PWR_WAKEUP_PIN6 (PWR_CSR_EWUP6) /*!< WKUP pin 6 : PB5 */ +#endif /* PWR_CSR_EWUP6 */ +#if defined(PWR_CSR_EWUP7) +#define LL_PWR_WAKEUP_PIN7 (PWR_CSR_EWUP7) /*!< WKUP pin 7 : PB15 */ +#endif /* PWR_CSR_EWUP7 */ +#if defined(PWR_CSR_EWUP8) +#define LL_PWR_WAKEUP_PIN8 (PWR_CSR_EWUP8) /*!< WKUP pin 8 : PF2 */ +#endif /* PWR_CSR_EWUP8 */ +/** + * @} + */ + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWR_LL_Exported_Macros PWR Exported Macros + * @{ + */ + +/** @defgroup PWR_LL_EM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in PWR register + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_PWR_WriteReg(__REG__, __VALUE__) WRITE_REG(PWR->__REG__, (__VALUE__)) + +/** + * @brief Read a value in PWR register + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_PWR_ReadReg(__REG__) READ_REG(PWR->__REG__) + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup PWR_LL_Exported_Functions PWR Exported Functions + * @{ + */ + + /** @defgroup PWR_LL_EF_Configuration Configuration + * @{ + */ + + /** + * @brief Enable access to the backup domain + * @rmtoll CR DBP LL_PWR_EnableBkUpAccess + * @retval None + */ + __STATIC_INLINE void LL_PWR_EnableBkUpAccess(void) + { + SET_BIT(PWR->CR, PWR_CR_DBP); + } + + /** + * @brief Disable access to the backup domain + * @rmtoll CR DBP LL_PWR_DisableBkUpAccess + * @retval None + */ + __STATIC_INLINE void LL_PWR_DisableBkUpAccess(void) + { + CLEAR_BIT(PWR->CR, PWR_CR_DBP); + } + + /** + * @brief Check if the backup domain is enabled + * @rmtoll CR DBP LL_PWR_IsEnabledBkUpAccess + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_PWR_IsEnabledBkUpAccess(void) + { + return (READ_BIT(PWR->CR, PWR_CR_DBP) == (PWR_CR_DBP)); + } + +#if defined(PWR_CR_LPDS) + /** + * @brief Set voltage Regulator mode during deep sleep mode + * @rmtoll CR LPDS LL_PWR_SetRegulModeDS + * @param RegulMode This parameter can be one of the following values: + * @arg @ref LL_PWR_REGU_DSMODE_MAIN + * @arg @ref LL_PWR_REGU_DSMODE_LOW_POWER + * @retval None + */ + __STATIC_INLINE void LL_PWR_SetRegulModeDS(uint32_t RegulMode) + { + MODIFY_REG(PWR->CR, PWR_CR_LPDS, RegulMode); + } + + /** + * @brief Get voltage Regulator mode during deep sleep mode + * @rmtoll CR LPDS LL_PWR_GetRegulModeDS + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_REGU_DSMODE_MAIN + * @arg @ref LL_PWR_REGU_DSMODE_LOW_POWER + */ + __STATIC_INLINE uint32_t LL_PWR_GetRegulModeDS(void) + { + return (uint32_t)(READ_BIT(PWR->CR, PWR_CR_LPDS)); + } +#endif /* PWR_CR_LPDS */ + + /** + * @brief Set Power Down mode when CPU enters deepsleep + * @rmtoll CR PDDS LL_PWR_SetPowerMode\n + * @rmtoll CR LPDS LL_PWR_SetPowerMode + * @param PDMode This parameter can be one of the following values: + * @arg @ref LL_PWR_MODE_STOP_MAINREGU + * @arg @ref LL_PWR_MODE_STOP_LPREGU + * @arg @ref LL_PWR_MODE_STANDBY + * @retval None + */ + __STATIC_INLINE void LL_PWR_SetPowerMode(uint32_t PDMode) + { + MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPDS), PDMode); + } + + /** + * @brief Get Power Down mode when CPU enters deepsleep + * @rmtoll CR PDDS LL_PWR_GetPowerMode\n + * @rmtoll CR LPDS LL_PWR_GetPowerMode + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_MODE_STOP_MAINREGU + * @arg @ref LL_PWR_MODE_STOP_LPREGU + * @arg @ref LL_PWR_MODE_STANDBY + */ + __STATIC_INLINE uint32_t LL_PWR_GetPowerMode(void) + { + return (uint32_t)(READ_BIT(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPDS))); + } + +#if defined(PWR_PVD_SUPPORT) + /** + * @brief Configure the voltage threshold detected by the Power Voltage Detector + * @rmtoll CR PLS LL_PWR_SetPVDLevel + * @param PVDLevel This parameter can be one of the following values: + * @arg @ref LL_PWR_PVDLEVEL_0 + * @arg @ref LL_PWR_PVDLEVEL_1 + * @arg @ref LL_PWR_PVDLEVEL_2 + * @arg @ref LL_PWR_PVDLEVEL_3 + * @arg @ref LL_PWR_PVDLEVEL_4 + * @arg @ref LL_PWR_PVDLEVEL_5 + * @arg @ref LL_PWR_PVDLEVEL_6 + * @arg @ref LL_PWR_PVDLEVEL_7 + * @retval None + */ + __STATIC_INLINE void LL_PWR_SetPVDLevel(uint32_t PVDLevel) + { + MODIFY_REG(PWR->CR, PWR_CR_PLS, PVDLevel); + } + + /** + * @brief Get the voltage threshold detection + * @rmtoll CR PLS LL_PWR_GetPVDLevel + * @retval Returned value can be one of the following values: + * @arg @ref LL_PWR_PVDLEVEL_0 + * @arg @ref LL_PWR_PVDLEVEL_1 + * @arg @ref LL_PWR_PVDLEVEL_2 + * @arg @ref LL_PWR_PVDLEVEL_3 + * @arg @ref LL_PWR_PVDLEVEL_4 + * @arg @ref LL_PWR_PVDLEVEL_5 + * @arg @ref LL_PWR_PVDLEVEL_6 + * @arg @ref LL_PWR_PVDLEVEL_7 + */ + __STATIC_INLINE uint32_t LL_PWR_GetPVDLevel(void) + { + return (uint32_t)(READ_BIT(PWR->CR, PWR_CR_PLS)); + } + + /** + * @brief Enable Power Voltage Detector + * @rmtoll CR PVDE LL_PWR_EnablePVD + * @retval None + */ + __STATIC_INLINE void LL_PWR_EnablePVD(void) + { + SET_BIT(PWR->CR, PWR_CR_PVDE); + } + + /** + * @brief Disable Power Voltage Detector + * @rmtoll CR PVDE LL_PWR_DisablePVD + * @retval None + */ + __STATIC_INLINE void LL_PWR_DisablePVD(void) + { + CLEAR_BIT(PWR->CR, PWR_CR_PVDE); + } + + /** + * @brief Check if Power Voltage Detector is enabled + * @rmtoll CR PVDE LL_PWR_IsEnabledPVD + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_PWR_IsEnabledPVD(void) + { + return (READ_BIT(PWR->CR, PWR_CR_PVDE) == (PWR_CR_PVDE)); + } +#endif /* PWR_PVD_SUPPORT */ + + /** + * @brief Enable the WakeUp PINx functionality + * @rmtoll CSR EWUP1 LL_PWR_EnableWakeUpPin\n + * @rmtoll CSR EWUP2 LL_PWR_EnableWakeUpPin\n + * @rmtoll CSR EWUP3 LL_PWR_EnableWakeUpPin\n + * @rmtoll CSR EWUP4 LL_PWR_EnableWakeUpPin\n + * @rmtoll CSR EWUP5 LL_PWR_EnableWakeUpPin\n + * @rmtoll CSR EWUP6 LL_PWR_EnableWakeUpPin\n + * @rmtoll CSR EWUP7 LL_PWR_EnableWakeUpPin\n + * @rmtoll CSR EWUP8 LL_PWR_EnableWakeUpPin + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 (*) + * @arg @ref LL_PWR_WAKEUP_PIN4 (*) + * @arg @ref LL_PWR_WAKEUP_PIN5 (*) + * @arg @ref LL_PWR_WAKEUP_PIN6 (*) + * @arg @ref LL_PWR_WAKEUP_PIN7 (*) + * @arg @ref LL_PWR_WAKEUP_PIN8 (*) + * + * (*) not available on all devices + * @retval None + */ + __STATIC_INLINE void LL_PWR_EnableWakeUpPin(uint32_t WakeUpPin) + { + SET_BIT(PWR->CSR, WakeUpPin); + } + + /** + * @brief Disable the WakeUp PINx functionality + * @rmtoll CSR EWUP1 LL_PWR_DisableWakeUpPin\n + * @rmtoll CSR EWUP2 LL_PWR_DisableWakeUpPin\n + * @rmtoll CSR EWUP3 LL_PWR_DisableWakeUpPin\n + * @rmtoll CSR EWUP4 LL_PWR_DisableWakeUpPin\n + * @rmtoll CSR EWUP5 LL_PWR_DisableWakeUpPin\n + * @rmtoll CSR EWUP6 LL_PWR_DisableWakeUpPin\n + * @rmtoll CSR EWUP7 LL_PWR_DisableWakeUpPin\n + * @rmtoll CSR EWUP8 LL_PWR_DisableWakeUpPin + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 (*) + * @arg @ref LL_PWR_WAKEUP_PIN4 (*) + * @arg @ref LL_PWR_WAKEUP_PIN5 (*) + * @arg @ref LL_PWR_WAKEUP_PIN6 (*) + * @arg @ref LL_PWR_WAKEUP_PIN7 (*) + * @arg @ref LL_PWR_WAKEUP_PIN8 (*) + * + * (*) not available on all devices + * @retval None + */ + __STATIC_INLINE void LL_PWR_DisableWakeUpPin(uint32_t WakeUpPin) + { + CLEAR_BIT(PWR->CSR, WakeUpPin); + } + + /** + * @brief Check if the WakeUp PINx functionality is enabled + * @rmtoll CSR EWUP1 LL_PWR_IsEnabledWakeUpPin\n + * @rmtoll CSR EWUP2 LL_PWR_IsEnabledWakeUpPin\n + * @rmtoll CSR EWUP3 LL_PWR_IsEnabledWakeUpPin\n + * @rmtoll CSR EWUP4 LL_PWR_IsEnabledWakeUpPin\n + * @rmtoll CSR EWUP5 LL_PWR_IsEnabledWakeUpPin\n + * @rmtoll CSR EWUP6 LL_PWR_IsEnabledWakeUpPin\n + * @rmtoll CSR EWUP7 LL_PWR_IsEnabledWakeUpPin\n + * @rmtoll CSR EWUP8 LL_PWR_IsEnabledWakeUpPin + * @param WakeUpPin This parameter can be one of the following values: + * @arg @ref LL_PWR_WAKEUP_PIN1 + * @arg @ref LL_PWR_WAKEUP_PIN2 + * @arg @ref LL_PWR_WAKEUP_PIN3 (*) + * @arg @ref LL_PWR_WAKEUP_PIN4 (*) + * @arg @ref LL_PWR_WAKEUP_PIN5 (*) + * @arg @ref LL_PWR_WAKEUP_PIN6 (*) + * @arg @ref LL_PWR_WAKEUP_PIN7 (*) + * @arg @ref LL_PWR_WAKEUP_PIN8 (*) + * + * (*) not available on all devices + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_PWR_IsEnabledWakeUpPin(uint32_t WakeUpPin) + { + return (READ_BIT(PWR->CSR, WakeUpPin) == (WakeUpPin)); + } + + + /** + * @} + */ + + /** @defgroup PWR_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + + /** + * @brief Get Wake-up Flag + * @rmtoll CSR WUF LL_PWR_IsActiveFlag_WU + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_WU(void) + { + return (READ_BIT(PWR->CSR, PWR_CSR_WUF) == (PWR_CSR_WUF)); + } + + /** + * @brief Get Standby Flag + * @rmtoll CSR SBF LL_PWR_IsActiveFlag_SB + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_SB(void) + { + return (READ_BIT(PWR->CSR, PWR_CSR_SBF) == (PWR_CSR_SBF)); + } + +#if defined(PWR_PVD_SUPPORT) + /** + * @brief Indicate whether VDD voltage is below the selected PVD threshold + * @rmtoll CSR PVDO LL_PWR_IsActiveFlag_PVDO + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_PVDO(void) + { + return (READ_BIT(PWR->CSR, PWR_CSR_PVDO) == (PWR_CSR_PVDO)); + } +#endif /* PWR_PVD_SUPPORT */ + +#if defined(PWR_CSR_VREFINTRDYF) + /** + * @brief Get Internal Reference VrefInt Flag + * @rmtoll CSR VREFINTRDYF LL_PWR_IsActiveFlag_VREFINTRDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_PWR_IsActiveFlag_VREFINTRDY(void) + { + return (READ_BIT(PWR->CSR, PWR_CSR_VREFINTRDYF) == (PWR_CSR_VREFINTRDYF)); + } +#endif /* PWR_CSR_VREFINTRDYF */ + /** + * @brief Clear Standby Flag + * @rmtoll CR CSBF LL_PWR_ClearFlag_SB + * @retval None + */ + __STATIC_INLINE void LL_PWR_ClearFlag_SB(void) + { + SET_BIT(PWR->CR, PWR_CR_CSBF); + } + + /** + * @brief Clear Wake-up Flags + * @rmtoll CR CWUF LL_PWR_ClearFlag_WU + * @retval None + */ + __STATIC_INLINE void LL_PWR_ClearFlag_WU(void) + { + SET_BIT(PWR->CR, PWR_CR_CWUF); + } + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup PWR_LL_EF_Init De-initialization function + * @{ + */ + ErrorStatus LL_PWR_DeInit(void); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* defined(PWR) */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_PWR_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_rcc.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_rcc.h new file mode 100644 index 0000000000..92607830a5 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_rcc.h @@ -0,0 +1,2401 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_rcc.h + * @author MCD Application Team + * @brief Header file of RCC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file in + * the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_RCC_H +#define __STM32F0xx_LL_RCC_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(RCC) + +/** @defgroup RCC_LL RCC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RCC_LL_Private_Constants RCC Private Constants + * @{ + */ +/* Defines used for the bit position in the register and perform offsets*/ +#define RCC_POSITION_HPRE (uint32_t)4U /*!< field position in register RCC_CFGR */ +#define RCC_POSITION_PPRE1 (uint32_t)8U /*!< field position in register RCC_CFGR */ +#define RCC_POSITION_PLLMUL (uint32_t)18U /*!< field position in register RCC_CFGR */ +#define RCC_POSITION_HSICAL (uint32_t)8U /*!< field position in register RCC_CR */ +#define RCC_POSITION_HSITRIM (uint32_t)3U /*!< field position in register RCC_CR */ +#define RCC_POSITION_HSI14TRIM (uint32_t)3U /*!< field position in register RCC_CR2 */ +#define RCC_POSITION_HSI14CAL (uint32_t)8U /*!< field position in register RCC_CR2 */ +#if defined(RCC_HSI48_SUPPORT) +#define RCC_POSITION_HSI48CAL (uint32_t)24U /*!< field position in register RCC_CR2 */ +#endif /* RCC_HSI48_SUPPORT */ +#define RCC_POSITION_USART1SW (uint32_t)0U /*!< field position in register RCC_CFGR3 */ +#define RCC_POSITION_USART2SW (uint32_t)16U /*!< field position in register RCC_CFGR3 */ +#define RCC_POSITION_USART3SW (uint32_t)18U /*!< field position in register RCC_CFGR3 */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RCC_LL_Private_Macros RCC Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup RCC_LL_Exported_Types RCC Exported Types + * @{ + */ + + /** @defgroup LL_ES_CLOCK_FREQ Clocks Frequency Structure + * @{ + */ + + /** + * @brief RCC Clocks Frequency Structure + */ + typedef struct + { + uint32_t SYSCLK_Frequency; /*!< SYSCLK clock frequency */ + uint32_t HCLK_Frequency; /*!< HCLK clock frequency */ + uint32_t PCLK1_Frequency; /*!< PCLK1 clock frequency */ + } LL_RCC_ClocksTypeDef; + +/** + * @} + */ + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RCC_LL_Exported_Constants RCC Exported Constants + * @{ + */ + +/** @defgroup RCC_LL_EC_OSC_VALUES Oscillator Values adaptation + * @brief Defines used to adapt values of different oscillators + * @note These values could be modified in the user environment according to + * HW set-up. + * @{ + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE 8000000U /*!< Value of the HSE oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSI_VALUE) +#define HSI_VALUE 8000000U /*!< Value of the HSI oscillator in Hz */ +#endif /* HSI_VALUE */ + +#if !defined(LSE_VALUE) +#define LSE_VALUE 32768U /*!< Value of the LSE oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined(LSI_VALUE) +#define LSI_VALUE 32000U /*!< Value of the LSI oscillator in Hz */ +#endif /* LSI_VALUE */ +#if defined(RCC_HSI48_SUPPORT) + +#if !defined(HSI48_VALUE) +#define HSI48_VALUE 48000000U /*!< Value of the HSI48 oscillator in Hz */ +#endif /* HSI48_VALUE */ +#endif /* RCC_HSI48_SUPPORT */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_RCC_WriteReg function + * @{ + */ +#define LL_RCC_CIR_LSIRDYC RCC_CIR_LSIRDYC /*!< LSI Ready Interrupt Clear */ +#define LL_RCC_CIR_LSERDYC RCC_CIR_LSERDYC /*!< LSE Ready Interrupt Clear */ +#define LL_RCC_CIR_HSIRDYC RCC_CIR_HSIRDYC /*!< HSI Ready Interrupt Clear */ +#define LL_RCC_CIR_HSERDYC RCC_CIR_HSERDYC /*!< HSE Ready Interrupt Clear */ +#define LL_RCC_CIR_PLLRDYC RCC_CIR_PLLRDYC /*!< PLL Ready Interrupt Clear */ +#define LL_RCC_CIR_HSI14RDYC RCC_CIR_HSI14RDYC /*!< HSI14 Ready Interrupt Clear */ +#if defined(RCC_HSI48_SUPPORT) +#define LL_RCC_CIR_HSI48RDYC RCC_CIR_HSI48RDYC /*!< HSI48 Ready Interrupt Clear */ +#endif /* RCC_HSI48_SUPPORT */ +#define LL_RCC_CIR_CSSC RCC_CIR_CSSC /*!< Clock Security System Interrupt Clear */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_RCC_ReadReg function + * @{ + */ +#define LL_RCC_CIR_LSIRDYF RCC_CIR_LSIRDYF /*!< LSI Ready Interrupt flag */ +#define LL_RCC_CIR_LSERDYF RCC_CIR_LSERDYF /*!< LSE Ready Interrupt flag */ +#define LL_RCC_CIR_HSIRDYF RCC_CIR_HSIRDYF /*!< HSI Ready Interrupt flag */ +#define LL_RCC_CIR_HSERDYF RCC_CIR_HSERDYF /*!< HSE Ready Interrupt flag */ +#define LL_RCC_CIR_PLLRDYF RCC_CIR_PLLRDYF /*!< PLL Ready Interrupt flag */ +#define LL_RCC_CIR_HSI14RDYF RCC_CIR_HSI14RDYF /*!< HSI14 Ready Interrupt flag */ +#if defined(RCC_HSI48_SUPPORT) +#define LL_RCC_CIR_HSI48RDYF RCC_CIR_HSI48RDYF /*!< HSI48 Ready Interrupt flag */ +#endif /* RCC_HSI48_SUPPORT */ +#define LL_RCC_CIR_CSSF RCC_CIR_CSSF /*!< Clock Security System Interrupt flag */ +#define LL_RCC_CSR_OBLRSTF RCC_CSR_OBLRSTF /*!< OBL reset flag */ +#define LL_RCC_CSR_PINRSTF RCC_CSR_PINRSTF /*!< PIN reset flag */ +#define LL_RCC_CSR_PORRSTF RCC_CSR_PORRSTF /*!< POR/PDR reset flag */ +#define LL_RCC_CSR_SFTRSTF RCC_CSR_SFTRSTF /*!< Software Reset flag */ +#define LL_RCC_CSR_IWDGRSTF RCC_CSR_IWDGRSTF /*!< Independent Watchdog reset flag */ +#define LL_RCC_CSR_WWDGRSTF RCC_CSR_WWDGRSTF /*!< Window watchdog reset flag */ +#define LL_RCC_CSR_LPWRRSTF RCC_CSR_LPWRRSTF /*!< Low-Power reset flag */ +#if defined(RCC_CSR_V18PWRRSTF) +#define LL_RCC_CSR_V18PWRRSTF RCC_CSR_V18PWRRSTF /*!< Reset flag of the 1.8 V domain. */ +#endif /* RCC_CSR_V18PWRRSTF */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_RCC_ReadReg and LL_RCC_WriteReg + * functions + * @{ + */ +#define LL_RCC_CIR_LSIRDYIE RCC_CIR_LSIRDYIE /*!< LSI Ready Interrupt Enable */ +#define LL_RCC_CIR_LSERDYIE RCC_CIR_LSERDYIE /*!< LSE Ready Interrupt Enable */ +#define LL_RCC_CIR_HSIRDYIE RCC_CIR_HSIRDYIE /*!< HSI Ready Interrupt Enable */ +#define LL_RCC_CIR_HSERDYIE RCC_CIR_HSERDYIE /*!< HSE Ready Interrupt Enable */ +#define LL_RCC_CIR_PLLRDYIE RCC_CIR_PLLRDYIE /*!< PLL Ready Interrupt Enable */ +#define LL_RCC_CIR_HSI14RDYIE RCC_CIR_HSI14RDYIE /*!< HSI14 Ready Interrupt Enable */ +#if defined(RCC_HSI48_SUPPORT) +#define LL_RCC_CIR_HSI48RDYIE RCC_CIR_HSI48RDYIE /*!< HSI48 Ready Interrupt Enable */ +#endif /* RCC_HSI48_SUPPORT */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_LSEDRIVE LSE oscillator drive capability + * @{ + */ +#define LL_RCC_LSEDRIVE_LOW \ + ((uint32_t)0x00000000U) /*!< Xtal mode lower driving capability */ +#define LL_RCC_LSEDRIVE_MEDIUMLOW \ + RCC_BDCR_LSEDRV_1 /*!< Xtal mode medium low driving capability */ +#define LL_RCC_LSEDRIVE_MEDIUMHIGH \ + RCC_BDCR_LSEDRV_0 /*!< Xtal mode medium high driving capability */ +#define LL_RCC_LSEDRIVE_HIGH RCC_BDCR_LSEDRV /*!< Xtal mode higher driving capability */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYS_CLKSOURCE System clock switch + * @{ + */ +#define LL_RCC_SYS_CLKSOURCE_HSI RCC_CFGR_SW_HSI /*!< HSI selection as system clock */ +#define LL_RCC_SYS_CLKSOURCE_HSE RCC_CFGR_SW_HSE /*!< HSE selection as system clock */ +#define LL_RCC_SYS_CLKSOURCE_PLL RCC_CFGR_SW_PLL /*!< PLL selection as system clock */ +#if defined(RCC_CFGR_SW_HSI48) +#define LL_RCC_SYS_CLKSOURCE_HSI48 \ + RCC_CFGR_SW_HSI48 /*!< HSI48 selection as system clock */ +#endif /* RCC_CFGR_SW_HSI48 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYS_CLKSOURCE_STATUS System clock switch status + * @{ + */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_HSI \ + RCC_CFGR_SWS_HSI /*!< HSI used as system clock \ + */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_HSE \ + RCC_CFGR_SWS_HSE /*!< HSE used as system clock \ + */ +#define LL_RCC_SYS_CLKSOURCE_STATUS_PLL \ + RCC_CFGR_SWS_PLL /*!< PLL used as system clock \ + */ +#if defined(RCC_CFGR_SWS_HSI48) +#define LL_RCC_SYS_CLKSOURCE_STATUS_HSI48 \ + RCC_CFGR_SWS_HSI48 /*!< HSI48 used as system clock */ +#endif /* RCC_CFGR_SWS_HSI48 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_SYSCLK_DIV AHB prescaler + * @{ + */ +#define LL_RCC_SYSCLK_DIV_1 RCC_CFGR_HPRE_DIV1 /*!< SYSCLK not divided */ +#define LL_RCC_SYSCLK_DIV_2 RCC_CFGR_HPRE_DIV2 /*!< SYSCLK divided by 2 */ +#define LL_RCC_SYSCLK_DIV_4 RCC_CFGR_HPRE_DIV4 /*!< SYSCLK divided by 4 */ +#define LL_RCC_SYSCLK_DIV_8 RCC_CFGR_HPRE_DIV8 /*!< SYSCLK divided by 8 */ +#define LL_RCC_SYSCLK_DIV_16 RCC_CFGR_HPRE_DIV16 /*!< SYSCLK divided by 16 */ +#define LL_RCC_SYSCLK_DIV_64 RCC_CFGR_HPRE_DIV64 /*!< SYSCLK divided by 64 */ +#define LL_RCC_SYSCLK_DIV_128 RCC_CFGR_HPRE_DIV128 /*!< SYSCLK divided by 128 */ +#define LL_RCC_SYSCLK_DIV_256 RCC_CFGR_HPRE_DIV256 /*!< SYSCLK divided by 256 */ +#define LL_RCC_SYSCLK_DIV_512 RCC_CFGR_HPRE_DIV512 /*!< SYSCLK divided by 512 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_APB1_DIV APB low-speed prescaler (APB1) + * @{ + */ +#define LL_RCC_APB1_DIV_1 RCC_CFGR_PPRE_DIV1 /*!< HCLK not divided */ +#define LL_RCC_APB1_DIV_2 RCC_CFGR_PPRE_DIV2 /*!< HCLK divided by 2 */ +#define LL_RCC_APB1_DIV_4 RCC_CFGR_PPRE_DIV4 /*!< HCLK divided by 4 */ +#define LL_RCC_APB1_DIV_8 RCC_CFGR_PPRE_DIV8 /*!< HCLK divided by 8 */ +#define LL_RCC_APB1_DIV_16 RCC_CFGR_PPRE_DIV16 /*!< HCLK divided by 16 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_MCO1SOURCE MCO1 SOURCE selection + * @{ + */ +#define LL_RCC_MCO1SOURCE_NOCLOCK \ + RCC_CFGR_MCOSEL_NOCLOCK /*!< MCO output disabled, no clock on MCO */ +#define LL_RCC_MCO1SOURCE_HSI14 \ + RCC_CFGR_MCOSEL_HSI14 /*!< HSI14 oscillator clock selected */ +#define LL_RCC_MCO1SOURCE_SYSCLK \ + RCC_CFGR_MCOSEL_SYSCLK /*!< SYSCLK selection as MCO source */ +#define LL_RCC_MCO1SOURCE_HSI RCC_CFGR_MCOSEL_HSI /*!< HSI selection as MCO source */ +#define LL_RCC_MCO1SOURCE_HSE RCC_CFGR_MCOSEL_HSE /*!< HSE selection as MCO source */ +#define LL_RCC_MCO1SOURCE_LSI RCC_CFGR_MCOSEL_LSI /*!< LSI selection as MCO source */ +#define LL_RCC_MCO1SOURCE_LSE RCC_CFGR_MCOSEL_LSE /*!< LSE selection as MCO source */ +#if defined(RCC_CFGR_MCOSEL_HSI48) +#define LL_RCC_MCO1SOURCE_HSI48 \ + RCC_CFGR_MCOSEL_HSI48 /*!< HSI48 selection as MCO source */ +#endif /* RCC_CFGR_MCOSEL_HSI48 */ +#define LL_RCC_MCO1SOURCE_PLLCLK_DIV_2 \ + RCC_CFGR_MCOSEL_PLL_DIV2 /*!< PLL clock divided by 2*/ +#if defined(RCC_CFGR_PLLNODIV) +#define LL_RCC_MCO1SOURCE_PLLCLK \ + (RCC_CFGR_MCOSEL_PLL_DIV2 | RCC_CFGR_PLLNODIV) /*!< PLL clock selected*/ +#endif /* RCC_CFGR_PLLNODIV */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_MCO1_DIV MCO1 prescaler + * @{ + */ +#define LL_RCC_MCO1_DIV_1 ((uint32_t)0x00000000U) /*!< MCO Clock divided by 1 */ +#if defined(RCC_CFGR_MCOPRE) +#define LL_RCC_MCO1_DIV_2 RCC_CFGR_MCOPRE_DIV2 /*!< MCO Clock divided by 2 */ +#define LL_RCC_MCO1_DIV_4 RCC_CFGR_MCOPRE_DIV4 /*!< MCO Clock divided by 4 */ +#define LL_RCC_MCO1_DIV_8 RCC_CFGR_MCOPRE_DIV8 /*!< MCO Clock divided by 8 */ +#define LL_RCC_MCO1_DIV_16 RCC_CFGR_MCOPRE_DIV16 /*!< MCO Clock divided by 16 */ +#define LL_RCC_MCO1_DIV_32 RCC_CFGR_MCOPRE_DIV32 /*!< MCO Clock divided by 32 */ +#define LL_RCC_MCO1_DIV_64 RCC_CFGR_MCOPRE_DIV64 /*!< MCO Clock divided by 64 */ +#define LL_RCC_MCO1_DIV_128 RCC_CFGR_MCOPRE_DIV128 /*!< MCO Clock divided by 128 */ +#endif /* RCC_CFGR_MCOPRE */ + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup RCC_LL_EC_PERIPH_FREQUENCY Peripheral clock frequency + * @{ + */ +#define LL_RCC_PERIPH_FREQUENCY_NO \ + 0x00000000U /*!< No clock enabled for the peripheral */ +#define LL_RCC_PERIPH_FREQUENCY_NA \ + 0xFFFFFFFFU /*!< Frequency cannot be provided as external clock */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup RCC_LL_EC_USART1_CLKSOURCE Peripheral USART clock source selection + * @{ + */ +#define LL_RCC_USART1_CLKSOURCE_PCLK1 \ + (uint32_t)((RCC_POSITION_USART1SW << 24) | \ + RCC_CFGR3_USART1SW_PCLK) /*!< PCLK1 clock used as USART1 clock source */ +#define LL_RCC_USART1_CLKSOURCE_SYSCLK \ + (uint32_t)( \ + (RCC_POSITION_USART1SW << 24) | \ + RCC_CFGR3_USART1SW_SYSCLK) /*!< System clock selected as USART1 clock source */ +#define LL_RCC_USART1_CLKSOURCE_LSE \ + (uint32_t)( \ + (RCC_POSITION_USART1SW << 24) | \ + RCC_CFGR3_USART1SW_LSE) /*!< LSE oscillator clock used as USART1 clock source */ +#define LL_RCC_USART1_CLKSOURCE_HSI \ + (uint32_t)( \ + (RCC_POSITION_USART1SW << 24) | \ + RCC_CFGR3_USART1SW_HSI) /*!< HSI oscillator clock used as USART1 clock source */ +#if defined(RCC_CFGR3_USART2SW) +#define LL_RCC_USART2_CLKSOURCE_PCLK1 \ + (uint32_t)((RCC_POSITION_USART2SW << 24) | \ + RCC_CFGR3_USART2SW_PCLK) /*!< PCLK1 clock used as USART2 clock source */ +#define LL_RCC_USART2_CLKSOURCE_SYSCLK \ + (uint32_t)( \ + (RCC_POSITION_USART2SW << 24) | \ + RCC_CFGR3_USART2SW_SYSCLK) /*!< System clock selected as USART2 clock source */ +#define LL_RCC_USART2_CLKSOURCE_LSE \ + (uint32_t)( \ + (RCC_POSITION_USART2SW << 24) | \ + RCC_CFGR3_USART2SW_LSE) /*!< LSE oscillator clock used as USART2 clock source */ +#define LL_RCC_USART2_CLKSOURCE_HSI \ + (uint32_t)( \ + (RCC_POSITION_USART2SW << 24) | \ + RCC_CFGR3_USART2SW_HSI) /*!< HSI oscillator clock used as USART2 clock source */ +#endif /* RCC_CFGR3_USART2SW */ +#if defined(RCC_CFGR3_USART3SW) +#define LL_RCC_USART3_CLKSOURCE_PCLK1 \ + (uint32_t)((RCC_POSITION_USART3SW << 24) | \ + RCC_CFGR3_USART3SW_PCLK) /*!< PCLK1 clock used as USART3 clock source */ +#define LL_RCC_USART3_CLKSOURCE_SYSCLK \ + (uint32_t)( \ + (RCC_POSITION_USART3SW << 24) | \ + RCC_CFGR3_USART3SW_SYSCLK) /*!< System clock selected as USART3 clock source */ +#define LL_RCC_USART3_CLKSOURCE_LSE \ + (uint32_t)( \ + (RCC_POSITION_USART3SW << 24) | \ + RCC_CFGR3_USART3SW_LSE) /*!< LSE oscillator clock used as USART3 clock source */ +#define LL_RCC_USART3_CLKSOURCE_HSI \ + (uint32_t)( \ + (RCC_POSITION_USART3SW << 24) | \ + RCC_CFGR3_USART3SW_HSI) /*!< HSI oscillator clock used as USART3 clock source */ +#endif /* RCC_CFGR3_USART3SW */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_I2C1_CLKSOURCE Peripheral I2C clock source selection + * @{ + */ +#define LL_RCC_I2C1_CLKSOURCE_HSI \ + RCC_CFGR3_I2C1SW_HSI /*!< HSI oscillator clock used as I2C1 clock source */ +#define LL_RCC_I2C1_CLKSOURCE_SYSCLK \ + RCC_CFGR3_I2C1SW_SYSCLK /*!< System clock selected as I2C1 clock source */ + /** + * @} + */ + +#if defined(CEC) +/** @defgroup RCC_LL_EC_CEC_CLKSOURCE Peripheral CEC clock source selection + * @{ + */ +#define LL_RCC_CEC_CLKSOURCE_HSI_DIV244 \ + RCC_CFGR3_CECSW_HSI_DIV244 /*!< HSI clock divided by 244 selected as HDMI CEC entry \ + clock source */ +#define LL_RCC_CEC_CLKSOURCE_LSE \ + RCC_CFGR3_CECSW_LSE /*!< LSE clock selected as HDMI CEC entry clock source */ + /** + * @} + */ + +#endif /* CEC */ + +#if defined(USB) +/** @defgroup RCC_LL_EC_USB_CLKSOURCE Peripheral USB clock source selection + * @{ + */ +#if defined(RCC_CFGR3_USBSW_HSI48) +#define LL_RCC_USB_CLKSOURCE_HSI48 \ + RCC_CFGR3_USBSW_HSI48 /*!< HSI48 oscillator clock used as USB clock source */ +#else +#define LL_RCC_USB_CLKSOURCE_NONE ((uint32_t)0x00000000) /*!< USB Clock disabled */ +#endif /*RCC_CFGR3_USBSW_HSI48*/ +#define LL_RCC_USB_CLKSOURCE_PLL \ + RCC_CFGR3_USBSW_PLLCLK /*!< PLL selected as USB clock source */ + /** + * @} + */ + +#endif /* USB */ + +/** @defgroup RCC_LL_EC_USART1 Peripheral USART get clock source + * @{ + */ +#define LL_RCC_USART1_CLKSOURCE \ + RCC_POSITION_USART1SW /*!< USART1 Clock source selection */ +#if defined(RCC_CFGR3_USART2SW) +#define LL_RCC_USART2_CLKSOURCE \ + RCC_POSITION_USART2SW /*!< USART2 Clock source selection */ +#endif /* RCC_CFGR3_USART2SW */ +#if defined(RCC_CFGR3_USART3SW) +#define LL_RCC_USART3_CLKSOURCE \ + RCC_POSITION_USART3SW /*!< USART3 Clock source selection */ +#endif /* RCC_CFGR3_USART3SW */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_I2C1 Peripheral I2C get clock source + * @{ + */ +#define LL_RCC_I2C1_CLKSOURCE RCC_CFGR3_I2C1SW /*!< I2C1 Clock source selection */ + /** + * @} + */ + +#if defined(CEC) +/** @defgroup RCC_LL_EC_CEC Peripheral CEC get clock source + * @{ + */ +#define LL_RCC_CEC_CLKSOURCE RCC_CFGR3_CECSW /*!< CEC Clock source selection */ +/** + * @} + */ +#endif /* CEC */ + +#if defined(USB) +/** @defgroup RCC_LL_EC_USB Peripheral USB get clock source + * @{ + */ +#define LL_RCC_USB_CLKSOURCE RCC_CFGR3_USBSW /*!< USB Clock source selection */ +/** + * @} + */ +#endif /* USB */ + +/** @defgroup RCC_LL_EC_RTC_CLKSOURCE RTC clock source selection + * @{ + */ +#define LL_RCC_RTC_CLKSOURCE_NONE 0x00000000U /*!< No clock used as RTC clock */ +#define LL_RCC_RTC_CLKSOURCE_LSE \ + RCC_BDCR_RTCSEL_0 /*!< LSE oscillator clock used as RTC clock */ +#define LL_RCC_RTC_CLKSOURCE_LSI \ + RCC_BDCR_RTCSEL_1 /*!< LSI oscillator clock used as RTC clock */ +#define LL_RCC_RTC_CLKSOURCE_HSE_DIV32 \ + RCC_BDCR_RTCSEL /*!< HSE oscillator clock divided by 32 used as RTC clock */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLL_MUL PLL Multiplicator factor + * @{ + */ +#define LL_RCC_PLL_MUL_2 RCC_CFGR_PLLMUL2 /*!< PLL input clock*2 */ +#define LL_RCC_PLL_MUL_3 RCC_CFGR_PLLMUL3 /*!< PLL input clock*3 */ +#define LL_RCC_PLL_MUL_4 RCC_CFGR_PLLMUL4 /*!< PLL input clock*4 */ +#define LL_RCC_PLL_MUL_5 RCC_CFGR_PLLMUL5 /*!< PLL input clock*5 */ +#define LL_RCC_PLL_MUL_6 RCC_CFGR_PLLMUL6 /*!< PLL input clock*6 */ +#define LL_RCC_PLL_MUL_7 RCC_CFGR_PLLMUL7 /*!< PLL input clock*7 */ +#define LL_RCC_PLL_MUL_8 RCC_CFGR_PLLMUL8 /*!< PLL input clock*8 */ +#define LL_RCC_PLL_MUL_9 RCC_CFGR_PLLMUL9 /*!< PLL input clock*9 */ +#define LL_RCC_PLL_MUL_10 RCC_CFGR_PLLMUL10 /*!< PLL input clock*10 */ +#define LL_RCC_PLL_MUL_11 RCC_CFGR_PLLMUL11 /*!< PLL input clock*11 */ +#define LL_RCC_PLL_MUL_12 RCC_CFGR_PLLMUL12 /*!< PLL input clock*12 */ +#define LL_RCC_PLL_MUL_13 RCC_CFGR_PLLMUL13 /*!< PLL input clock*13 */ +#define LL_RCC_PLL_MUL_14 RCC_CFGR_PLLMUL14 /*!< PLL input clock*14 */ +#define LL_RCC_PLL_MUL_15 RCC_CFGR_PLLMUL15 /*!< PLL input clock*15 */ +#define LL_RCC_PLL_MUL_16 RCC_CFGR_PLLMUL16 /*!< PLL input clock*16 */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PLLSOURCE PLL SOURCE + * @{ + */ +#define LL_RCC_PLLSOURCE_NONE \ + 0x00000000U /*!< No clock selected as main PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE \ + RCC_CFGR_PLLSRC_HSE_PREDIV /*!< HSE/PREDIV clock selected as PLL entry clock source \ + */ +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) +#define LL_RCC_PLLSOURCE_HSI \ + RCC_CFGR_PLLSRC_HSI_PREDIV /*!< HSI/PREDIV clock selected as PLL entry clock source \ + */ +#if defined(RCC_CFGR_SW_HSI48) +#define LL_RCC_PLLSOURCE_HSI48 \ + RCC_CFGR_PLLSRC_HSI48_PREDIV /*!< HSI48/PREDIV clock selected as PLL entry clock \ + source */ +#endif /* RCC_CFGR_SW_HSI48 */ +#else +#define LL_RCC_PLLSOURCE_HSI_DIV_2 \ + RCC_CFGR_PLLSRC_HSI_DIV2 /*!< HSI clock divided by 2 selected as PLL entry clock \ + source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_1 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV1) /*!< HSE clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_2 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV2) /*!< HSE/2 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_3 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV3) /*!< HSE/3 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_4 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV4) /*!< HSE/4 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_5 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV5) /*!< HSE/5 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_6 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV6) /*!< HSE/6 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_7 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV7) /*!< HSE/7 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_8 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV8) /*!< HSE/8 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_9 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV9) /*!< HSE/9 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_10 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV10) /*!< HSE/10 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_11 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV11) /*!< HSE/11 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_12 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV12) /*!< HSE/12 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_13 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV13) /*!< HSE/13 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_14 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV14) /*!< HSE/14 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_15 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV15) /*!< HSE/15 clock selected as PLL entry clock source */ +#define LL_RCC_PLLSOURCE_HSE_DIV_16 \ + (RCC_CFGR_PLLSRC_HSE_PREDIV | \ + RCC_CFGR2_PREDIV_DIV16) /*!< HSE/16 clock selected as PLL entry clock source */ +#endif /* RCC_PLLSRC_PREDIV1_SUPPORT */ +/** + * @} + */ + +/** @defgroup RCC_LL_EC_PREDIV_DIV PREDIV Division factor + * @{ + */ +#define LL_RCC_PREDIV_DIV_1 RCC_CFGR2_PREDIV_DIV1 /*!< PREDIV input clock not divided */ +#define LL_RCC_PREDIV_DIV_2 \ + RCC_CFGR2_PREDIV_DIV2 /*!< PREDIV input clock divided by 2 \ + */ +#define LL_RCC_PREDIV_DIV_3 \ + RCC_CFGR2_PREDIV_DIV3 /*!< PREDIV input clock divided by 3 \ + */ +#define LL_RCC_PREDIV_DIV_4 \ + RCC_CFGR2_PREDIV_DIV4 /*!< PREDIV input clock divided by 4 \ + */ +#define LL_RCC_PREDIV_DIV_5 \ + RCC_CFGR2_PREDIV_DIV5 /*!< PREDIV input clock divided by 5 \ + */ +#define LL_RCC_PREDIV_DIV_6 \ + RCC_CFGR2_PREDIV_DIV6 /*!< PREDIV input clock divided by 6 \ + */ +#define LL_RCC_PREDIV_DIV_7 \ + RCC_CFGR2_PREDIV_DIV7 /*!< PREDIV input clock divided by 7 \ + */ +#define LL_RCC_PREDIV_DIV_8 \ + RCC_CFGR2_PREDIV_DIV8 /*!< PREDIV input clock divided by 8 \ + */ +#define LL_RCC_PREDIV_DIV_9 \ + RCC_CFGR2_PREDIV_DIV9 /*!< PREDIV input clock divided by 9 \ + */ +#define LL_RCC_PREDIV_DIV_10 \ + RCC_CFGR2_PREDIV_DIV10 /*!< PREDIV input clock divided by 10 */ +#define LL_RCC_PREDIV_DIV_11 \ + RCC_CFGR2_PREDIV_DIV11 /*!< PREDIV input clock divided by 11 */ +#define LL_RCC_PREDIV_DIV_12 \ + RCC_CFGR2_PREDIV_DIV12 /*!< PREDIV input clock divided by 12 */ +#define LL_RCC_PREDIV_DIV_13 \ + RCC_CFGR2_PREDIV_DIV13 /*!< PREDIV input clock divided by 13 */ +#define LL_RCC_PREDIV_DIV_14 \ + RCC_CFGR2_PREDIV_DIV14 /*!< PREDIV input clock divided by 14 */ +#define LL_RCC_PREDIV_DIV_15 \ + RCC_CFGR2_PREDIV_DIV15 /*!< PREDIV input clock divided by 15 */ +#define LL_RCC_PREDIV_DIV_16 \ + RCC_CFGR2_PREDIV_DIV16 /*!< PREDIV input clock divided by 16 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RCC_LL_Exported_Macros RCC Exported Macros + * @{ + */ + +/** @defgroup RCC_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in RCC register + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_RCC_WriteReg(__REG__, __VALUE__) WRITE_REG(RCC->__REG__, (__VALUE__)) + +/** + * @brief Read a value in RCC register + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_RCC_ReadReg(__REG__) READ_REG(RCC->__REG__) + /** + * @} + */ + + /** @defgroup RCC_LL_EM_CALC_FREQ Calculate frequencies + * @{ + */ + +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) +/** + * @brief Helper macro to calculate the PLLCLK frequency + * @note ex: @ref __LL_RCC_CALC_PLLCLK_FREQ (HSE_VALUE, @ref LL_RCC_PLL_GetMultiplicator() + * , @ref LL_RCC_PLL_GetPrediv()); + * @param __INPUTFREQ__ PLL Input frequency (based on HSE/HSI/HSI48) + * @param __PLLMUL__ This parameter can be one of the following values: + * @arg @ref LL_RCC_PLL_MUL_2 + * @arg @ref LL_RCC_PLL_MUL_3 + * @arg @ref LL_RCC_PLL_MUL_4 + * @arg @ref LL_RCC_PLL_MUL_5 + * @arg @ref LL_RCC_PLL_MUL_6 + * @arg @ref LL_RCC_PLL_MUL_7 + * @arg @ref LL_RCC_PLL_MUL_8 + * @arg @ref LL_RCC_PLL_MUL_9 + * @arg @ref LL_RCC_PLL_MUL_10 + * @arg @ref LL_RCC_PLL_MUL_11 + * @arg @ref LL_RCC_PLL_MUL_12 + * @arg @ref LL_RCC_PLL_MUL_13 + * @arg @ref LL_RCC_PLL_MUL_14 + * @arg @ref LL_RCC_PLL_MUL_15 + * @arg @ref LL_RCC_PLL_MUL_16 + * @param __PLLPREDIV__ This parameter can be one of the following values: + * @arg @ref LL_RCC_PREDIV_DIV_1 + * @arg @ref LL_RCC_PREDIV_DIV_2 + * @arg @ref LL_RCC_PREDIV_DIV_3 + * @arg @ref LL_RCC_PREDIV_DIV_4 + * @arg @ref LL_RCC_PREDIV_DIV_5 + * @arg @ref LL_RCC_PREDIV_DIV_6 + * @arg @ref LL_RCC_PREDIV_DIV_7 + * @arg @ref LL_RCC_PREDIV_DIV_8 + * @arg @ref LL_RCC_PREDIV_DIV_9 + * @arg @ref LL_RCC_PREDIV_DIV_10 + * @arg @ref LL_RCC_PREDIV_DIV_11 + * @arg @ref LL_RCC_PREDIV_DIV_12 + * @arg @ref LL_RCC_PREDIV_DIV_13 + * @arg @ref LL_RCC_PREDIV_DIV_14 + * @arg @ref LL_RCC_PREDIV_DIV_15 + * @arg @ref LL_RCC_PREDIV_DIV_16 + * @retval PLL clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLLCLK_FREQ(__INPUTFREQ__, __PLLMUL__, __PLLPREDIV__) \ + (((__INPUTFREQ__) / ((((__PLLPREDIV__)&RCC_CFGR2_PREDIV) + 1U))) * \ + ((((__PLLMUL__)&RCC_CFGR_PLLMUL) >> RCC_POSITION_PLLMUL) + 2U)) + +#else +/** + * @brief Helper macro to calculate the PLLCLK frequency + * @note ex: @ref __LL_RCC_CALC_PLLCLK_FREQ (HSE_VALUE / (@ref LL_RCC_PLL_GetPrediv () + + * 1), @ref LL_RCC_PLL_GetMultiplicator()); + * @param __INPUTFREQ__ PLL Input frequency (based on HSE div Prediv / HSI div 2) + * @param __PLLMUL__ This parameter can be one of the following values: + * @arg @ref LL_RCC_PLL_MUL_2 + * @arg @ref LL_RCC_PLL_MUL_3 + * @arg @ref LL_RCC_PLL_MUL_4 + * @arg @ref LL_RCC_PLL_MUL_5 + * @arg @ref LL_RCC_PLL_MUL_6 + * @arg @ref LL_RCC_PLL_MUL_7 + * @arg @ref LL_RCC_PLL_MUL_8 + * @arg @ref LL_RCC_PLL_MUL_9 + * @arg @ref LL_RCC_PLL_MUL_10 + * @arg @ref LL_RCC_PLL_MUL_11 + * @arg @ref LL_RCC_PLL_MUL_12 + * @arg @ref LL_RCC_PLL_MUL_13 + * @arg @ref LL_RCC_PLL_MUL_14 + * @arg @ref LL_RCC_PLL_MUL_15 + * @arg @ref LL_RCC_PLL_MUL_16 + * @retval PLL clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PLLCLK_FREQ(__INPUTFREQ__, __PLLMUL__) \ + ((__INPUTFREQ__) * ((((__PLLMUL__)&RCC_CFGR_PLLMUL) >> RCC_POSITION_PLLMUL) + 2U)) +#endif /* RCC_PLLSRC_PREDIV1_SUPPORT */ +/** + * @brief Helper macro to calculate the HCLK frequency + * @note: __AHBPRESCALER__ be retrieved by @ref LL_RCC_GetAHBPrescaler + * ex: __LL_RCC_CALC_HCLK_FREQ(LL_RCC_GetAHBPrescaler()) + * @param __SYSCLKFREQ__ SYSCLK frequency (based on HSE/HSI/PLLCLK) + * @param __AHBPRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_SYSCLK_DIV_1 + * @arg @ref LL_RCC_SYSCLK_DIV_2 + * @arg @ref LL_RCC_SYSCLK_DIV_4 + * @arg @ref LL_RCC_SYSCLK_DIV_8 + * @arg @ref LL_RCC_SYSCLK_DIV_16 + * @arg @ref LL_RCC_SYSCLK_DIV_64 + * @arg @ref LL_RCC_SYSCLK_DIV_128 + * @arg @ref LL_RCC_SYSCLK_DIV_256 + * @arg @ref LL_RCC_SYSCLK_DIV_512 + * @retval HCLK clock frequency (in Hz) + */ +#define __LL_RCC_CALC_HCLK_FREQ(__SYSCLKFREQ__, __AHBPRESCALER__) \ + ((__SYSCLKFREQ__) >> \ + AHBPrescTable[((__AHBPRESCALER__)&RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]) + +/** + * @brief Helper macro to calculate the PCLK1 frequency (ABP1) + * @note: __APB1PRESCALER__ be retrieved by @ref LL_RCC_GetAPB1Prescaler + * ex: __LL_RCC_CALC_PCLK1_FREQ(LL_RCC_GetAPB1Prescaler()) + * @param __HCLKFREQ__ HCLK frequency + * @param __APB1PRESCALER__ This parameter can be one of the following values: + * @arg @ref LL_RCC_APB1_DIV_1 + * @arg @ref LL_RCC_APB1_DIV_2 + * @arg @ref LL_RCC_APB1_DIV_4 + * @arg @ref LL_RCC_APB1_DIV_8 + * @arg @ref LL_RCC_APB1_DIV_16 + * @retval PCLK1 clock frequency (in Hz) + */ +#define __LL_RCC_CALC_PCLK1_FREQ(__HCLKFREQ__, __APB1PRESCALER__) \ + ((__HCLKFREQ__) >> APBPrescTable[(__APB1PRESCALER__) >> RCC_CFGR_PPRE_Pos]) + + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup RCC_LL_Exported_Functions RCC Exported Functions + * @{ + */ + + /** @defgroup RCC_LL_EF_HSE HSE + * @{ + */ + + /** + * @brief Enable the Clock Security System. + * @rmtoll CR CSSON LL_RCC_HSE_EnableCSS + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSE_EnableCSS(void) + { + SET_BIT(RCC->CR, RCC_CR_CSSON); + } + + /** + * @brief Disable the Clock Security System. + * @note Cannot be disabled in HSE is ready (only by hardware) + * @rmtoll CR CSSON LL_RCC_HSE_DisableCSS + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSE_DisableCSS(void) + { + CLEAR_BIT(RCC->CR, RCC_CR_CSSON); + } + + /** + * @brief Enable HSE external oscillator (HSE Bypass) + * @rmtoll CR HSEBYP LL_RCC_HSE_EnableBypass + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSE_EnableBypass(void) + { + SET_BIT(RCC->CR, RCC_CR_HSEBYP); + } + + /** + * @brief Disable HSE external oscillator (HSE Bypass) + * @rmtoll CR HSEBYP LL_RCC_HSE_DisableBypass + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSE_DisableBypass(void) + { + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + } + + /** + * @brief Enable HSE crystal oscillator (HSE ON) + * @rmtoll CR HSEON LL_RCC_HSE_Enable + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSE_Enable(void) + { + SET_BIT(RCC->CR, RCC_CR_HSEON); + } + + /** + * @brief Disable HSE crystal oscillator (HSE ON) + * @rmtoll CR HSEON LL_RCC_HSE_Disable + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSE_Disable(void) + { + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); + } + + /** + * @brief Check if HSE oscillator Ready + * @rmtoll CR HSERDY LL_RCC_HSE_IsReady + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_HSE_IsReady(void) + { + return (READ_BIT(RCC->CR, RCC_CR_HSERDY) == (RCC_CR_HSERDY)); + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_HSI HSI + * @{ + */ + + /** + * @brief Enable HSI oscillator + * @rmtoll CR HSION LL_RCC_HSI_Enable + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI_Enable(void) + { + SET_BIT(RCC->CR, RCC_CR_HSION); + } + + /** + * @brief Disable HSI oscillator + * @rmtoll CR HSION LL_RCC_HSI_Disable + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI_Disable(void) + { + CLEAR_BIT(RCC->CR, RCC_CR_HSION); + } + + /** + * @brief Check if HSI clock is ready + * @rmtoll CR HSIRDY LL_RCC_HSI_IsReady + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_HSI_IsReady(void) + { + return (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == (RCC_CR_HSIRDY)); + } + + /** + * @brief Get HSI Calibration value + * @note When HSITRIM is written, HSICAL is updated with the sum of + * HSITRIM and the factory trim value + * @rmtoll CR HSICAL LL_RCC_HSI_GetCalibration + * @retval Between Min_Data = 0x00 and Max_Data = 0xFF + */ + __STATIC_INLINE uint32_t LL_RCC_HSI_GetCalibration(void) + { + return (uint32_t)(READ_BIT(RCC->CR, RCC_CR_HSICAL) >> RCC_CR_HSICAL_Pos); + } + + /** + * @brief Set HSI Calibration trimming + * @note user-programmable trimming value that is added to the HSICAL + * @note Default value is 16, which, when added to the HSICAL value, + * should trim the HSI to 16 MHz +/- 1 % + * @rmtoll CR HSITRIM LL_RCC_HSI_SetCalibTrimming + * @param Value between Min_Data = 0x00 and Max_Data = 0x1F + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI_SetCalibTrimming(uint32_t Value) + { + MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, Value << RCC_CR_HSITRIM_Pos); + } + + /** + * @brief Get HSI Calibration trimming + * @rmtoll CR HSITRIM LL_RCC_HSI_GetCalibTrimming + * @retval Between Min_Data = 0x00 and Max_Data = 0x1F + */ + __STATIC_INLINE uint32_t LL_RCC_HSI_GetCalibTrimming(void) + { + return (uint32_t)(READ_BIT(RCC->CR, RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos); + } + + /** + * @} + */ + +#if defined(RCC_HSI48_SUPPORT) + /** @defgroup RCC_LL_EF_HSI48 HSI48 + * @{ + */ + + /** + * @brief Enable HSI48 + * @rmtoll CR2 HSI48ON LL_RCC_HSI48_Enable + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI48_Enable(void) + { + SET_BIT(RCC->CR2, RCC_CR2_HSI48ON); + } + + /** + * @brief Disable HSI48 + * @rmtoll CR2 HSI48ON LL_RCC_HSI48_Disable + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI48_Disable(void) + { + CLEAR_BIT(RCC->CR2, RCC_CR2_HSI48ON); + } + + /** + * @brief Check if HSI48 oscillator Ready + * @rmtoll CR2 HSI48RDY LL_RCC_HSI48_IsReady + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_HSI48_IsReady(void) + { + return (READ_BIT(RCC->CR2, RCC_CR2_HSI48RDY) == (RCC_CR2_HSI48RDY)); + } + + /** + * @brief Get HSI48 Calibration value + * @rmtoll CR2 HSI48CAL LL_RCC_HSI48_GetCalibration + * @retval Between Min_Data = 0x00 and Max_Data = 0xFF + */ + __STATIC_INLINE uint32_t LL_RCC_HSI48_GetCalibration(void) + { + return (uint32_t)(READ_BIT(RCC->CR2, RCC_CR2_HSI48CAL) >> RCC_POSITION_HSI48CAL); + } + + /** + * @} + */ + +#endif /* RCC_HSI48_SUPPORT */ + + /** @defgroup RCC_LL_EF_HSI14 HSI14 + * @{ + */ + + /** + * @brief Enable HSI14 + * @rmtoll CR2 HSI14ON LL_RCC_HSI14_Enable + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI14_Enable(void) + { + SET_BIT(RCC->CR2, RCC_CR2_HSI14ON); + } + + /** + * @brief Disable HSI14 + * @rmtoll CR2 HSI14ON LL_RCC_HSI14_Disable + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI14_Disable(void) + { + CLEAR_BIT(RCC->CR2, RCC_CR2_HSI14ON); + } + + /** + * @brief Check if HSI14 oscillator Ready + * @rmtoll CR2 HSI14RDY LL_RCC_HSI14_IsReady + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_HSI14_IsReady(void) + { + return (READ_BIT(RCC->CR2, RCC_CR2_HSI14RDY) == (RCC_CR2_HSI14RDY)); + } + + /** + * @brief ADC interface can turn on the HSI14 oscillator + * @rmtoll CR2 HSI14DIS LL_RCC_HSI14_EnableADCControl + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI14_EnableADCControl(void) + { + CLEAR_BIT(RCC->CR2, RCC_CR2_HSI14DIS); + } + + /** + * @brief ADC interface can not turn on the HSI14 oscillator + * @rmtoll CR2 HSI14DIS LL_RCC_HSI14_DisableADCControl + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI14_DisableADCControl(void) + { + SET_BIT(RCC->CR2, RCC_CR2_HSI14DIS); + } + + /** + * @brief Set HSI14 Calibration trimming + * @note user-programmable trimming value that is added to the HSI14CAL + * @note Default value is 16, which, when added to the HSI14CAL value, + * should trim the HSI14 to 14 MHz +/- 1 % + * @rmtoll CR2 HSI14TRIM LL_RCC_HSI14_SetCalibTrimming + * @param Value between Min_Data = 0x00 and Max_Data = 0xFF + * @retval None + */ + __STATIC_INLINE void LL_RCC_HSI14_SetCalibTrimming(uint32_t Value) + { + MODIFY_REG(RCC->CR2, RCC_CR2_HSI14TRIM, Value << RCC_POSITION_HSI14TRIM); + } + + /** + * @brief Get HSI14 Calibration value + * @note When HSI14TRIM is written, HSI14CAL is updated with the sum of + * HSI14TRIM and the factory trim value + * @rmtoll CR2 HSI14TRIM LL_RCC_HSI14_GetCalibTrimming + * @retval Between Min_Data = 0x00 and Max_Data = 0x1F + */ + __STATIC_INLINE uint32_t LL_RCC_HSI14_GetCalibTrimming(void) + { + return (uint32_t)(READ_BIT(RCC->CR2, RCC_CR2_HSI14TRIM) >> + RCC_POSITION_HSI14TRIM); + } + + /** + * @brief Get HSI14 Calibration trimming + * @rmtoll CR2 HSI14CAL LL_RCC_HSI14_GetCalibration + * @retval Between Min_Data = 0x00 and Max_Data = 0x1F + */ + __STATIC_INLINE uint32_t LL_RCC_HSI14_GetCalibration(void) + { + return (uint32_t)(READ_BIT(RCC->CR2, RCC_CR2_HSI14CAL) >> RCC_POSITION_HSI14CAL); + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_LSE LSE + * @{ + */ + + /** + * @brief Enable Low Speed External (LSE) crystal. + * @rmtoll BDCR LSEON LL_RCC_LSE_Enable + * @retval None + */ + __STATIC_INLINE void LL_RCC_LSE_Enable(void) + { + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); + } + + /** + * @brief Disable Low Speed External (LSE) crystal. + * @rmtoll BDCR LSEON LL_RCC_LSE_Disable + * @retval None + */ + __STATIC_INLINE void LL_RCC_LSE_Disable(void) + { + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); + } + + /** + * @brief Enable external clock source (LSE bypass). + * @rmtoll BDCR LSEBYP LL_RCC_LSE_EnableBypass + * @retval None + */ + __STATIC_INLINE void LL_RCC_LSE_EnableBypass(void) + { + SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); + } + + /** + * @brief Disable external clock source (LSE bypass). + * @rmtoll BDCR LSEBYP LL_RCC_LSE_DisableBypass + * @retval None + */ + __STATIC_INLINE void LL_RCC_LSE_DisableBypass(void) + { + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); + } + + /** + * @brief Set LSE oscillator drive capability + * @note The oscillator is in Xtal mode when it is not in bypass mode. + * @rmtoll BDCR LSEDRV LL_RCC_LSE_SetDriveCapability + * @param LSEDrive This parameter can be one of the following values: + * @arg @ref LL_RCC_LSEDRIVE_LOW + * @arg @ref LL_RCC_LSEDRIVE_MEDIUMLOW + * @arg @ref LL_RCC_LSEDRIVE_MEDIUMHIGH + * @arg @ref LL_RCC_LSEDRIVE_HIGH + * @retval None + */ + __STATIC_INLINE void LL_RCC_LSE_SetDriveCapability(uint32_t LSEDrive) + { + MODIFY_REG(RCC->BDCR, RCC_BDCR_LSEDRV, LSEDrive); + } + + /** + * @brief Get LSE oscillator drive capability + * @rmtoll BDCR LSEDRV LL_RCC_LSE_GetDriveCapability + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_LSEDRIVE_LOW + * @arg @ref LL_RCC_LSEDRIVE_MEDIUMLOW + * @arg @ref LL_RCC_LSEDRIVE_MEDIUMHIGH + * @arg @ref LL_RCC_LSEDRIVE_HIGH + */ + __STATIC_INLINE uint32_t LL_RCC_LSE_GetDriveCapability(void) + { + return (uint32_t)(READ_BIT(RCC->BDCR, RCC_BDCR_LSEDRV)); + } + + /** + * @brief Check if LSE oscillator Ready + * @rmtoll BDCR LSERDY LL_RCC_LSE_IsReady + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_LSE_IsReady(void) + { + return (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == (RCC_BDCR_LSERDY)); + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_LSI LSI + * @{ + */ + + /** + * @brief Enable LSI Oscillator + * @rmtoll CSR LSION LL_RCC_LSI_Enable + * @retval None + */ + __STATIC_INLINE void LL_RCC_LSI_Enable(void) + { + SET_BIT(RCC->CSR, RCC_CSR_LSION); + } + + /** + * @brief Disable LSI Oscillator + * @rmtoll CSR LSION LL_RCC_LSI_Disable + * @retval None + */ + __STATIC_INLINE void LL_RCC_LSI_Disable(void) + { + CLEAR_BIT(RCC->CSR, RCC_CSR_LSION); + } + + /** + * @brief Check if LSI is Ready + * @rmtoll CSR LSIRDY LL_RCC_LSI_IsReady + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_LSI_IsReady(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == (RCC_CSR_LSIRDY)); + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_System System + * @{ + */ + + /** + * @brief Configure the system clock source + * @rmtoll CFGR SW LL_RCC_SetSysClkSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_SYS_CLKSOURCE_HSI + * @arg @ref LL_RCC_SYS_CLKSOURCE_HSE + * @arg @ref LL_RCC_SYS_CLKSOURCE_PLL + * @arg @ref LL_RCC_SYS_CLKSOURCE_HSI48 (*) + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_RCC_SetSysClkSource(uint32_t Source) + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, Source); + } + + /** + * @brief Get the system clock source + * @rmtoll CFGR SWS LL_RCC_GetSysClkSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SYS_CLKSOURCE_STATUS_HSI + * @arg @ref LL_RCC_SYS_CLKSOURCE_STATUS_HSE + * @arg @ref LL_RCC_SYS_CLKSOURCE_STATUS_PLL + * @arg @ref LL_RCC_SYS_CLKSOURCE_STATUS_HSI48 (*) + * + * (*) value not defined in all devices + */ + __STATIC_INLINE uint32_t LL_RCC_GetSysClkSource(void) + { + return (uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_SWS)); + } + + /** + * @brief Set AHB prescaler + * @rmtoll CFGR HPRE LL_RCC_SetAHBPrescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_SYSCLK_DIV_1 + * @arg @ref LL_RCC_SYSCLK_DIV_2 + * @arg @ref LL_RCC_SYSCLK_DIV_4 + * @arg @ref LL_RCC_SYSCLK_DIV_8 + * @arg @ref LL_RCC_SYSCLK_DIV_16 + * @arg @ref LL_RCC_SYSCLK_DIV_64 + * @arg @ref LL_RCC_SYSCLK_DIV_128 + * @arg @ref LL_RCC_SYSCLK_DIV_256 + * @arg @ref LL_RCC_SYSCLK_DIV_512 + * @retval None + */ + __STATIC_INLINE void LL_RCC_SetAHBPrescaler(uint32_t Prescaler) + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, Prescaler); + } + + /** + * @brief Set APB1 prescaler + * @rmtoll CFGR PPRE LL_RCC_SetAPB1Prescaler + * @param Prescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_APB1_DIV_1 + * @arg @ref LL_RCC_APB1_DIV_2 + * @arg @ref LL_RCC_APB1_DIV_4 + * @arg @ref LL_RCC_APB1_DIV_8 + * @arg @ref LL_RCC_APB1_DIV_16 + * @retval None + */ + __STATIC_INLINE void LL_RCC_SetAPB1Prescaler(uint32_t Prescaler) + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, Prescaler); + } + + /** + * @brief Get AHB prescaler + * @rmtoll CFGR HPRE LL_RCC_GetAHBPrescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_SYSCLK_DIV_1 + * @arg @ref LL_RCC_SYSCLK_DIV_2 + * @arg @ref LL_RCC_SYSCLK_DIV_4 + * @arg @ref LL_RCC_SYSCLK_DIV_8 + * @arg @ref LL_RCC_SYSCLK_DIV_16 + * @arg @ref LL_RCC_SYSCLK_DIV_64 + * @arg @ref LL_RCC_SYSCLK_DIV_128 + * @arg @ref LL_RCC_SYSCLK_DIV_256 + * @arg @ref LL_RCC_SYSCLK_DIV_512 + */ + __STATIC_INLINE uint32_t LL_RCC_GetAHBPrescaler(void) + { + return (uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE)); + } + + /** + * @brief Get APB1 prescaler + * @rmtoll CFGR PPRE LL_RCC_GetAPB1Prescaler + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_APB1_DIV_1 + * @arg @ref LL_RCC_APB1_DIV_2 + * @arg @ref LL_RCC_APB1_DIV_4 + * @arg @ref LL_RCC_APB1_DIV_8 + * @arg @ref LL_RCC_APB1_DIV_16 + */ + __STATIC_INLINE uint32_t LL_RCC_GetAPB1Prescaler(void) + { + return (uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PPRE)); + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_MCO MCO + * @{ + */ + + /** + * @brief Configure MCOx + * @rmtoll CFGR MCO LL_RCC_ConfigMCO\n + * CFGR MCOPRE LL_RCC_ConfigMCO\n + * CFGR PLLNODIV LL_RCC_ConfigMCO + * @param MCOxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_MCO1SOURCE_NOCLOCK + * @arg @ref LL_RCC_MCO1SOURCE_HSI14 + * @arg @ref LL_RCC_MCO1SOURCE_SYSCLK + * @arg @ref LL_RCC_MCO1SOURCE_HSI + * @arg @ref LL_RCC_MCO1SOURCE_HSE + * @arg @ref LL_RCC_MCO1SOURCE_LSI + * @arg @ref LL_RCC_MCO1SOURCE_LSE + * @arg @ref LL_RCC_MCO1SOURCE_HSI48 (*) + * @arg @ref LL_RCC_MCO1SOURCE_PLLCLK (*) + * @arg @ref LL_RCC_MCO1SOURCE_PLLCLK_DIV_2 + * + * (*) value not defined in all devices + * @param MCOxPrescaler This parameter can be one of the following values: + * @arg @ref LL_RCC_MCO1_DIV_1 + * @arg @ref LL_RCC_MCO1_DIV_2 (*) + * @arg @ref LL_RCC_MCO1_DIV_4 (*) + * @arg @ref LL_RCC_MCO1_DIV_8 (*) + * @arg @ref LL_RCC_MCO1_DIV_16 (*) + * @arg @ref LL_RCC_MCO1_DIV_32 (*) + * @arg @ref LL_RCC_MCO1_DIV_64 (*) + * @arg @ref LL_RCC_MCO1_DIV_128 (*) + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_RCC_ConfigMCO(uint32_t MCOxSource, uint32_t MCOxPrescaler) + { +#if defined(RCC_CFGR_MCOPRE) +#if defined(RCC_CFGR_PLLNODIV) + MODIFY_REG(RCC->CFGR, RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE | RCC_CFGR_PLLNODIV, + MCOxSource | MCOxPrescaler); +#else + MODIFY_REG(RCC->CFGR, RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE, + MCOxSource | MCOxPrescaler); +#endif /* RCC_CFGR_PLLNODIV */ +#else + MODIFY_REG(RCC->CFGR, RCC_CFGR_MCOSEL, MCOxSource); +#endif /* RCC_CFGR_MCOPRE */ + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_Peripheral_Clock_Source Peripheral Clock Source + * @{ + */ + + /** + * @brief Configure USARTx clock source + * @rmtoll CFGR3 USART1SW LL_RCC_SetUSARTClockSource\n + * CFGR3 USART2SW LL_RCC_SetUSARTClockSource\n + * CFGR3 USART3SW LL_RCC_SetUSARTClockSource + * @param USARTxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART1_CLKSOURCE_SYSCLK + * @arg @ref LL_RCC_USART1_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_SYSCLK (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_SYSCLK (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_HSI (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_RCC_SetUSARTClockSource(uint32_t USARTxSource) + { + MODIFY_REG(RCC->CFGR3, + (RCC_CFGR3_USART1SW << ((USARTxSource & 0xFF000000U) >> 24U)), + (USARTxSource & 0x00FFFFFFU)); + } + + /** + * @brief Configure I2Cx clock source + * @rmtoll CFGR3 I2C1SW LL_RCC_SetI2CClockSource + * @param I2CxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_SYSCLK + * @retval None + */ + __STATIC_INLINE void LL_RCC_SetI2CClockSource(uint32_t I2CxSource) + { + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_I2C1SW, I2CxSource); + } + +#if defined(CEC) + /** + * @brief Configure CEC clock source + * @rmtoll CFGR3 CECSW LL_RCC_SetCECClockSource + * @param CECxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_CEC_CLKSOURCE_HSI_DIV244 + * @arg @ref LL_RCC_CEC_CLKSOURCE_LSE + * @retval None + */ + __STATIC_INLINE void LL_RCC_SetCECClockSource(uint32_t CECxSource) + { + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_CECSW, CECxSource); + } +#endif /* CEC */ + +#if defined(USB) + /** + * @brief Configure USB clock source + * @rmtoll CFGR3 USBSW LL_RCC_SetUSBClockSource + * @param USBxSource This parameter can be one of the following values: + * @arg @ref LL_RCC_USB_CLKSOURCE_HSI48 (*) + * @arg @ref LL_RCC_USB_CLKSOURCE_NONE (*) + * @arg @ref LL_RCC_USB_CLKSOURCE_PLL + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_RCC_SetUSBClockSource(uint32_t USBxSource) + { + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USBSW, USBxSource); + } +#endif /* USB */ + + /** + * @brief Get USARTx clock source + * @rmtoll CFGR3 USART1SW LL_RCC_GetUSARTClockSource\n + * CFGR3 USART2SW LL_RCC_GetUSARTClockSource\n + * CFGR3 USART3SW LL_RCC_GetUSARTClockSource + * @param USARTx This parameter can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE + * @arg @ref LL_RCC_USART2_CLKSOURCE (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE (*) + * + * (*) value not defined in all devices. + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_USART1_CLKSOURCE_PCLK1 + * @arg @ref LL_RCC_USART1_CLKSOURCE_SYSCLK + * @arg @ref LL_RCC_USART1_CLKSOURCE_LSE + * @arg @ref LL_RCC_USART1_CLKSOURCE_HSI + * @arg @ref LL_RCC_USART2_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_SYSCLK (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART2_CLKSOURCE_HSI (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_PCLK1 (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_SYSCLK (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_LSE (*) + * @arg @ref LL_RCC_USART3_CLKSOURCE_HSI (*) + * + * (*) value not defined in all devices. + */ + __STATIC_INLINE uint32_t LL_RCC_GetUSARTClockSource(uint32_t USARTx) + { + return (uint32_t)(READ_BIT(RCC->CFGR3, (RCC_CFGR3_USART1SW << USARTx)) | + (USARTx << 24U)); + } + + /** + * @brief Get I2Cx clock source + * @rmtoll CFGR3 I2C1SW LL_RCC_GetI2CClockSource + * @param I2Cx This parameter can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_I2C1_CLKSOURCE_HSI + * @arg @ref LL_RCC_I2C1_CLKSOURCE_SYSCLK + */ + __STATIC_INLINE uint32_t LL_RCC_GetI2CClockSource(uint32_t I2Cx) + { + return (uint32_t)(READ_BIT(RCC->CFGR3, I2Cx)); + } + +#if defined(CEC) + /** + * @brief Get CEC clock source + * @rmtoll CFGR3 CECSW LL_RCC_GetCECClockSource + * @param CECx This parameter can be one of the following values: + * @arg @ref LL_RCC_CEC_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_CEC_CLKSOURCE_HSI_DIV244 + * @arg @ref LL_RCC_CEC_CLKSOURCE_LSE + */ + __STATIC_INLINE uint32_t LL_RCC_GetCECClockSource(uint32_t CECx) + { + return (uint32_t)(READ_BIT(RCC->CFGR3, CECx)); + } +#endif /* CEC */ + +#if defined(USB) + /** + * @brief Get USBx clock source + * @rmtoll CFGR3 USBSW LL_RCC_GetUSBClockSource + * @param USBx This parameter can be one of the following values: + * @arg @ref LL_RCC_USB_CLKSOURCE + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_USB_CLKSOURCE_HSI48 (*) + * @arg @ref LL_RCC_USB_CLKSOURCE_NONE (*) + * @arg @ref LL_RCC_USB_CLKSOURCE_PLL + * + * (*) value not defined in all devices. + */ + __STATIC_INLINE uint32_t LL_RCC_GetUSBClockSource(uint32_t USBx) + { + return (uint32_t)(READ_BIT(RCC->CFGR3, USBx)); + } +#endif /* USB */ + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_RTC RTC + * @{ + */ + + /** + * @brief Set RTC Clock Source + * @note Once the RTC clock source has been selected, it cannot be changed any more + * unless the Backup domain is reset. The BDRST bit can be used to reset them. + * @rmtoll BDCR RTCSEL LL_RCC_SetRTCClockSource + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_RTC_CLKSOURCE_NONE + * @arg @ref LL_RCC_RTC_CLKSOURCE_LSE + * @arg @ref LL_RCC_RTC_CLKSOURCE_LSI + * @arg @ref LL_RCC_RTC_CLKSOURCE_HSE_DIV32 + * @retval None + */ + __STATIC_INLINE void LL_RCC_SetRTCClockSource(uint32_t Source) + { + MODIFY_REG(RCC->BDCR, RCC_BDCR_RTCSEL, Source); + } + + /** + * @brief Get RTC Clock Source + * @rmtoll BDCR RTCSEL LL_RCC_GetRTCClockSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_RTC_CLKSOURCE_NONE + * @arg @ref LL_RCC_RTC_CLKSOURCE_LSE + * @arg @ref LL_RCC_RTC_CLKSOURCE_LSI + * @arg @ref LL_RCC_RTC_CLKSOURCE_HSE_DIV32 + */ + __STATIC_INLINE uint32_t LL_RCC_GetRTCClockSource(void) + { + return (uint32_t)(READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL)); + } + + /** + * @brief Enable RTC + * @rmtoll BDCR RTCEN LL_RCC_EnableRTC + * @retval None + */ + __STATIC_INLINE void LL_RCC_EnableRTC(void) + { + SET_BIT(RCC->BDCR, RCC_BDCR_RTCEN); + } + + /** + * @brief Disable RTC + * @rmtoll BDCR RTCEN LL_RCC_DisableRTC + * @retval None + */ + __STATIC_INLINE void LL_RCC_DisableRTC(void) + { + CLEAR_BIT(RCC->BDCR, RCC_BDCR_RTCEN); + } + + /** + * @brief Check if RTC has been enabled or not + * @rmtoll BDCR RTCEN LL_RCC_IsEnabledRTC + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsEnabledRTC(void) + { + return (READ_BIT(RCC->BDCR, RCC_BDCR_RTCEN) == (RCC_BDCR_RTCEN)); + } + + /** + * @brief Force the Backup domain reset + * @rmtoll BDCR BDRST LL_RCC_ForceBackupDomainReset + * @retval None + */ + __STATIC_INLINE void LL_RCC_ForceBackupDomainReset(void) + { + SET_BIT(RCC->BDCR, RCC_BDCR_BDRST); + } + + /** + * @brief Release the Backup domain reset + * @rmtoll BDCR BDRST LL_RCC_ReleaseBackupDomainReset + * @retval None + */ + __STATIC_INLINE void LL_RCC_ReleaseBackupDomainReset(void) + { + CLEAR_BIT(RCC->BDCR, RCC_BDCR_BDRST); + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_PLL PLL + * @{ + */ + + /** + * @brief Enable PLL + * @rmtoll CR PLLON LL_RCC_PLL_Enable + * @retval None + */ + __STATIC_INLINE void LL_RCC_PLL_Enable(void) + { + SET_BIT(RCC->CR, RCC_CR_PLLON); + } + + /** + * @brief Disable PLL + * @note Cannot be disabled if the PLL clock is used as the system clock + * @rmtoll CR PLLON LL_RCC_PLL_Disable + * @retval None + */ + __STATIC_INLINE void LL_RCC_PLL_Disable(void) + { + CLEAR_BIT(RCC->CR, RCC_CR_PLLON); + } + + /** + * @brief Check if PLL Ready + * @rmtoll CR PLLRDY LL_RCC_PLL_IsReady + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_PLL_IsReady(void) + { + return (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == (RCC_CR_PLLRDY)); + } + +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + /** + * @brief Configure PLL used for SYSCLK Domain + * @rmtoll CFGR PLLSRC LL_RCC_PLL_ConfigDomain_SYS\n + * CFGR PLLMUL LL_RCC_PLL_ConfigDomain_SYS\n + * CFGR2 PREDIV LL_RCC_PLL_ConfigDomain_SYS + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLSOURCE_HSI + * @arg @ref LL_RCC_PLLSOURCE_HSE + * @arg @ref LL_RCC_PLLSOURCE_HSI48 (*) + * + * (*) value not defined in all devices + * @param PLLMul This parameter can be one of the following values: + * @arg @ref LL_RCC_PLL_MUL_2 + * @arg @ref LL_RCC_PLL_MUL_3 + * @arg @ref LL_RCC_PLL_MUL_4 + * @arg @ref LL_RCC_PLL_MUL_5 + * @arg @ref LL_RCC_PLL_MUL_6 + * @arg @ref LL_RCC_PLL_MUL_7 + * @arg @ref LL_RCC_PLL_MUL_8 + * @arg @ref LL_RCC_PLL_MUL_9 + * @arg @ref LL_RCC_PLL_MUL_10 + * @arg @ref LL_RCC_PLL_MUL_11 + * @arg @ref LL_RCC_PLL_MUL_12 + * @arg @ref LL_RCC_PLL_MUL_13 + * @arg @ref LL_RCC_PLL_MUL_14 + * @arg @ref LL_RCC_PLL_MUL_15 + * @arg @ref LL_RCC_PLL_MUL_16 + * @param PLLDiv This parameter can be one of the following values: + * @arg @ref LL_RCC_PREDIV_DIV_1 + * @arg @ref LL_RCC_PREDIV_DIV_2 + * @arg @ref LL_RCC_PREDIV_DIV_3 + * @arg @ref LL_RCC_PREDIV_DIV_4 + * @arg @ref LL_RCC_PREDIV_DIV_5 + * @arg @ref LL_RCC_PREDIV_DIV_6 + * @arg @ref LL_RCC_PREDIV_DIV_7 + * @arg @ref LL_RCC_PREDIV_DIV_8 + * @arg @ref LL_RCC_PREDIV_DIV_9 + * @arg @ref LL_RCC_PREDIV_DIV_10 + * @arg @ref LL_RCC_PREDIV_DIV_11 + * @arg @ref LL_RCC_PREDIV_DIV_12 + * @arg @ref LL_RCC_PREDIV_DIV_13 + * @arg @ref LL_RCC_PREDIV_DIV_14 + * @arg @ref LL_RCC_PREDIV_DIV_15 + * @arg @ref LL_RCC_PREDIV_DIV_16 + * @retval None + */ + __STATIC_INLINE void LL_RCC_PLL_ConfigDomain_SYS(uint32_t Source, uint32_t PLLMul, + uint32_t PLLDiv) + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL, Source | PLLMul); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV, PLLDiv); + } + +#else + + /** + * @brief Configure PLL used for SYSCLK Domain + * @rmtoll CFGR PLLSRC LL_RCC_PLL_ConfigDomain_SYS\n + * CFGR PLLMUL LL_RCC_PLL_ConfigDomain_SYS\n + * CFGR2 PREDIV LL_RCC_PLL_ConfigDomain_SYS + * @param Source This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLSOURCE_HSI_DIV_2 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_1 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_2 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_3 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_4 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_5 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_6 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_7 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_8 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_9 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_10 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_11 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_12 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_13 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_14 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_15 + * @arg @ref LL_RCC_PLLSOURCE_HSE_DIV_16 + * @param PLLMul This parameter can be one of the following values: + * @arg @ref LL_RCC_PLL_MUL_2 + * @arg @ref LL_RCC_PLL_MUL_3 + * @arg @ref LL_RCC_PLL_MUL_4 + * @arg @ref LL_RCC_PLL_MUL_5 + * @arg @ref LL_RCC_PLL_MUL_6 + * @arg @ref LL_RCC_PLL_MUL_7 + * @arg @ref LL_RCC_PLL_MUL_8 + * @arg @ref LL_RCC_PLL_MUL_9 + * @arg @ref LL_RCC_PLL_MUL_10 + * @arg @ref LL_RCC_PLL_MUL_11 + * @arg @ref LL_RCC_PLL_MUL_12 + * @arg @ref LL_RCC_PLL_MUL_13 + * @arg @ref LL_RCC_PLL_MUL_14 + * @arg @ref LL_RCC_PLL_MUL_15 + * @arg @ref LL_RCC_PLL_MUL_16 + * @retval None + */ + __STATIC_INLINE void LL_RCC_PLL_ConfigDomain_SYS(uint32_t Source, uint32_t PLLMul) + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL, + (Source & RCC_CFGR_PLLSRC) | PLLMul); + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV, (Source & RCC_CFGR2_PREDIV)); + } +#endif /* RCC_PLLSRC_PREDIV1_SUPPORT */ + + /** + * @brief Configure PLL clock source + * @rmtoll CFGR PLLSRC LL_RCC_PLL_SetMainSource + * @param PLLSource This parameter can be one of the following values: + * @arg @ref LL_RCC_PLLSOURCE_NONE + * @arg @ref LL_RCC_PLLSOURCE_HSI (*) + * @arg @ref LL_RCC_PLLSOURCE_HSI_DIV_2 (*) + * @arg @ref LL_RCC_PLLSOURCE_HSE + * @arg @ref LL_RCC_PLLSOURCE_HSI48 (*) + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_RCC_PLL_SetMainSource(uint32_t PLLSource) + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLSRC, PLLSource); + } + + /** + * @brief Get the oscillator used as PLL clock source. + * @rmtoll CFGR PLLSRC LL_RCC_PLL_GetMainSource + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLLSOURCE_NONE + * @arg @ref LL_RCC_PLLSOURCE_HSI (*) + * @arg @ref LL_RCC_PLLSOURCE_HSI_DIV_2 (*) + * @arg @ref LL_RCC_PLLSOURCE_HSE + * @arg @ref LL_RCC_PLLSOURCE_HSI48 (*) + * + * (*) value not defined in all devices + */ + __STATIC_INLINE uint32_t LL_RCC_PLL_GetMainSource(void) + { + return (uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PLLSRC)); + } + + /** + * @brief Get PLL multiplication Factor + * @rmtoll CFGR PLLMUL LL_RCC_PLL_GetMultiplicator + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PLL_MUL_2 + * @arg @ref LL_RCC_PLL_MUL_3 + * @arg @ref LL_RCC_PLL_MUL_4 + * @arg @ref LL_RCC_PLL_MUL_5 + * @arg @ref LL_RCC_PLL_MUL_6 + * @arg @ref LL_RCC_PLL_MUL_7 + * @arg @ref LL_RCC_PLL_MUL_8 + * @arg @ref LL_RCC_PLL_MUL_9 + * @arg @ref LL_RCC_PLL_MUL_10 + * @arg @ref LL_RCC_PLL_MUL_11 + * @arg @ref LL_RCC_PLL_MUL_12 + * @arg @ref LL_RCC_PLL_MUL_13 + * @arg @ref LL_RCC_PLL_MUL_14 + * @arg @ref LL_RCC_PLL_MUL_15 + * @arg @ref LL_RCC_PLL_MUL_16 + */ + __STATIC_INLINE uint32_t LL_RCC_PLL_GetMultiplicator(void) + { + return (uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PLLMUL)); + } + + /** + * @brief Get PREDIV division factor for the main PLL + * @note They can be written only when the PLL is disabled + * @rmtoll CFGR2 PREDIV LL_RCC_PLL_GetPrediv + * @retval Returned value can be one of the following values: + * @arg @ref LL_RCC_PREDIV_DIV_1 + * @arg @ref LL_RCC_PREDIV_DIV_2 + * @arg @ref LL_RCC_PREDIV_DIV_3 + * @arg @ref LL_RCC_PREDIV_DIV_4 + * @arg @ref LL_RCC_PREDIV_DIV_5 + * @arg @ref LL_RCC_PREDIV_DIV_6 + * @arg @ref LL_RCC_PREDIV_DIV_7 + * @arg @ref LL_RCC_PREDIV_DIV_8 + * @arg @ref LL_RCC_PREDIV_DIV_9 + * @arg @ref LL_RCC_PREDIV_DIV_10 + * @arg @ref LL_RCC_PREDIV_DIV_11 + * @arg @ref LL_RCC_PREDIV_DIV_12 + * @arg @ref LL_RCC_PREDIV_DIV_13 + * @arg @ref LL_RCC_PREDIV_DIV_14 + * @arg @ref LL_RCC_PREDIV_DIV_15 + * @arg @ref LL_RCC_PREDIV_DIV_16 + */ + __STATIC_INLINE uint32_t LL_RCC_PLL_GetPrediv(void) + { + return (uint32_t)(READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV)); + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_FLAG_Management FLAG Management + * @{ + */ + + /** + * @brief Clear LSI ready interrupt flag + * @rmtoll CIR LSIRDYC LL_RCC_ClearFlag_LSIRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearFlag_LSIRDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_LSIRDYC); + } + + /** + * @brief Clear LSE ready interrupt flag + * @rmtoll CIR LSERDYC LL_RCC_ClearFlag_LSERDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearFlag_LSERDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_LSERDYC); + } + + /** + * @brief Clear HSI ready interrupt flag + * @rmtoll CIR HSIRDYC LL_RCC_ClearFlag_HSIRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearFlag_HSIRDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_HSIRDYC); + } + + /** + * @brief Clear HSE ready interrupt flag + * @rmtoll CIR HSERDYC LL_RCC_ClearFlag_HSERDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearFlag_HSERDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_HSERDYC); + } + + /** + * @brief Clear PLL ready interrupt flag + * @rmtoll CIR PLLRDYC LL_RCC_ClearFlag_PLLRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearFlag_PLLRDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_PLLRDYC); + } + + /** + * @brief Clear HSI14 ready interrupt flag + * @rmtoll CIR HSI14RDYC LL_RCC_ClearFlag_HSI14RDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearFlag_HSI14RDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_HSI14RDYC); + } + +#if defined(RCC_HSI48_SUPPORT) + /** + * @brief Clear HSI48 ready interrupt flag + * @rmtoll CIR HSI48RDYC LL_RCC_ClearFlag_HSI48RDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearFlag_HSI48RDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_HSI48RDYC); + } +#endif /* RCC_HSI48_SUPPORT */ + + /** + * @brief Clear Clock security system interrupt flag + * @rmtoll CIR CSSC LL_RCC_ClearFlag_HSECSS + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearFlag_HSECSS(void) + { + SET_BIT(RCC->CIR, RCC_CIR_CSSC); + } + + /** + * @brief Check if LSI ready interrupt occurred or not + * @rmtoll CIR LSIRDYF LL_RCC_IsActiveFlag_LSIRDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_LSIRDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_LSIRDYF) == (RCC_CIR_LSIRDYF)); + } + + /** + * @brief Check if LSE ready interrupt occurred or not + * @rmtoll CIR LSERDYF LL_RCC_IsActiveFlag_LSERDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_LSERDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_LSERDYF) == (RCC_CIR_LSERDYF)); + } + + /** + * @brief Check if HSI ready interrupt occurred or not + * @rmtoll CIR HSIRDYF LL_RCC_IsActiveFlag_HSIRDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSIRDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_HSIRDYF) == (RCC_CIR_HSIRDYF)); + } + + /** + * @brief Check if HSE ready interrupt occurred or not + * @rmtoll CIR HSERDYF LL_RCC_IsActiveFlag_HSERDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSERDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_HSERDYF) == (RCC_CIR_HSERDYF)); + } + + /** + * @brief Check if PLL ready interrupt occurred or not + * @rmtoll CIR PLLRDYF LL_RCC_IsActiveFlag_PLLRDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_PLLRDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_PLLRDYF) == (RCC_CIR_PLLRDYF)); + } + + /** + * @brief Check if HSI14 ready interrupt occurred or not + * @rmtoll CIR HSI14RDYF LL_RCC_IsActiveFlag_HSI14RDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSI14RDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_HSI14RDYF) == (RCC_CIR_HSI14RDYF)); + } + +#if defined(RCC_HSI48_SUPPORT) + /** + * @brief Check if HSI48 ready interrupt occurred or not + * @rmtoll CIR HSI48RDYF LL_RCC_IsActiveFlag_HSI48RDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSI48RDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_HSI48RDYF) == (RCC_CIR_HSI48RDYF)); + } +#endif /* RCC_HSI48_SUPPORT */ + + /** + * @brief Check if Clock security system interrupt occurred or not + * @rmtoll CIR CSSF LL_RCC_IsActiveFlag_HSECSS + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_HSECSS(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_CSSF) == (RCC_CIR_CSSF)); + } + + /** + * @brief Check if RCC flag Independent Watchdog reset is set or not. + * @rmtoll CSR IWDGRSTF LL_RCC_IsActiveFlag_IWDGRST + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_IWDGRST(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_IWDGRSTF) == (RCC_CSR_IWDGRSTF)); + } + + /** + * @brief Check if RCC flag Low Power reset is set or not. + * @rmtoll CSR LPWRRSTF LL_RCC_IsActiveFlag_LPWRRST + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_LPWRRST(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_LPWRRSTF) == (RCC_CSR_LPWRRSTF)); + } + + /** + * @brief Check if RCC flag is set or not. + * @rmtoll CSR OBLRSTF LL_RCC_IsActiveFlag_OBLRST + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_OBLRST(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_OBLRSTF) == (RCC_CSR_OBLRSTF)); + } + + /** + * @brief Check if RCC flag Pin reset is set or not. + * @rmtoll CSR PINRSTF LL_RCC_IsActiveFlag_PINRST + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_PINRST(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_PINRSTF) == (RCC_CSR_PINRSTF)); + } + + /** + * @brief Check if RCC flag POR/PDR reset is set or not. + * @rmtoll CSR PORRSTF LL_RCC_IsActiveFlag_PORRST + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_PORRST(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_PORRSTF) == (RCC_CSR_PORRSTF)); + } + + /** + * @brief Check if RCC flag Software reset is set or not. + * @rmtoll CSR SFTRSTF LL_RCC_IsActiveFlag_SFTRST + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_SFTRST(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_SFTRSTF) == (RCC_CSR_SFTRSTF)); + } + + /** + * @brief Check if RCC flag Window Watchdog reset is set or not. + * @rmtoll CSR WWDGRSTF LL_RCC_IsActiveFlag_WWDGRST + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_WWDGRST(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_WWDGRSTF) == (RCC_CSR_WWDGRSTF)); + } + +#if defined(RCC_CSR_V18PWRRSTF) + /** + * @brief Check if RCC Reset flag of the 1.8 V domain is set or not. + * @rmtoll CSR V18PWRRSTF LL_RCC_IsActiveFlag_V18PWRRST + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsActiveFlag_V18PWRRST(void) + { + return (READ_BIT(RCC->CSR, RCC_CSR_V18PWRRSTF) == (RCC_CSR_V18PWRRSTF)); + } +#endif /* RCC_CSR_V18PWRRSTF */ + + /** + * @brief Set RMVF bit to clear the reset flags. + * @rmtoll CSR RMVF LL_RCC_ClearResetFlags + * @retval None + */ + __STATIC_INLINE void LL_RCC_ClearResetFlags(void) + { + SET_BIT(RCC->CSR, RCC_CSR_RMVF); + } + + /** + * @} + */ + + /** @defgroup RCC_LL_EF_IT_Management IT Management + * @{ + */ + + /** + * @brief Enable LSI ready interrupt + * @rmtoll CIR LSIRDYIE LL_RCC_EnableIT_LSIRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_EnableIT_LSIRDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_LSIRDYIE); + } + + /** + * @brief Enable LSE ready interrupt + * @rmtoll CIR LSERDYIE LL_RCC_EnableIT_LSERDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_EnableIT_LSERDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_LSERDYIE); + } + + /** + * @brief Enable HSI ready interrupt + * @rmtoll CIR HSIRDYIE LL_RCC_EnableIT_HSIRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_EnableIT_HSIRDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_HSIRDYIE); + } + + /** + * @brief Enable HSE ready interrupt + * @rmtoll CIR HSERDYIE LL_RCC_EnableIT_HSERDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_EnableIT_HSERDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_HSERDYIE); + } + + /** + * @brief Enable PLL ready interrupt + * @rmtoll CIR PLLRDYIE LL_RCC_EnableIT_PLLRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_EnableIT_PLLRDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_PLLRDYIE); + } + + /** + * @brief Enable HSI14 ready interrupt + * @rmtoll CIR HSI14RDYIE LL_RCC_EnableIT_HSI14RDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_EnableIT_HSI14RDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_HSI14RDYIE); + } + +#if defined(RCC_HSI48_SUPPORT) + /** + * @brief Enable HSI48 ready interrupt + * @rmtoll CIR HSI48RDYIE LL_RCC_EnableIT_HSI48RDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_EnableIT_HSI48RDY(void) + { + SET_BIT(RCC->CIR, RCC_CIR_HSI48RDYIE); + } +#endif /* RCC_HSI48_SUPPORT */ + + /** + * @brief Disable LSI ready interrupt + * @rmtoll CIR LSIRDYIE LL_RCC_DisableIT_LSIRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_DisableIT_LSIRDY(void) + { + CLEAR_BIT(RCC->CIR, RCC_CIR_LSIRDYIE); + } + + /** + * @brief Disable LSE ready interrupt + * @rmtoll CIR LSERDYIE LL_RCC_DisableIT_LSERDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_DisableIT_LSERDY(void) + { + CLEAR_BIT(RCC->CIR, RCC_CIR_LSERDYIE); + } + + /** + * @brief Disable HSI ready interrupt + * @rmtoll CIR HSIRDYIE LL_RCC_DisableIT_HSIRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_DisableIT_HSIRDY(void) + { + CLEAR_BIT(RCC->CIR, RCC_CIR_HSIRDYIE); + } + + /** + * @brief Disable HSE ready interrupt + * @rmtoll CIR HSERDYIE LL_RCC_DisableIT_HSERDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_DisableIT_HSERDY(void) + { + CLEAR_BIT(RCC->CIR, RCC_CIR_HSERDYIE); + } + + /** + * @brief Disable PLL ready interrupt + * @rmtoll CIR PLLRDYIE LL_RCC_DisableIT_PLLRDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_DisableIT_PLLRDY(void) + { + CLEAR_BIT(RCC->CIR, RCC_CIR_PLLRDYIE); + } + + /** + * @brief Disable HSI14 ready interrupt + * @rmtoll CIR HSI14RDYIE LL_RCC_DisableIT_HSI14RDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_DisableIT_HSI14RDY(void) + { + CLEAR_BIT(RCC->CIR, RCC_CIR_HSI14RDYIE); + } + +#if defined(RCC_HSI48_SUPPORT) + /** + * @brief Disable HSI48 ready interrupt + * @rmtoll CIR HSI48RDYIE LL_RCC_DisableIT_HSI48RDY + * @retval None + */ + __STATIC_INLINE void LL_RCC_DisableIT_HSI48RDY(void) + { + CLEAR_BIT(RCC->CIR, RCC_CIR_HSI48RDYIE); + } +#endif /* RCC_HSI48_SUPPORT */ + + /** + * @brief Checks if LSI ready interrupt source is enabled or disabled. + * @rmtoll CIR LSIRDYIE LL_RCC_IsEnabledIT_LSIRDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_LSIRDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_LSIRDYIE) == (RCC_CIR_LSIRDYIE)); + } + + /** + * @brief Checks if LSE ready interrupt source is enabled or disabled. + * @rmtoll CIR LSERDYIE LL_RCC_IsEnabledIT_LSERDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_LSERDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_LSERDYIE) == (RCC_CIR_LSERDYIE)); + } + + /** + * @brief Checks if HSI ready interrupt source is enabled or disabled. + * @rmtoll CIR HSIRDYIE LL_RCC_IsEnabledIT_HSIRDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_HSIRDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_HSIRDYIE) == (RCC_CIR_HSIRDYIE)); + } + + /** + * @brief Checks if HSE ready interrupt source is enabled or disabled. + * @rmtoll CIR HSERDYIE LL_RCC_IsEnabledIT_HSERDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_HSERDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_HSERDYIE) == (RCC_CIR_HSERDYIE)); + } + + /** + * @brief Checks if PLL ready interrupt source is enabled or disabled. + * @rmtoll CIR PLLRDYIE LL_RCC_IsEnabledIT_PLLRDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_PLLRDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_PLLRDYIE) == (RCC_CIR_PLLRDYIE)); + } + + /** + * @brief Checks if HSI14 ready interrupt source is enabled or disabled. + * @rmtoll CIR HSI14RDYIE LL_RCC_IsEnabledIT_HSI14RDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_HSI14RDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_HSI14RDYIE) == (RCC_CIR_HSI14RDYIE)); + } + +#if defined(RCC_HSI48_SUPPORT) + /** + * @brief Checks if HSI48 ready interrupt source is enabled or disabled. + * @rmtoll CIR HSI48RDYIE LL_RCC_IsEnabledIT_HSI48RDY + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_RCC_IsEnabledIT_HSI48RDY(void) + { + return (READ_BIT(RCC->CIR, RCC_CIR_HSI48RDYIE) == (RCC_CIR_HSI48RDYIE)); + } +#endif /* RCC_HSI48_SUPPORT */ + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup RCC_LL_EF_Init De-initialization function + * @{ + */ + ErrorStatus LL_RCC_DeInit(void); + /** + * @} + */ + + /** @defgroup RCC_LL_EF_Get_Freq Get system and peripherals clocks frequency functions + * @{ + */ + void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks); + uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource); + uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource); +#if defined(USB_OTG_FS) || defined(USB) + uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource); +#endif /* USB_OTG_FS || USB */ +#if defined(CEC) + uint32_t LL_RCC_GetCECClockFreq(uint32_t CECxSource); +#endif /* CEC */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* RCC */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_RCC_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_spi.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_spi.h new file mode 100644 index 0000000000..379837e7fe --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_spi.h @@ -0,0 +1,2427 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_spi.h + * @author MCD Application Team + * @brief Header file of SPI LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_LL_SPI_H +#define STM32F0xx_LL_SPI_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(SPI1) || defined(SPI2) + +/** @defgroup SPI_LL SPI + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup SPI_LL_ES_INIT SPI Exported Init structure + * @{ + */ + + /** + * @brief SPI Init structures definition + */ + typedef struct + { + uint32_t + TransferDirection; /*!< Specifies the SPI unidirectional or bidirectional data + mode. This parameter can be a value of @ref + SPI_LL_EC_TRANSFER_MODE. + + This feature can be modified afterwards using unitary + function @ref LL_SPI_SetTransferDirection().*/ + + uint32_t Mode; /*!< Specifies the SPI mode (Master/Slave). + This parameter can be a value of @ref SPI_LL_EC_MODE. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetMode().*/ + + uint32_t + DataWidth; /*!< Specifies the SPI data width. + This parameter can be a value of @ref SPI_LL_EC_DATAWIDTH. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetDataWidth().*/ + + uint32_t + ClockPolarity; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_LL_EC_POLARITY. + + This feature can be modified afterwards using unitary + function @ref LL_SPI_SetClockPolarity().*/ + + uint32_t ClockPhase; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_LL_EC_PHASE. + + This feature can be modified afterwards using unitary + function @ref LL_SPI_SetClockPhase().*/ + + uint32_t NSS; /*!< Specifies whether the NSS signal is managed by hardware (NSS + pin) or by software using the SSI bit. This parameter can be a + value of @ref SPI_LL_EC_NSS_MODE. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetNSSMode().*/ + + uint32_t + BaudRate; /*!< Specifies the BaudRate prescaler value which will be used to + configure the transmit and receive SCK clock. This parameter can + be a value of @ref SPI_LL_EC_BAUDRATEPRESCALER. + @note The communication clock is derived from the master clock. + The slave clock does not need to be set. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetBaudRatePrescaler().*/ + + uint32_t + BitOrder; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SPI_LL_EC_BIT_ORDER. + + This feature can be modified afterwards using unitary function + @ref LL_SPI_SetTransferBitOrder().*/ + + uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not. + This parameter can be a value of @ref + SPI_LL_EC_CRC_CALCULATION. + + This feature can be modified afterwards using + unitary functions @ref LL_SPI_EnableCRC() and @ref + LL_SPI_DisableCRC().*/ + + uint32_t CRCPoly; /*!< Specifies the polynomial used for the CRC calculation. + This parameter must be a number between Min_Data = 0x00 and + Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary + function @ref LL_SPI_SetCRCPolynomial().*/ + + } LL_SPI_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPI_LL_Exported_Constants SPI Exported Constants + * @{ + */ + +/** @defgroup SPI_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_SPI_ReadReg function + * @{ + */ +#define LL_SPI_SR_RXNE SPI_SR_RXNE /*!< Rx buffer not empty flag */ +#define LL_SPI_SR_TXE SPI_SR_TXE /*!< Tx buffer empty flag */ +#define LL_SPI_SR_BSY SPI_SR_BSY /*!< Busy flag */ +#define LL_SPI_SR_CRCERR SPI_SR_CRCERR /*!< CRC error flag */ +#define LL_SPI_SR_MODF SPI_SR_MODF /*!< Mode fault flag */ +#define LL_SPI_SR_OVR SPI_SR_OVR /*!< Overrun flag */ +#define LL_SPI_SR_FRE SPI_SR_FRE /*!< TI mode frame format error flag */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg + * functions + * @{ + */ +#define LL_SPI_CR2_RXNEIE SPI_CR2_RXNEIE /*!< Rx buffer not empty interrupt enable */ +#define LL_SPI_CR2_TXEIE SPI_CR2_TXEIE /*!< Tx buffer empty interrupt enable */ +#define LL_SPI_CR2_ERRIE SPI_CR2_ERRIE /*!< Error interrupt enable */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_MODE Operation Mode + * @{ + */ +#define LL_SPI_MODE_MASTER (SPI_CR1_MSTR | SPI_CR1_SSI) /*!< Master configuration */ +#define LL_SPI_MODE_SLAVE 0x00000000U /*!< Slave configuration */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_PROTOCOL Serial Protocol + * @{ + */ +#define LL_SPI_PROTOCOL_MOTOROLA \ + 0x00000000U /*!< Motorola mode. Used as default value \ + */ +#define LL_SPI_PROTOCOL_TI (SPI_CR2_FRF) /*!< TI mode */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_PHASE Clock Phase + * @{ + */ +#define LL_SPI_PHASE_1EDGE \ + 0x00000000U /*!< First clock transition is the first data capture edge */ +#define LL_SPI_PHASE_2EDGE \ + (SPI_CR1_CPHA) /*!< Second clock transition is the first data capture edge */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_POLARITY Clock Polarity + * @{ + */ +#define LL_SPI_POLARITY_LOW 0x00000000U /*!< Clock to 0 when idle */ +#define LL_SPI_POLARITY_HIGH (SPI_CR1_CPOL) /*!< Clock to 1 when idle */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_BAUDRATEPRESCALER Baud Rate Prescaler + * @{ + */ +#define LL_SPI_BAUDRATEPRESCALER_DIV2 \ + 0x00000000U /*!< BaudRate control equal to fPCLK/2 */ +#define LL_SPI_BAUDRATEPRESCALER_DIV4 \ + (SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/4 */ +#define LL_SPI_BAUDRATEPRESCALER_DIV8 \ + (SPI_CR1_BR_1) /*!< BaudRate control equal to fPCLK/8 */ +#define LL_SPI_BAUDRATEPRESCALER_DIV16 \ + (SPI_CR1_BR_1 | SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/16 */ +#define LL_SPI_BAUDRATEPRESCALER_DIV32 \ + (SPI_CR1_BR_2) /*!< BaudRate control equal to fPCLK/32 */ +#define LL_SPI_BAUDRATEPRESCALER_DIV64 \ + (SPI_CR1_BR_2 | SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/64 */ +#define LL_SPI_BAUDRATEPRESCALER_DIV128 \ + (SPI_CR1_BR_2 | SPI_CR1_BR_1) /*!< BaudRate control equal to fPCLK/128 */ +#define LL_SPI_BAUDRATEPRESCALER_DIV256 \ + (SPI_CR1_BR_2 | SPI_CR1_BR_1 | \ + SPI_CR1_BR_0) /*!< BaudRate control equal to fPCLK/256 */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_BIT_ORDER Transmission Bit Order + * @{ + */ +#define LL_SPI_LSB_FIRST \ + (SPI_CR1_LSBFIRST) /*!< Data is transmitted/received with the LSB first */ +#define LL_SPI_MSB_FIRST \ + 0x00000000U /*!< Data is transmitted/received with the MSB first */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_TRANSFER_MODE Transfer Mode + * @{ + */ +#define LL_SPI_FULL_DUPLEX \ + 0x00000000U /*!< Full-Duplex mode. Rx and Tx transfer on 2 lines */ +#define LL_SPI_SIMPLEX_RX \ + (SPI_CR1_RXONLY) /*!< Simplex Rx mode. Rx transfer only on 1 line */ +#define LL_SPI_HALF_DUPLEX_RX \ + (SPI_CR1_BIDIMODE) /*!< Half-Duplex Rx mode. Rx transfer on 1 line */ +#define LL_SPI_HALF_DUPLEX_TX \ + (SPI_CR1_BIDIMODE | \ + SPI_CR1_BIDIOE) /*!< Half-Duplex Tx mode. Tx transfer on 1 line */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_NSS_MODE Slave Select Pin Mode + * @{ + */ +#define LL_SPI_NSS_SOFT \ + (SPI_CR1_SSM) /*!< NSS managed internally. NSS pin not used and free */ +#define LL_SPI_NSS_HARD_INPUT \ + 0x00000000U /*!< NSS pin used in Input. Only used in Master mode */ +#define LL_SPI_NSS_HARD_OUTPUT \ + ( \ + ((uint32_t)SPI_CR2_SSOE \ + << 16U)) /*!< NSS pin used in Output. Only used in Slave mode as chip select */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_DATAWIDTH Datawidth + * @{ + */ +#define LL_SPI_DATAWIDTH_4BIT \ + (SPI_CR2_DS_0 | SPI_CR2_DS_1) /*!< Data length for SPI transfer: 4 bits */ +#define LL_SPI_DATAWIDTH_5BIT \ + (SPI_CR2_DS_2) /*!< Data length for SPI transfer: 5 bits \ + */ +#define LL_SPI_DATAWIDTH_6BIT \ + (SPI_CR2_DS_2 | SPI_CR2_DS_0) /*!< Data length for SPI transfer: 6 bits */ +#define LL_SPI_DATAWIDTH_7BIT \ + (SPI_CR2_DS_2 | SPI_CR2_DS_1) /*!< Data length for SPI transfer: 7 bits */ +#define LL_SPI_DATAWIDTH_8BIT \ + (SPI_CR2_DS_2 | SPI_CR2_DS_1 | \ + SPI_CR2_DS_0) /*!< Data length for SPI transfer: 8 bits */ +#define LL_SPI_DATAWIDTH_9BIT \ + (SPI_CR2_DS_3) /*!< Data length for SPI transfer: 9 bits \ + */ +#define LL_SPI_DATAWIDTH_10BIT \ + (SPI_CR2_DS_3 | SPI_CR2_DS_0) /*!< Data length for SPI transfer: 10 bits */ +#define LL_SPI_DATAWIDTH_11BIT \ + (SPI_CR2_DS_3 | SPI_CR2_DS_1) /*!< Data length for SPI transfer: 11 bits */ +#define LL_SPI_DATAWIDTH_12BIT \ + (SPI_CR2_DS_3 | SPI_CR2_DS_1 | \ + SPI_CR2_DS_0) /*!< Data length for SPI transfer: 12 bits */ +#define LL_SPI_DATAWIDTH_13BIT \ + (SPI_CR2_DS_3 | SPI_CR2_DS_2) /*!< Data length for SPI transfer: 13 bits */ +#define LL_SPI_DATAWIDTH_14BIT \ + (SPI_CR2_DS_3 | SPI_CR2_DS_2 | \ + SPI_CR2_DS_0) /*!< Data length for SPI transfer: 14 bits */ +#define LL_SPI_DATAWIDTH_15BIT \ + (SPI_CR2_DS_3 | SPI_CR2_DS_2 | \ + SPI_CR2_DS_1) /*!< Data length for SPI transfer: 15 bits */ +#define LL_SPI_DATAWIDTH_16BIT \ + (SPI_CR2_DS_3 | SPI_CR2_DS_2 | SPI_CR2_DS_1 | \ + SPI_CR2_DS_0) /*!< Data length for SPI transfer: 16 bits */ +/** + * @} + */ +#if defined(USE_FULL_LL_DRIVER) + +/** @defgroup SPI_LL_EC_CRC_CALCULATION CRC Calculation + * @{ + */ +#define LL_SPI_CRCCALCULATION_DISABLE 0x00000000U /*!< CRC calculation disabled */ +#define LL_SPI_CRCCALCULATION_ENABLE (SPI_CR1_CRCEN) /*!< CRC calculation enabled */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup SPI_LL_EC_CRC_LENGTH CRC Length + * @{ + */ +#define LL_SPI_CRC_8BIT 0x00000000U /*!< 8-bit CRC length */ +#define LL_SPI_CRC_16BIT (SPI_CR1_CRCL) /*!< 16-bit CRC length */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_RX_FIFO_TH RX FIFO Threshold + * @{ + */ +#define LL_SPI_RX_FIFO_TH_HALF \ + 0x00000000U /*!< RXNE event is generated if FIFO level is greater than or equal to \ + 1/2 (16-bit) */ +#define LL_SPI_RX_FIFO_TH_QUARTER \ + (SPI_CR2_FRXTH) /*!< RXNE event is generated if FIFO level is greater than or equal \ + to 1/4 (8-bit) */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_RX_FIFO RX FIFO Level + * @{ + */ +#define LL_SPI_RX_FIFO_EMPTY 0x00000000U /*!< FIFO reception empty */ +#define LL_SPI_RX_FIFO_QUARTER_FULL (SPI_SR_FRLVL_0) /*!< FIFO reception 1/4 */ +#define LL_SPI_RX_FIFO_HALF_FULL (SPI_SR_FRLVL_1) /*!< FIFO reception 1/2 */ +#define LL_SPI_RX_FIFO_FULL \ + (SPI_SR_FRLVL_1 | SPI_SR_FRLVL_0) /*!< FIFO reception full \ + */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_TX_FIFO TX FIFO Level + * @{ + */ +#define LL_SPI_TX_FIFO_EMPTY 0x00000000U /*!< FIFO transmission empty */ +#define LL_SPI_TX_FIFO_QUARTER_FULL (SPI_SR_FTLVL_0) /*!< FIFO transmission 1/4 */ +#define LL_SPI_TX_FIFO_HALF_FULL (SPI_SR_FTLVL_1) /*!< FIFO transmission 1/2 */ +#define LL_SPI_TX_FIFO_FULL \ + (SPI_SR_FTLVL_1 | SPI_SR_FTLVL_0) /*!< FIFO transmission full */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_DMA_PARITY DMA Parity + * @{ + */ +#define LL_SPI_DMA_PARITY_EVEN 0x00000000U /*!< Select DMA parity Even */ +#define LL_SPI_DMA_PARITY_ODD 0x00000001U /*!< Select DMA parity Odd */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SPI_LL_Exported_Macros SPI Exported Macros + * @{ + */ + +/** @defgroup SPI_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in SPI register + * @param __INSTANCE__ SPI Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_SPI_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in SPI register + * @param __INSTANCE__ SPI Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_SPI_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup SPI_LL_Exported_Functions SPI Exported Functions + * @{ + */ + + /** @defgroup SPI_LL_EF_Configuration Configuration + * @{ + */ + + /** + * @brief Enable SPI peripheral + * @rmtoll CR1 SPE LL_SPI_Enable + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_Enable(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR1, SPI_CR1_SPE); + } + + /** + * @brief Disable SPI peripheral + * @note When disabling the SPI, follow the procedure described in the Reference + * Manual. + * @rmtoll CR1 SPE LL_SPI_Disable + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_Disable(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE); + } + + /** + * @brief Check if SPI peripheral is enabled + * @rmtoll CR1 SPE LL_SPI_IsEnabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsEnabled(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->CR1, SPI_CR1_SPE) == (SPI_CR1_SPE)) ? 1UL : 0UL); + } + + /** + * @brief Set SPI operation mode to Master or Slave + * @note This bit should not be changed when communication is ongoing. + * @rmtoll CR1 MSTR LL_SPI_SetMode\n + * CR1 SSI LL_SPI_SetMode + * @param SPIx SPI Instance + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_SPI_MODE_MASTER + * @arg @ref LL_SPI_MODE_SLAVE + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetMode(SPI_TypeDef *SPIx, uint32_t Mode) + { + MODIFY_REG(SPIx->CR1, SPI_CR1_MSTR | SPI_CR1_SSI, Mode); + } + + /** + * @brief Get SPI operation mode (Master or Slave) + * @rmtoll CR1 MSTR LL_SPI_GetMode\n + * CR1 SSI LL_SPI_GetMode + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_MODE_MASTER + * @arg @ref LL_SPI_MODE_SLAVE + */ + __STATIC_INLINE uint32_t LL_SPI_GetMode(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_MSTR | SPI_CR1_SSI)); + } + + /** + * @brief Set serial protocol used + * @note This bit should be written only when SPI is disabled (SPE = 0) for correct + * operation. + * @rmtoll CR2 FRF LL_SPI_SetStandard + * @param SPIx SPI Instance + * @param Standard This parameter can be one of the following values: + * @arg @ref LL_SPI_PROTOCOL_MOTOROLA + * @arg @ref LL_SPI_PROTOCOL_TI + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard) + { + MODIFY_REG(SPIx->CR2, SPI_CR2_FRF, Standard); + } + + /** + * @brief Get serial protocol used + * @rmtoll CR2 FRF LL_SPI_GetStandard + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_PROTOCOL_MOTOROLA + * @arg @ref LL_SPI_PROTOCOL_TI + */ + __STATIC_INLINE uint32_t LL_SPI_GetStandard(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR2, SPI_CR2_FRF)); + } + + /** + * @brief Set clock phase + * @note This bit should not be changed when communication is ongoing. + * This bit is not used in SPI TI mode. + * @rmtoll CR1 CPHA LL_SPI_SetClockPhase + * @param SPIx SPI Instance + * @param ClockPhase This parameter can be one of the following values: + * @arg @ref LL_SPI_PHASE_1EDGE + * @arg @ref LL_SPI_PHASE_2EDGE + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetClockPhase(SPI_TypeDef *SPIx, uint32_t ClockPhase) + { + MODIFY_REG(SPIx->CR1, SPI_CR1_CPHA, ClockPhase); + } + + /** + * @brief Get clock phase + * @rmtoll CR1 CPHA LL_SPI_GetClockPhase + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_PHASE_1EDGE + * @arg @ref LL_SPI_PHASE_2EDGE + */ + __STATIC_INLINE uint32_t LL_SPI_GetClockPhase(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_CPHA)); + } + + /** + * @brief Set clock polarity + * @note This bit should not be changed when communication is ongoing. + * This bit is not used in SPI TI mode. + * @rmtoll CR1 CPOL LL_SPI_SetClockPolarity + * @param SPIx SPI Instance + * @param ClockPolarity This parameter can be one of the following values: + * @arg @ref LL_SPI_POLARITY_LOW + * @arg @ref LL_SPI_POLARITY_HIGH + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetClockPolarity(SPI_TypeDef *SPIx, + uint32_t ClockPolarity) + { + MODIFY_REG(SPIx->CR1, SPI_CR1_CPOL, ClockPolarity); + } + + /** + * @brief Get clock polarity + * @rmtoll CR1 CPOL LL_SPI_GetClockPolarity + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_POLARITY_LOW + * @arg @ref LL_SPI_POLARITY_HIGH + */ + __STATIC_INLINE uint32_t LL_SPI_GetClockPolarity(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_CPOL)); + } + + /** + * @brief Set baud rate prescaler + * @note These bits should not be changed when communication is ongoing. SPI + * BaudRate = fPCLK/Prescaler. + * @rmtoll CR1 BR LL_SPI_SetBaudRatePrescaler + * @param SPIx SPI Instance + * @param BaudRate This parameter can be one of the following values: + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256 + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetBaudRatePrescaler(SPI_TypeDef *SPIx, uint32_t BaudRate) + { + MODIFY_REG(SPIx->CR1, SPI_CR1_BR, BaudRate); + } + + /** + * @brief Get baud rate prescaler + * @rmtoll CR1 BR LL_SPI_GetBaudRatePrescaler + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128 + * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256 + */ + __STATIC_INLINE uint32_t LL_SPI_GetBaudRatePrescaler(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_BR)); + } + + /** + * @brief Set transfer bit order + * @note This bit should not be changed when communication is ongoing. This bit is + * not used in SPI TI mode. + * @rmtoll CR1 LSBFIRST LL_SPI_SetTransferBitOrder + * @param SPIx SPI Instance + * @param BitOrder This parameter can be one of the following values: + * @arg @ref LL_SPI_LSB_FIRST + * @arg @ref LL_SPI_MSB_FIRST + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetTransferBitOrder(SPI_TypeDef *SPIx, uint32_t BitOrder) + { + MODIFY_REG(SPIx->CR1, SPI_CR1_LSBFIRST, BitOrder); + } + + /** + * @brief Get transfer bit order + * @rmtoll CR1 LSBFIRST LL_SPI_GetTransferBitOrder + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_LSB_FIRST + * @arg @ref LL_SPI_MSB_FIRST + */ + __STATIC_INLINE uint32_t LL_SPI_GetTransferBitOrder(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_LSBFIRST)); + } + + /** + * @brief Set transfer direction mode + * @note For Half-Duplex mode, Rx Direction is set by default. + * In master mode, the MOSI pin is used and in slave mode, the MISO pin is + * used for Half-Duplex. + * @rmtoll CR1 RXONLY LL_SPI_SetTransferDirection\n + * CR1 BIDIMODE LL_SPI_SetTransferDirection\n + * CR1 BIDIOE LL_SPI_SetTransferDirection + * @param SPIx SPI Instance + * @param TransferDirection This parameter can be one of the following values: + * @arg @ref LL_SPI_FULL_DUPLEX + * @arg @ref LL_SPI_SIMPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_TX + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetTransferDirection(SPI_TypeDef *SPIx, + uint32_t TransferDirection) + { + MODIFY_REG(SPIx->CR1, SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE, + TransferDirection); + } + + /** + * @brief Get transfer direction mode + * @rmtoll CR1 RXONLY LL_SPI_GetTransferDirection\n + * CR1 BIDIMODE LL_SPI_GetTransferDirection\n + * CR1 BIDIOE LL_SPI_GetTransferDirection + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_FULL_DUPLEX + * @arg @ref LL_SPI_SIMPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_RX + * @arg @ref LL_SPI_HALF_DUPLEX_TX + */ + __STATIC_INLINE uint32_t LL_SPI_GetTransferDirection(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR1, + SPI_CR1_RXONLY | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE)); + } + + /** + * @brief Set frame data width + * @rmtoll CR2 DS LL_SPI_SetDataWidth + * @param SPIx SPI Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref LL_SPI_DATAWIDTH_4BIT + * @arg @ref LL_SPI_DATAWIDTH_5BIT + * @arg @ref LL_SPI_DATAWIDTH_6BIT + * @arg @ref LL_SPI_DATAWIDTH_7BIT + * @arg @ref LL_SPI_DATAWIDTH_8BIT + * @arg @ref LL_SPI_DATAWIDTH_9BIT + * @arg @ref LL_SPI_DATAWIDTH_10BIT + * @arg @ref LL_SPI_DATAWIDTH_11BIT + * @arg @ref LL_SPI_DATAWIDTH_12BIT + * @arg @ref LL_SPI_DATAWIDTH_13BIT + * @arg @ref LL_SPI_DATAWIDTH_14BIT + * @arg @ref LL_SPI_DATAWIDTH_15BIT + * @arg @ref LL_SPI_DATAWIDTH_16BIT + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetDataWidth(SPI_TypeDef *SPIx, uint32_t DataWidth) + { + MODIFY_REG(SPIx->CR2, SPI_CR2_DS, DataWidth); + } + + /** + * @brief Get frame data width + * @rmtoll CR2 DS LL_SPI_GetDataWidth + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_DATAWIDTH_4BIT + * @arg @ref LL_SPI_DATAWIDTH_5BIT + * @arg @ref LL_SPI_DATAWIDTH_6BIT + * @arg @ref LL_SPI_DATAWIDTH_7BIT + * @arg @ref LL_SPI_DATAWIDTH_8BIT + * @arg @ref LL_SPI_DATAWIDTH_9BIT + * @arg @ref LL_SPI_DATAWIDTH_10BIT + * @arg @ref LL_SPI_DATAWIDTH_11BIT + * @arg @ref LL_SPI_DATAWIDTH_12BIT + * @arg @ref LL_SPI_DATAWIDTH_13BIT + * @arg @ref LL_SPI_DATAWIDTH_14BIT + * @arg @ref LL_SPI_DATAWIDTH_15BIT + * @arg @ref LL_SPI_DATAWIDTH_16BIT + */ + __STATIC_INLINE uint32_t LL_SPI_GetDataWidth(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR2, SPI_CR2_DS)); + } + + /** + * @brief Set threshold of RXFIFO that triggers an RXNE event + * @rmtoll CR2 FRXTH LL_SPI_SetRxFIFOThreshold + * @param SPIx SPI Instance + * @param Threshold This parameter can be one of the following values: + * @arg @ref LL_SPI_RX_FIFO_TH_HALF + * @arg @ref LL_SPI_RX_FIFO_TH_QUARTER + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetRxFIFOThreshold(SPI_TypeDef *SPIx, uint32_t Threshold) + { + MODIFY_REG(SPIx->CR2, SPI_CR2_FRXTH, Threshold); + } + + /** + * @brief Get threshold of RXFIFO that triggers an RXNE event + * @rmtoll CR2 FRXTH LL_SPI_GetRxFIFOThreshold + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_RX_FIFO_TH_HALF + * @arg @ref LL_SPI_RX_FIFO_TH_QUARTER + */ + __STATIC_INLINE uint32_t LL_SPI_GetRxFIFOThreshold(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR2, SPI_CR2_FRXTH)); + } + + /** + * @} + */ + + /** @defgroup SPI_LL_EF_CRC_Management CRC Management + * @{ + */ + + /** + * @brief Enable CRC + * @note This bit should be written only when SPI is disabled (SPE = 0) for correct + * operation. + * @rmtoll CR1 CRCEN LL_SPI_EnableCRC + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_EnableCRC(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR1, SPI_CR1_CRCEN); + } + + /** + * @brief Disable CRC + * @note This bit should be written only when SPI is disabled (SPE = 0) for correct + * operation. + * @rmtoll CR1 CRCEN LL_SPI_DisableCRC + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_DisableCRC(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->CR1, SPI_CR1_CRCEN); + } + + /** + * @brief Check if CRC is enabled + * @note This bit should be written only when SPI is disabled (SPE = 0) for correct + * operation. + * @rmtoll CR1 CRCEN LL_SPI_IsEnabledCRC + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsEnabledCRC(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->CR1, SPI_CR1_CRCEN) == (SPI_CR1_CRCEN)) ? 1UL : 0UL); + } + + /** + * @brief Set CRC Length + * @note This bit should be written only when SPI is disabled (SPE = 0) for correct + * operation. + * @rmtoll CR1 CRCL LL_SPI_SetCRCWidth + * @param SPIx SPI Instance + * @param CRCLength This parameter can be one of the following values: + * @arg @ref LL_SPI_CRC_8BIT + * @arg @ref LL_SPI_CRC_16BIT + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetCRCWidth(SPI_TypeDef *SPIx, uint32_t CRCLength) + { + MODIFY_REG(SPIx->CR1, SPI_CR1_CRCL, CRCLength); + } + + /** + * @brief Get CRC Length + * @rmtoll CR1 CRCL LL_SPI_GetCRCWidth + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_CRC_8BIT + * @arg @ref LL_SPI_CRC_16BIT + */ + __STATIC_INLINE uint32_t LL_SPI_GetCRCWidth(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_CRCL)); + } + + /** + * @brief Set CRCNext to transfer CRC on the line + * @note This bit has to be written as soon as the last data is written in the + * SPIx_DR register. + * @rmtoll CR1 CRCNEXT LL_SPI_SetCRCNext + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetCRCNext(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR1, SPI_CR1_CRCNEXT); + } + + /** + * @brief Set polynomial for CRC calculation + * @rmtoll CRCPR CRCPOLY LL_SPI_SetCRCPolynomial + * @param SPIx SPI Instance + * @param CRCPoly This parameter must be a number between Min_Data = 0x00 and + * Max_Data = 0xFFFF + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetCRCPolynomial(SPI_TypeDef *SPIx, uint32_t CRCPoly) + { + WRITE_REG(SPIx->CRCPR, (uint16_t)CRCPoly); + } + + /** + * @brief Get polynomial for CRC calculation + * @rmtoll CRCPR CRCPOLY LL_SPI_GetCRCPolynomial + * @param SPIx SPI Instance + * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF + */ + __STATIC_INLINE uint32_t LL_SPI_GetCRCPolynomial(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_REG(SPIx->CRCPR)); + } + + /** + * @brief Get Rx CRC + * @rmtoll RXCRCR RXCRC LL_SPI_GetRxCRC + * @param SPIx SPI Instance + * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF + */ + __STATIC_INLINE uint32_t LL_SPI_GetRxCRC(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_REG(SPIx->RXCRCR)); + } + + /** + * @brief Get Tx CRC + * @rmtoll TXCRCR TXCRC LL_SPI_GetTxCRC + * @param SPIx SPI Instance + * @retval Returned value is a number between Min_Data = 0x00 and Max_Data = 0xFFFF + */ + __STATIC_INLINE uint32_t LL_SPI_GetTxCRC(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_REG(SPIx->TXCRCR)); + } + + /** + * @} + */ + + /** @defgroup SPI_LL_EF_NSS_Management Slave Select Pin Management + * @{ + */ + + /** + * @brief Set NSS mode + * @note LL_SPI_NSS_SOFT Mode is not used in SPI TI mode. + * @rmtoll CR1 SSM LL_SPI_SetNSSMode\n + * @rmtoll CR2 SSOE LL_SPI_SetNSSMode + * @param SPIx SPI Instance + * @param NSS This parameter can be one of the following values: + * @arg @ref LL_SPI_NSS_SOFT + * @arg @ref LL_SPI_NSS_HARD_INPUT + * @arg @ref LL_SPI_NSS_HARD_OUTPUT + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetNSSMode(SPI_TypeDef *SPIx, uint32_t NSS) + { + MODIFY_REG(SPIx->CR1, SPI_CR1_SSM, NSS); + MODIFY_REG(SPIx->CR2, SPI_CR2_SSOE, ((uint32_t)(NSS >> 16U))); + } + + /** + * @brief Get NSS mode + * @rmtoll CR1 SSM LL_SPI_GetNSSMode\n + * @rmtoll CR2 SSOE LL_SPI_GetNSSMode + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_NSS_SOFT + * @arg @ref LL_SPI_NSS_HARD_INPUT + * @arg @ref LL_SPI_NSS_HARD_OUTPUT + */ + __STATIC_INLINE uint32_t LL_SPI_GetNSSMode(SPI_TypeDef *SPIx) + { + uint32_t Ssm = (READ_BIT(SPIx->CR1, SPI_CR1_SSM)); + uint32_t Ssoe = (READ_BIT(SPIx->CR2, SPI_CR2_SSOE) << 16U); + return (Ssm | Ssoe); + } + + /** + * @brief Enable NSS pulse management + * @note This bit should not be changed when communication is ongoing. This bit is + * not used in SPI TI mode. + * @rmtoll CR2 NSSP LL_SPI_EnableNSSPulseMgt + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_EnableNSSPulseMgt(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR2, SPI_CR2_NSSP); + } + + /** + * @brief Disable NSS pulse management + * @note This bit should not be changed when communication is ongoing. This bit is + * not used in SPI TI mode. + * @rmtoll CR2 NSSP LL_SPI_DisableNSSPulseMgt + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_DisableNSSPulseMgt(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->CR2, SPI_CR2_NSSP); + } + + /** + * @brief Check if NSS pulse is enabled + * @note This bit should not be changed when communication is ongoing. This bit is + * not used in SPI TI mode. + * @rmtoll CR2 NSSP LL_SPI_IsEnabledNSSPulse + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsEnabledNSSPulse(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->CR2, SPI_CR2_NSSP) == (SPI_CR2_NSSP)) ? 1UL : 0UL); + } + + /** + * @} + */ + + /** @defgroup SPI_LL_EF_FLAG_Management FLAG Management + * @{ + */ + + /** + * @brief Check if Rx buffer is not empty + * @rmtoll SR RXNE LL_SPI_IsActiveFlag_RXNE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXNE(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_RXNE) == (SPI_SR_RXNE)) ? 1UL : 0UL); + } + + /** + * @brief Check if Tx buffer is empty + * @rmtoll SR TXE LL_SPI_IsActiveFlag_TXE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXE(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_TXE) == (SPI_SR_TXE)) ? 1UL : 0UL); + } + + /** + * @brief Get CRC error flag + * @rmtoll SR CRCERR LL_SPI_IsActiveFlag_CRCERR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_CRCERR(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_CRCERR) == (SPI_SR_CRCERR)) ? 1UL : 0UL); + } + + /** + * @brief Get mode fault error flag + * @rmtoll SR MODF LL_SPI_IsActiveFlag_MODF + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_MODF(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_MODF) == (SPI_SR_MODF)) ? 1UL : 0UL); + } + + /** + * @brief Get overrun error flag + * @rmtoll SR OVR LL_SPI_IsActiveFlag_OVR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_OVR(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_OVR) == (SPI_SR_OVR)) ? 1UL : 0UL); + } + + /** + * @brief Get busy flag + * @note The BSY flag is cleared under any one of the following conditions: + * -When the SPI is correctly disabled + * -When a fault is detected in Master mode (MODF bit set to 1) + * -In Master mode, when it finishes a data transmission and no new data is ready to + * be sent -In Slave mode, when the BSY flag is set to '0' for at least one SPI clock + * cycle between each data transfer. + * @rmtoll SR BSY LL_SPI_IsActiveFlag_BSY + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_BSY(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_BSY) == (SPI_SR_BSY)) ? 1UL : 0UL); + } + + /** + * @brief Get frame format error flag + * @rmtoll SR FRE LL_SPI_IsActiveFlag_FRE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_FRE(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_FRE) == (SPI_SR_FRE)) ? 1UL : 0UL); + } + + /** + * @brief Get FIFO reception Level + * @rmtoll SR FRLVL LL_SPI_GetRxFIFOLevel + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_RX_FIFO_EMPTY + * @arg @ref LL_SPI_RX_FIFO_QUARTER_FULL + * @arg @ref LL_SPI_RX_FIFO_HALF_FULL + * @arg @ref LL_SPI_RX_FIFO_FULL + */ + __STATIC_INLINE uint32_t LL_SPI_GetRxFIFOLevel(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->SR, SPI_SR_FRLVL)); + } + + /** + * @brief Get FIFO Transmission Level + * @rmtoll SR FTLVL LL_SPI_GetTxFIFOLevel + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_TX_FIFO_EMPTY + * @arg @ref LL_SPI_TX_FIFO_QUARTER_FULL + * @arg @ref LL_SPI_TX_FIFO_HALF_FULL + * @arg @ref LL_SPI_TX_FIFO_FULL + */ + __STATIC_INLINE uint32_t LL_SPI_GetTxFIFOLevel(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->SR, SPI_SR_FTLVL)); + } + + /** + * @brief Clear CRC error flag + * @rmtoll SR CRCERR LL_SPI_ClearFlag_CRCERR + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_ClearFlag_CRCERR(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->SR, SPI_SR_CRCERR); + } + + /** + * @brief Clear mode fault error flag + * @note Clearing this flag is done by a read access to the SPIx_SR + * register followed by a write access to the SPIx_CR1 register + * @rmtoll SR MODF LL_SPI_ClearFlag_MODF + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_ClearFlag_MODF(SPI_TypeDef *SPIx) + { + __IO uint32_t tmpreg_sr; + tmpreg_sr = SPIx->SR; + (void)tmpreg_sr; + CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE); + } + + /** + * @brief Clear overrun error flag + * @note Clearing this flag is done by a read access to the SPIx_DR + * register followed by a read access to the SPIx_SR register + * @rmtoll SR OVR LL_SPI_ClearFlag_OVR + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_ClearFlag_OVR(SPI_TypeDef *SPIx) + { + __IO uint32_t tmpreg; + tmpreg = SPIx->DR; + (void)tmpreg; + tmpreg = SPIx->SR; + (void)tmpreg; + } + + /** + * @brief Clear frame format error flag + * @note Clearing this flag is done by reading SPIx_SR register + * @rmtoll SR FRE LL_SPI_ClearFlag_FRE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_ClearFlag_FRE(SPI_TypeDef *SPIx) + { + __IO uint32_t tmpreg; + tmpreg = SPIx->SR; + (void)tmpreg; + } + + /** + * @} + */ + + /** @defgroup SPI_LL_EF_IT_Management Interrupt Management + * @{ + */ + + /** + * @brief Enable error interrupt + * @note This bit controls the generation of an interrupt when an error condition + * occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode). + * @rmtoll CR2 ERRIE LL_SPI_EnableIT_ERR + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_EnableIT_ERR(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR2, SPI_CR2_ERRIE); + } + + /** + * @brief Enable Rx buffer not empty interrupt + * @rmtoll CR2 RXNEIE LL_SPI_EnableIT_RXNE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_EnableIT_RXNE(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR2, SPI_CR2_RXNEIE); + } + + /** + * @brief Enable Tx buffer empty interrupt + * @rmtoll CR2 TXEIE LL_SPI_EnableIT_TXE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_EnableIT_TXE(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR2, SPI_CR2_TXEIE); + } + + /** + * @brief Disable error interrupt + * @note This bit controls the generation of an interrupt when an error condition + * occurs (CRCERR, OVR, MODF in SPI mode, FRE at TI mode). + * @rmtoll CR2 ERRIE LL_SPI_DisableIT_ERR + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_DisableIT_ERR(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->CR2, SPI_CR2_ERRIE); + } + + /** + * @brief Disable Rx buffer not empty interrupt + * @rmtoll CR2 RXNEIE LL_SPI_DisableIT_RXNE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_DisableIT_RXNE(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->CR2, SPI_CR2_RXNEIE); + } + + /** + * @brief Disable Tx buffer empty interrupt + * @rmtoll CR2 TXEIE LL_SPI_DisableIT_TXE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_DisableIT_TXE(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->CR2, SPI_CR2_TXEIE); + } + + /** + * @brief Check if error interrupt is enabled + * @rmtoll CR2 ERRIE LL_SPI_IsEnabledIT_ERR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_ERR(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->CR2, SPI_CR2_ERRIE) == (SPI_CR2_ERRIE)) ? 1UL : 0UL); + } + + /** + * @brief Check if Rx buffer not empty interrupt is enabled + * @rmtoll CR2 RXNEIE LL_SPI_IsEnabledIT_RXNE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_RXNE(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->CR2, SPI_CR2_RXNEIE) == (SPI_CR2_RXNEIE)) ? 1UL : 0UL); + } + + /** + * @brief Check if Tx buffer empty interrupt + * @rmtoll CR2 TXEIE LL_SPI_IsEnabledIT_TXE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_TXE(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->CR2, SPI_CR2_TXEIE) == (SPI_CR2_TXEIE)) ? 1UL : 0UL); + } + + /** + * @} + */ + + /** @defgroup SPI_LL_EF_DMA_Management DMA Management + * @{ + */ + + /** + * @brief Enable DMA Rx + * @rmtoll CR2 RXDMAEN LL_SPI_EnableDMAReq_RX + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_EnableDMAReq_RX(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR2, SPI_CR2_RXDMAEN); + } + + /** + * @brief Disable DMA Rx + * @rmtoll CR2 RXDMAEN LL_SPI_DisableDMAReq_RX + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_DisableDMAReq_RX(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN); + } + + /** + * @brief Check if DMA Rx is enabled + * @rmtoll CR2 RXDMAEN LL_SPI_IsEnabledDMAReq_RX + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_RX(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->CR2, SPI_CR2_RXDMAEN) == (SPI_CR2_RXDMAEN)) ? 1UL : 0UL); + } + + /** + * @brief Enable DMA Tx + * @rmtoll CR2 TXDMAEN LL_SPI_EnableDMAReq_TX + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_EnableDMAReq_TX(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN); + } + + /** + * @brief Disable DMA Tx + * @rmtoll CR2 TXDMAEN LL_SPI_DisableDMAReq_TX + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_SPI_DisableDMAReq_TX(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->CR2, SPI_CR2_TXDMAEN); + } + + /** + * @brief Check if DMA Tx is enabled + * @rmtoll CR2 TXDMAEN LL_SPI_IsEnabledDMAReq_TX + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_TX(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->CR2, SPI_CR2_TXDMAEN) == (SPI_CR2_TXDMAEN)) ? 1UL : 0UL); + } + + /** + * @brief Set parity of Last DMA reception + * @rmtoll CR2 LDMARX LL_SPI_SetDMAParity_RX + * @param SPIx SPI Instance + * @param Parity This parameter can be one of the following values: + * @arg @ref LL_SPI_DMA_PARITY_ODD + * @arg @ref LL_SPI_DMA_PARITY_EVEN + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetDMAParity_RX(SPI_TypeDef *SPIx, uint32_t Parity) + { + MODIFY_REG(SPIx->CR2, SPI_CR2_LDMARX, (Parity << SPI_CR2_LDMARX_Pos)); + } + + /** + * @brief Get parity configuration for Last DMA reception + * @rmtoll CR2 LDMARX LL_SPI_GetDMAParity_RX + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_DMA_PARITY_ODD + * @arg @ref LL_SPI_DMA_PARITY_EVEN + */ + __STATIC_INLINE uint32_t LL_SPI_GetDMAParity_RX(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR2, SPI_CR2_LDMARX) >> SPI_CR2_LDMARX_Pos); + } + + /** + * @brief Set parity of Last DMA transmission + * @rmtoll CR2 LDMATX LL_SPI_SetDMAParity_TX + * @param SPIx SPI Instance + * @param Parity This parameter can be one of the following values: + * @arg @ref LL_SPI_DMA_PARITY_ODD + * @arg @ref LL_SPI_DMA_PARITY_EVEN + * @retval None + */ + __STATIC_INLINE void LL_SPI_SetDMAParity_TX(SPI_TypeDef *SPIx, uint32_t Parity) + { + MODIFY_REG(SPIx->CR2, SPI_CR2_LDMATX, (Parity << SPI_CR2_LDMATX_Pos)); + } + + /** + * @brief Get parity configuration for Last DMA transmission + * @rmtoll CR2 LDMATX LL_SPI_GetDMAParity_TX + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_SPI_DMA_PARITY_ODD + * @arg @ref LL_SPI_DMA_PARITY_EVEN + */ + __STATIC_INLINE uint32_t LL_SPI_GetDMAParity_TX(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->CR2, SPI_CR2_LDMATX) >> SPI_CR2_LDMATX_Pos); + } + + /** + * @brief Get the data register address used for DMA transfer + * @rmtoll DR DR LL_SPI_DMA_GetRegAddr + * @param SPIx SPI Instance + * @retval Address of data register + */ + __STATIC_INLINE uint32_t LL_SPI_DMA_GetRegAddr(SPI_TypeDef *SPIx) + { + return (uint32_t) & (SPIx->DR); + } + + /** + * @} + */ + + /** @defgroup SPI_LL_EF_DATA_Management DATA Management + * @{ + */ + + /** + * @brief Read 8-Bits in the data register + * @rmtoll DR DR LL_SPI_ReceiveData8 + * @param SPIx SPI Instance + * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFF + */ + __STATIC_INLINE uint8_t LL_SPI_ReceiveData8(SPI_TypeDef *SPIx) + { + return (*((__IO uint8_t *)&SPIx->DR)); + } + + /** + * @brief Read 16-Bits in the data register + * @rmtoll DR DR LL_SPI_ReceiveData16 + * @param SPIx SPI Instance + * @retval RxData Value between Min_Data=0x00 and Max_Data=0xFFFF + */ + __STATIC_INLINE uint16_t LL_SPI_ReceiveData16(SPI_TypeDef *SPIx) + { + return (uint16_t)(READ_REG(SPIx->DR)); + } + + /** + * @brief Write 8-Bits in the data register + * @rmtoll DR DR LL_SPI_TransmitData8 + * @param SPIx SPI Instance + * @param TxData Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ + __STATIC_INLINE void LL_SPI_TransmitData8(SPI_TypeDef *SPIx, uint8_t TxData) + { +#if defined(__GNUC__) + __IO uint8_t *spidr = ((__IO uint8_t *)&SPIx->DR); + *spidr = TxData; +#else + *((__IO uint8_t *)&SPIx->DR) = TxData; +#endif /* __GNUC__ */ + } + + /** + * @brief Write 16-Bits in the data register + * @rmtoll DR DR LL_SPI_TransmitData16 + * @param SPIx SPI Instance + * @param TxData Value between Min_Data=0x00 and Max_Data=0xFFFF + * @retval None + */ + __STATIC_INLINE void LL_SPI_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData) + { +#if defined(__GNUC__) + __IO uint16_t *spidr = ((__IO uint16_t *)&SPIx->DR); + *spidr = TxData; +#else + SPIx->DR = TxData; +#endif /* __GNUC__ */ + } + +/** + * @} + */ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup SPI_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx); + ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct); + void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + /** + * @} + */ + + /** + * @} + */ + +#if defined(SPI_I2S_SUPPORT) +/** @defgroup I2S_LL I2S + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup I2S_LL_ES_INIT I2S Exported Init structure + * @{ + */ + + /** + * @brief I2S Init structure definition + */ + + typedef struct + { + uint32_t Mode; /*!< Specifies the I2S operating mode. + This parameter can be a value of @ref I2S_LL_EC_MODE + + This feature can be modified afterwards using unitary function + @ref LL_I2S_SetTransferMode().*/ + + uint32_t Standard; /*!< Specifies the standard used for the I2S communication. + This parameter can be a value of @ref I2S_LL_EC_STANDARD + + This feature can be modified afterwards using unitary + function @ref LL_I2S_SetStandard().*/ + + + uint32_t + DataFormat; /*!< Specifies the data format for the I2S communication. + This parameter can be a value of @ref I2S_LL_EC_DATA_FORMAT + + This feature can be modified afterwards using unitary + function @ref LL_I2S_SetDataFormat().*/ + + + uint32_t + MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. + This parameter can be a value of @ref I2S_LL_EC_MCLK_OUTPUT + + This feature can be modified afterwards using unitary + functions @ref LL_I2S_EnableMasterClock() or @ref + LL_I2S_DisableMasterClock.*/ + + + uint32_t + AudioFreq; /*!< Specifies the frequency selected for the I2S communication. + This parameter can be a value of @ref I2S_LL_EC_AUDIO_FREQ + + Audio Frequency can be modified afterwards using Reference + manual formulas to calculate Prescaler Linear, Parity and + unitary functions @ref LL_I2S_SetPrescalerLinear() and @ref + LL_I2S_SetPrescalerParity() to set it.*/ + + + uint32_t + ClockPolarity; /*!< Specifies the idle state of the I2S clock. + This parameter can be a value of @ref I2S_LL_EC_POLARITY + + This feature can be modified afterwards using unitary + function @ref LL_I2S_SetClockPolarity().*/ + + } LL_I2S_InitTypeDef; + +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2S_LL_Exported_Constants I2S Exported Constants + * @{ + */ + +/** @defgroup I2S_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_I2S_ReadReg function + * @{ + */ +#define LL_I2S_SR_RXNE LL_SPI_SR_RXNE /*!< Rx buffer not empty flag */ +#define LL_I2S_SR_TXE LL_SPI_SR_TXE /*!< Tx buffer empty flag */ +#define LL_I2S_SR_BSY LL_SPI_SR_BSY /*!< Busy flag */ +#define LL_I2S_SR_UDR SPI_SR_UDR /*!< Underrun flag */ +#define LL_I2S_SR_OVR LL_SPI_SR_OVR /*!< Overrun flag */ +#define LL_I2S_SR_FRE LL_SPI_SR_FRE /*!< TI mode frame format error flag */ +/** + * @} + */ + +/** @defgroup SPI_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg + * functions + * @{ + */ +#define LL_I2S_CR2_RXNEIE LL_SPI_CR2_RXNEIE /*!< Rx buffer not empty interrupt enable */ +#define LL_I2S_CR2_TXEIE LL_SPI_CR2_TXEIE /*!< Tx buffer empty interrupt enable */ +#define LL_I2S_CR2_ERRIE LL_SPI_CR2_ERRIE /*!< Error interrupt enable */ +/** + * @} + */ + +/** @defgroup I2S_LL_EC_DATA_FORMAT Data format + * @{ + */ +#define LL_I2S_DATAFORMAT_16B \ + 0x00000000U /*!< Data length 16 bits, Channel length 16bit */ +#define LL_I2S_DATAFORMAT_16B_EXTENDED \ + (SPI_I2SCFGR_CHLEN) /*!< Data length 16 bits, Channel length 32bit */ +#define LL_I2S_DATAFORMAT_24B \ + (SPI_I2SCFGR_CHLEN | \ + SPI_I2SCFGR_DATLEN_0) /*!< Data length 24 bits, Channel length 32bit */ +#define LL_I2S_DATAFORMAT_32B \ + (SPI_I2SCFGR_CHLEN | \ + SPI_I2SCFGR_DATLEN_1) /*!< Data length 16 bits, Channel length 32bit */ +/** + * @} + */ + +/** @defgroup I2S_LL_EC_POLARITY Clock Polarity + * @{ + */ +#define LL_I2S_POLARITY_LOW 0x00000000U /*!< Clock steady state is low level */ +#define LL_I2S_POLARITY_HIGH \ + (SPI_I2SCFGR_CKPOL) /*!< Clock steady state is high level \ + */ +/** + * @} + */ + +/** @defgroup I2S_LL_EC_STANDARD I2s Standard + * @{ + */ +#define LL_I2S_STANDARD_PHILIPS \ + 0x00000000U /*!< I2S standard philips */ +#define LL_I2S_STANDARD_MSB \ + (SPI_I2SCFGR_I2SSTD_0) /*!< MSB justified standard (left justified) */ +#define LL_I2S_STANDARD_LSB \ + (SPI_I2SCFGR_I2SSTD_1) /*!< LSB justified standard (right justified) */ +#define LL_I2S_STANDARD_PCM_SHORT \ + (SPI_I2SCFGR_I2SSTD_0 | \ + SPI_I2SCFGR_I2SSTD_1) /*!< PCM standard, short frame synchronization */ +#define LL_I2S_STANDARD_PCM_LONG \ + (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | \ + SPI_I2SCFGR_PCMSYNC) /*!< PCM standard, long frame synchronization */ +/** + * @} + */ + +/** @defgroup I2S_LL_EC_MODE Operation Mode + * @{ + */ +#define LL_I2S_MODE_SLAVE_TX 0x00000000U /*!< Slave Tx configuration */ +#define LL_I2S_MODE_SLAVE_RX (SPI_I2SCFGR_I2SCFG_0) /*!< Slave Rx configuration */ +#define LL_I2S_MODE_MASTER_TX (SPI_I2SCFGR_I2SCFG_1) /*!< Master Tx configuration */ +#define LL_I2S_MODE_MASTER_RX \ + (SPI_I2SCFGR_I2SCFG_0 | SPI_I2SCFGR_I2SCFG_1) /*!< Master Rx configuration */ +/** + * @} + */ + +/** @defgroup I2S_LL_EC_PRESCALER_FACTOR Prescaler Factor + * @{ + */ +#define LL_I2S_PRESCALER_PARITY_EVEN \ + 0x00000000U /*!< Odd factor: Real divider value is = I2SDIV * 2 */ +#define LL_I2S_PRESCALER_PARITY_ODD \ + (SPI_I2SPR_ODD >> 8U) /*!< Odd factor: Real divider value is = (I2SDIV * 2)+1 */ + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + +/** @defgroup I2S_LL_EC_MCLK_OUTPUT MCLK Output + * @{ + */ +#define LL_I2S_MCLK_OUTPUT_DISABLE 0x00000000U /*!< Master clock output is disabled */ +#define LL_I2S_MCLK_OUTPUT_ENABLE \ + (SPI_I2SPR_MCKOE) /*!< Master clock output is enabled */ + /** + * @} + */ + + /** @defgroup I2S_LL_EC_AUDIO_FREQ Audio Frequency + * @{ + */ + +#define LL_I2S_AUDIOFREQ_192K \ + 192000U /*!< Audio Frequency configuration 192000 Hz */ +#define LL_I2S_AUDIOFREQ_96K 96000U /*!< Audio Frequency configuration 96000 Hz */ +#define LL_I2S_AUDIOFREQ_48K 48000U /*!< Audio Frequency configuration 48000 Hz */ +#define LL_I2S_AUDIOFREQ_44K 44100U /*!< Audio Frequency configuration 44100 Hz */ +#define LL_I2S_AUDIOFREQ_32K 32000U /*!< Audio Frequency configuration 32000 Hz */ +#define LL_I2S_AUDIOFREQ_22K 22050U /*!< Audio Frequency configuration 22050 Hz */ +#define LL_I2S_AUDIOFREQ_16K 16000U /*!< Audio Frequency configuration 16000 Hz */ +#define LL_I2S_AUDIOFREQ_11K 11025U /*!< Audio Frequency configuration 11025 Hz */ +#define LL_I2S_AUDIOFREQ_8K 8000U /*!< Audio Frequency configuration 8000 Hz */ +#define LL_I2S_AUDIOFREQ_DEFAULT \ + 2U /*!< Audio Freq not specified. Register I2SDIV = 2 \ + */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2S_LL_Exported_Macros I2S Exported Macros + * @{ + */ + +/** @defgroup I2S_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in I2S register + * @param __INSTANCE__ I2S Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_I2S_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in I2S register + * @param __INSTANCE__ I2S Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_I2S_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) + /** + * @} + */ + + /** + * @} + */ + + + /* Exported functions --------------------------------------------------------*/ + + /** @defgroup I2S_LL_Exported_Functions I2S Exported Functions + * @{ + */ + + /** @defgroup I2S_LL_EF_Configuration Configuration + * @{ + */ + + /** + * @brief Select I2S mode and Enable I2S peripheral + * @rmtoll I2SCFGR I2SMOD LL_I2S_Enable\n + * I2SCFGR I2SE LL_I2S_Enable + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_Enable(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SE); + } + + /** + * @brief Disable I2S peripheral + * @rmtoll I2SCFGR I2SE LL_I2S_Disable + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_Disable(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SE); + } + + /** + * @brief Check if I2S peripheral is enabled + * @rmtoll I2SCFGR I2SE LL_I2S_IsEnabled + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsEnabled(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SE) == (SPI_I2SCFGR_I2SE)) ? 1UL + : 0UL); + } + + /** + * @brief Set I2S data frame length + * @rmtoll I2SCFGR DATLEN LL_I2S_SetDataFormat\n + * I2SCFGR CHLEN LL_I2S_SetDataFormat + * @param SPIx SPI Instance + * @param DataFormat This parameter can be one of the following values: + * @arg @ref LL_I2S_DATAFORMAT_16B + * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED + * @arg @ref LL_I2S_DATAFORMAT_24B + * @arg @ref LL_I2S_DATAFORMAT_32B + * @retval None + */ + __STATIC_INLINE void LL_I2S_SetDataFormat(SPI_TypeDef *SPIx, uint32_t DataFormat) + { + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN, DataFormat); + } + + /** + * @brief Get I2S data frame length + * @rmtoll I2SCFGR DATLEN LL_I2S_GetDataFormat\n + * I2SCFGR CHLEN LL_I2S_GetDataFormat + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2S_DATAFORMAT_16B + * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED + * @arg @ref LL_I2S_DATAFORMAT_24B + * @arg @ref LL_I2S_DATAFORMAT_32B + */ + __STATIC_INLINE uint32_t LL_I2S_GetDataFormat(SPI_TypeDef *SPIx) + { + return ( + uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)); + } + + /** + * @brief Set I2S clock polarity + * @rmtoll I2SCFGR CKPOL LL_I2S_SetClockPolarity + * @param SPIx SPI Instance + * @param ClockPolarity This parameter can be one of the following values: + * @arg @ref LL_I2S_POLARITY_LOW + * @arg @ref LL_I2S_POLARITY_HIGH + * @retval None + */ + __STATIC_INLINE void LL_I2S_SetClockPolarity(SPI_TypeDef *SPIx, + uint32_t ClockPolarity) + { + SET_BIT(SPIx->I2SCFGR, ClockPolarity); + } + + /** + * @brief Get I2S clock polarity + * @rmtoll I2SCFGR CKPOL LL_I2S_GetClockPolarity + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2S_POLARITY_LOW + * @arg @ref LL_I2S_POLARITY_HIGH + */ + __STATIC_INLINE uint32_t LL_I2S_GetClockPolarity(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_CKPOL)); + } + + /** + * @brief Set I2S standard protocol + * @rmtoll I2SCFGR I2SSTD LL_I2S_SetStandard\n + * I2SCFGR PCMSYNC LL_I2S_SetStandard + * @param SPIx SPI Instance + * @param Standard This parameter can be one of the following values: + * @arg @ref LL_I2S_STANDARD_PHILIPS + * @arg @ref LL_I2S_STANDARD_MSB + * @arg @ref LL_I2S_STANDARD_LSB + * @arg @ref LL_I2S_STANDARD_PCM_SHORT + * @arg @ref LL_I2S_STANDARD_PCM_LONG + * @retval None + */ + __STATIC_INLINE void LL_I2S_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard) + { + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC, Standard); + } + + /** + * @brief Get I2S standard protocol + * @rmtoll I2SCFGR I2SSTD LL_I2S_GetStandard\n + * I2SCFGR PCMSYNC LL_I2S_GetStandard + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2S_STANDARD_PHILIPS + * @arg @ref LL_I2S_STANDARD_MSB + * @arg @ref LL_I2S_STANDARD_LSB + * @arg @ref LL_I2S_STANDARD_PCM_SHORT + * @arg @ref LL_I2S_STANDARD_PCM_LONG + */ + __STATIC_INLINE uint32_t LL_I2S_GetStandard(SPI_TypeDef *SPIx) + { + return ( + uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC)); + } + + /** + * @brief Set I2S transfer mode + * @rmtoll I2SCFGR I2SCFG LL_I2S_SetTransferMode + * @param SPIx SPI Instance + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_I2S_MODE_SLAVE_TX + * @arg @ref LL_I2S_MODE_SLAVE_RX + * @arg @ref LL_I2S_MODE_MASTER_TX + * @arg @ref LL_I2S_MODE_MASTER_RX + * @retval None + */ + __STATIC_INLINE void LL_I2S_SetTransferMode(SPI_TypeDef *SPIx, uint32_t Mode) + { + MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG, Mode); + } + + /** + * @brief Get I2S transfer mode + * @rmtoll I2SCFGR I2SCFG LL_I2S_GetTransferMode + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2S_MODE_SLAVE_TX + * @arg @ref LL_I2S_MODE_SLAVE_RX + * @arg @ref LL_I2S_MODE_MASTER_TX + * @arg @ref LL_I2S_MODE_MASTER_RX + */ + __STATIC_INLINE uint32_t LL_I2S_GetTransferMode(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG)); + } + + /** + * @brief Set I2S linear prescaler + * @rmtoll I2SPR I2SDIV LL_I2S_SetPrescalerLinear + * @param SPIx SPI Instance + * @param PrescalerLinear Value between Min_Data=0x02 and Max_Data=0xFF + * @retval None + */ + __STATIC_INLINE void LL_I2S_SetPrescalerLinear(SPI_TypeDef *SPIx, + uint8_t PrescalerLinear) + { + MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV, PrescalerLinear); + } + + /** + * @brief Get I2S linear prescaler + * @rmtoll I2SPR I2SDIV LL_I2S_GetPrescalerLinear + * @param SPIx SPI Instance + * @retval PrescalerLinear Value between Min_Data=0x02 and Max_Data=0xFF + */ + __STATIC_INLINE uint32_t LL_I2S_GetPrescalerLinear(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_I2SDIV)); + } + + /** + * @brief Set I2S parity prescaler + * @rmtoll I2SPR ODD LL_I2S_SetPrescalerParity + * @param SPIx SPI Instance + * @param PrescalerParity This parameter can be one of the following values: + * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN + * @arg @ref LL_I2S_PRESCALER_PARITY_ODD + * @retval None + */ + __STATIC_INLINE void LL_I2S_SetPrescalerParity(SPI_TypeDef *SPIx, + uint32_t PrescalerParity) + { + MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_ODD, PrescalerParity << 8U); + } + + /** + * @brief Get I2S parity prescaler + * @rmtoll I2SPR ODD LL_I2S_GetPrescalerParity + * @param SPIx SPI Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN + * @arg @ref LL_I2S_PRESCALER_PARITY_ODD + */ + __STATIC_INLINE uint32_t LL_I2S_GetPrescalerParity(SPI_TypeDef *SPIx) + { + return (uint32_t)(READ_BIT(SPIx->I2SPR, SPI_I2SPR_ODD) >> 8U); + } + + /** + * @brief Enable the master clock output (Pin MCK) + * @rmtoll I2SPR MCKOE LL_I2S_EnableMasterClock + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_EnableMasterClock(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE); + } + + /** + * @brief Disable the master clock output (Pin MCK) + * @rmtoll I2SPR MCKOE LL_I2S_DisableMasterClock + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_DisableMasterClock(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE); + } + + /** + * @brief Check if the master clock output (Pin MCK) is enabled + * @rmtoll I2SPR MCKOE LL_I2S_IsEnabledMasterClock + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsEnabledMasterClock(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->I2SPR, SPI_I2SPR_MCKOE) == (SPI_I2SPR_MCKOE)) ? 1UL + : 0UL); + } + +#if defined(SPI_I2SCFGR_ASTRTEN) + /** + * @brief Enable asynchronous start + * @rmtoll I2SCFGR ASTRTEN LL_I2S_EnableAsyncStart + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_EnableAsyncStart(SPI_TypeDef *SPIx) + { + SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_ASTRTEN); + } + + /** + * @brief Disable asynchronous start + * @rmtoll I2SCFGR ASTRTEN LL_I2S_DisableAsyncStart + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_DisableAsyncStart(SPI_TypeDef *SPIx) + { + CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_ASTRTEN); + } + + /** + * @brief Check if asynchronous start is enabled + * @rmtoll I2SCFGR ASTRTEN LL_I2S_IsEnabledAsyncStart + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsEnabledAsyncStart(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_ASTRTEN) == (SPI_I2SCFGR_ASTRTEN)) + ? 1UL + : 0UL); + } +#endif /* SPI_I2SCFGR_ASTRTEN */ + + /** + * @} + */ + + /** @defgroup I2S_LL_EF_FLAG FLAG Management + * @{ + */ + + /** + * @brief Check if Rx buffer is not empty + * @rmtoll SR RXNE LL_I2S_IsActiveFlag_RXNE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_RXNE(SPI_TypeDef *SPIx) + { + return LL_SPI_IsActiveFlag_RXNE(SPIx); + } + + /** + * @brief Check if Tx buffer is empty + * @rmtoll SR TXE LL_I2S_IsActiveFlag_TXE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_TXE(SPI_TypeDef *SPIx) + { + return LL_SPI_IsActiveFlag_TXE(SPIx); + } + + /** + * @brief Get busy flag + * @rmtoll SR BSY LL_I2S_IsActiveFlag_BSY + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_BSY(SPI_TypeDef *SPIx) + { + return LL_SPI_IsActiveFlag_BSY(SPIx); + } + + /** + * @brief Get overrun error flag + * @rmtoll SR OVR LL_I2S_IsActiveFlag_OVR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_OVR(SPI_TypeDef *SPIx) + { + return LL_SPI_IsActiveFlag_OVR(SPIx); + } + + /** + * @brief Get underrun error flag + * @rmtoll SR UDR LL_I2S_IsActiveFlag_UDR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_UDR(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_UDR) == (SPI_SR_UDR)) ? 1UL : 0UL); + } + + /** + * @brief Get frame format error flag + * @rmtoll SR FRE LL_I2S_IsActiveFlag_FRE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_FRE(SPI_TypeDef *SPIx) + { + return LL_SPI_IsActiveFlag_FRE(SPIx); + } + + /** + * @brief Get channel side flag. + * @note 0: Channel Left has to be transmitted or has been received\n + * 1: Channel Right has to be transmitted or has been received\n + * It has no significance in PCM mode. + * @rmtoll SR CHSIDE LL_I2S_IsActiveFlag_CHSIDE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_CHSIDE(SPI_TypeDef *SPIx) + { + return ((READ_BIT(SPIx->SR, SPI_SR_CHSIDE) == (SPI_SR_CHSIDE)) ? 1UL : 0UL); + } + + /** + * @brief Clear overrun error flag + * @rmtoll SR OVR LL_I2S_ClearFlag_OVR + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_ClearFlag_OVR(SPI_TypeDef *SPIx) + { + LL_SPI_ClearFlag_OVR(SPIx); + } + + /** + * @brief Clear underrun error flag + * @rmtoll SR UDR LL_I2S_ClearFlag_UDR + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_ClearFlag_UDR(SPI_TypeDef *SPIx) + { + __IO uint32_t tmpreg; + tmpreg = SPIx->SR; + (void)tmpreg; + } + + /** + * @brief Clear frame format error flag + * @rmtoll SR FRE LL_I2S_ClearFlag_FRE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_ClearFlag_FRE(SPI_TypeDef *SPIx) + { + LL_SPI_ClearFlag_FRE(SPIx); + } + + /** + * @} + */ + + /** @defgroup I2S_LL_EF_IT Interrupt Management + * @{ + */ + + /** + * @brief Enable error IT + * @note This bit controls the generation of an interrupt when an error condition + * occurs (OVR, UDR and FRE in I2S mode). + * @rmtoll CR2 ERRIE LL_I2S_EnableIT_ERR + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_EnableIT_ERR(SPI_TypeDef *SPIx) + { + LL_SPI_EnableIT_ERR(SPIx); + } + + /** + * @brief Enable Rx buffer not empty IT + * @rmtoll CR2 RXNEIE LL_I2S_EnableIT_RXNE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_EnableIT_RXNE(SPI_TypeDef *SPIx) + { + LL_SPI_EnableIT_RXNE(SPIx); + } + + /** + * @brief Enable Tx buffer empty IT + * @rmtoll CR2 TXEIE LL_I2S_EnableIT_TXE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_EnableIT_TXE(SPI_TypeDef *SPIx) + { + LL_SPI_EnableIT_TXE(SPIx); + } + + /** + * @brief Disable error IT + * @note This bit controls the generation of an interrupt when an error condition + * occurs (OVR, UDR and FRE in I2S mode). + * @rmtoll CR2 ERRIE LL_I2S_DisableIT_ERR + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_DisableIT_ERR(SPI_TypeDef *SPIx) + { + LL_SPI_DisableIT_ERR(SPIx); + } + + /** + * @brief Disable Rx buffer not empty IT + * @rmtoll CR2 RXNEIE LL_I2S_DisableIT_RXNE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_DisableIT_RXNE(SPI_TypeDef *SPIx) + { + LL_SPI_DisableIT_RXNE(SPIx); + } + + /** + * @brief Disable Tx buffer empty IT + * @rmtoll CR2 TXEIE LL_I2S_DisableIT_TXE + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_DisableIT_TXE(SPI_TypeDef *SPIx) + { + LL_SPI_DisableIT_TXE(SPIx); + } + + /** + * @brief Check if ERR IT is enabled + * @rmtoll CR2 ERRIE LL_I2S_IsEnabledIT_ERR + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_ERR(SPI_TypeDef *SPIx) + { + return LL_SPI_IsEnabledIT_ERR(SPIx); + } + + /** + * @brief Check if RXNE IT is enabled + * @rmtoll CR2 RXNEIE LL_I2S_IsEnabledIT_RXNE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_RXNE(SPI_TypeDef *SPIx) + { + return LL_SPI_IsEnabledIT_RXNE(SPIx); + } + + /** + * @brief Check if TXE IT is enabled + * @rmtoll CR2 TXEIE LL_I2S_IsEnabledIT_TXE + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_TXE(SPI_TypeDef *SPIx) + { + return LL_SPI_IsEnabledIT_TXE(SPIx); + } + + /** + * @} + */ + + /** @defgroup I2S_LL_EF_DMA DMA Management + * @{ + */ + + /** + * @brief Enable DMA Rx + * @rmtoll CR2 RXDMAEN LL_I2S_EnableDMAReq_RX + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_EnableDMAReq_RX(SPI_TypeDef *SPIx) + { + LL_SPI_EnableDMAReq_RX(SPIx); + } + + /** + * @brief Disable DMA Rx + * @rmtoll CR2 RXDMAEN LL_I2S_DisableDMAReq_RX + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_DisableDMAReq_RX(SPI_TypeDef *SPIx) + { + LL_SPI_DisableDMAReq_RX(SPIx); + } + + /** + * @brief Check if DMA Rx is enabled + * @rmtoll CR2 RXDMAEN LL_I2S_IsEnabledDMAReq_RX + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_RX(SPI_TypeDef *SPIx) + { + return LL_SPI_IsEnabledDMAReq_RX(SPIx); + } + + /** + * @brief Enable DMA Tx + * @rmtoll CR2 TXDMAEN LL_I2S_EnableDMAReq_TX + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_EnableDMAReq_TX(SPI_TypeDef *SPIx) + { + LL_SPI_EnableDMAReq_TX(SPIx); + } + + /** + * @brief Disable DMA Tx + * @rmtoll CR2 TXDMAEN LL_I2S_DisableDMAReq_TX + * @param SPIx SPI Instance + * @retval None + */ + __STATIC_INLINE void LL_I2S_DisableDMAReq_TX(SPI_TypeDef *SPIx) + { + LL_SPI_DisableDMAReq_TX(SPIx); + } + + /** + * @brief Check if DMA Tx is enabled + * @rmtoll CR2 TXDMAEN LL_I2S_IsEnabledDMAReq_TX + * @param SPIx SPI Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_TX(SPI_TypeDef *SPIx) + { + return LL_SPI_IsEnabledDMAReq_TX(SPIx); + } + + /** + * @} + */ + + /** @defgroup I2S_LL_EF_DATA DATA Management + * @{ + */ + + /** + * @brief Read 16-Bits in data register + * @rmtoll DR DR LL_I2S_ReceiveData16 + * @param SPIx SPI Instance + * @retval RxData Value between Min_Data=0x0000 and Max_Data=0xFFFF + */ + __STATIC_INLINE uint16_t LL_I2S_ReceiveData16(SPI_TypeDef *SPIx) + { + return LL_SPI_ReceiveData16(SPIx); + } + + /** + * @brief Write 16-Bits in data register + * @rmtoll DR DR LL_I2S_TransmitData16 + * @param SPIx SPI Instance + * @param TxData Value between Min_Data=0x0000 and Max_Data=0xFFFF + * @retval None + */ + __STATIC_INLINE void LL_I2S_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData) + { + LL_SPI_TransmitData16(SPIx, TxData); + } + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup I2S_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + + ErrorStatus LL_I2S_DeInit(SPI_TypeDef *SPIx); + ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct); + void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct); + void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, + uint32_t PrescalerParity); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* SPI_I2S_SUPPORT */ + +#endif /* defined (SPI1) || defined (SPI2) */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_LL_SPI_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_system.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_system.h new file mode 100644 index 0000000000..7fb93e9472 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_system.h @@ -0,0 +1,2078 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_system.h + * @author MCD Application Team + * @brief Header file of SYSTEM LL module. + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The LL SYSTEM driver contains a set of generic APIs that can be + used by user: + (+) Some of the FLASH features need to be handled in the SYSTEM file. + (+) Access to DBGCMU registers + (+) Access to SYSCFG registers + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_SYSTEM_H +#define __STM32F0xx_LL_SYSTEM_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(FLASH) || defined(SYSCFG) || defined(DBGMCU) + +/** @defgroup SYSTEM_LL SYSTEM + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SYSTEM_LL_Private_Constants SYSTEM Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SYSTEM_LL_Exported_Constants SYSTEM Exported Constants + * @{ + */ + +/** @defgroup SYSTEM_LL_EC_REMAP SYSCFG Remap + * @{ + */ +#define LL_SYSCFG_REMAP_FLASH \ + (uint32_t)0x00000000U /*!< Main Flash memory mapped at 0x00000000 */ +#define LL_SYSCFG_REMAP_SYSTEMFLASH \ + SYSCFG_CFGR1_MEM_MODE_0 /*!< System Flash memory mapped at 0x00000000 */ +#define LL_SYSCFG_REMAP_SRAM \ + (SYSCFG_CFGR1_MEM_MODE_1 | \ + SYSCFG_CFGR1_MEM_MODE_0) /*!< Embedded SRAM mapped at 0x00000000 */ + /** + * @} + */ + +#if defined(SYSCFG_CFGR1_IR_MOD) +/** @defgroup SYSTEM_LL_EC_IR_MOD SYSCFG IR Modulation + * @{ + */ +#define LL_SYSCFG_IR_MOD_TIM16 \ + (SYSCFG_CFGR1_IR_MOD_0 & \ + SYSCFG_CFGR1_IR_MOD_1) /*!< Timer16 is selected as IR Modulation envelope source */ +#define LL_SYSCFG_IR_MOD_USART1 \ + (SYSCFG_CFGR1_IR_MOD_0) /*!< USART1 is selected as IR Modulation envelope source */ +#define LL_SYSCFG_IR_MOD_USART4 \ + (SYSCFG_CFGR1_IR_MOD_1) /*!< USART4 is selected as IR Modulation envelope source */ + /** + * @} + */ + +#endif /* SYSCFG_CFGR1_IR_MOD */ + +#if defined(SYSCFG_CFGR1_USART1TX_DMA_RMP) || defined(SYSCFG_CFGR1_USART1RX_DMA_RMP) || \ + defined(SYSCFG_CFGR1_USART2_DMA_RMP) || defined(SYSCFG_CFGR1_USART3_DMA_RMP) +/** @defgroup SYSTEM_LL_EC_USART1TX_RMP SYSCFG USART DMA Remap + * @{ + */ +#if defined(SYSCFG_CFGR1_USART1TX_DMA_RMP) +#define LL_SYSCFG_USART1TX_RMP_DMA1CH2 \ + ((SYSCFG_CFGR1_USART1TX_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< USART1_TX DMA request mapped on DMA channel 2U */ +#define LL_SYSCFG_USART1TX_RMP_DMA1CH4 \ + ((SYSCFG_CFGR1_USART1TX_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_USART1TX_DMA_RMP) /*!< USART1_TX DMA request mapped on DMA channel 4U \ + */ +#endif /*SYSCFG_CFGR1_USART1TX_DMA_RMP*/ +#if defined(SYSCFG_CFGR1_USART1RX_DMA_RMP) +#define LL_SYSCFG_USART1RX_RMP_DMA1CH3 \ + ((SYSCFG_CFGR1_USART1RX_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< USART1_RX DMA request mapped on DMA channel 3U */ +#define LL_SYSCFG_USART1RX_RMP_DMA1CH5 \ + ((SYSCFG_CFGR1_USART1RX_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_USART1RX_DMA_RMP) /*!< USART1_RX DMA request mapped on DMA channel 5 \ + */ +#endif /*SYSCFG_CFGR1_USART1RX_DMA_RMP*/ +#if defined(SYSCFG_CFGR1_USART2_DMA_RMP) +#define LL_SYSCFG_USART2_RMP_DMA1CH54 \ + ((SYSCFG_CFGR1_USART2_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< USART2_RX and USART2_TX DMA requests mapped on DMA \ + channel 5 and 4U respectively */ +#define LL_SYSCFG_USART2_RMP_DMA1CH67 \ + ((SYSCFG_CFGR1_USART2_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_USART2_DMA_RMP) /*!< USART2_RX and USART2_TX DMA requests mapped on \ + DMA channel 6 and 7 respectively */ +#endif /*SYSCFG_CFGR1_USART2_DMA_RMP*/ +#if defined(SYSCFG_CFGR1_USART3_DMA_RMP) +#define LL_SYSCFG_USART3_RMP_DMA1CH67 \ + ((SYSCFG_CFGR1_USART3_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< USART3_RX and USART3_TX DMA requests mapped on DMA \ + channel 6 and 7 respectively */ +#define LL_SYSCFG_USART3_RMP_DMA1CH32 \ + ((SYSCFG_CFGR1_USART3_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_USART3_DMA_RMP) /*!< USART3_RX and USART3_TX DMA requests mapped on \ + DMA channel 3U and 2U respectively */ +#endif /* SYSCFG_CFGR1_USART3_DMA_RMP */ +/** + * @} + */ +#endif /* SYSCFG_CFGR1_USART1TX_DMA_RMP || SYSCFG_CFGR1_USART1RX_DMA_RMP || \ + SYSCFG_CFGR1_USART2_DMA_RMP || SYSCFG_CFGR1_USART3_DMA_RMP */ + +#if defined(SYSCFG_CFGR1_SPI2_DMA_RMP) +/** @defgroup SYSTEM_LL_EC_SPI2_RMP_DMA1 SYSCFG SPI2 DMA Remap + * @{ + */ +#define LL_SYSCFG_SPI2_RMP_DMA1_CH45 \ + (uint32_t)0x00000000U /*!< SPI2_RX and SPI2_TX DMA requests mapped on DMA channel 4U \ + and 5 respectively */ +#define LL_SYSCFG_SPI2_RMP_DMA1_CH67 \ + SYSCFG_CFGR1_SPI2_DMA_RMP /*!< SPI2_RX and SPI2_TX DMA requests mapped on DMA \ + channel 6 and 7 respectively */ + /** + * @} + */ + +#endif /*SYSCFG_CFGR1_SPI2_DMA_RMP*/ + +#if defined(SYSCFG_CFGR1_I2C1_DMA_RMP) +/** @defgroup SYSTEM_LL_EC_I2C1_RMP_DMA1 SYSCFG I2C1 DMA Remap + * @{ + */ +#define LL_SYSCFG_I2C1_RMP_DMA1_CH32 \ + (uint32_t)0x00000000U /*!< I2C1_RX and I2C1_TX DMA requests mapped on DMA channel 3U \ + and 2U respectively */ +#define LL_SYSCFG_I2C1_RMP_DMA1_CH76 \ + SYSCFG_CFGR1_I2C1_DMA_RMP /*!< I2C1_RX and I2C1_TX DMA requests mapped on DMA \ + channel 7 and 6 respectively */ + /** + * @} + */ + +#endif /*SYSCFG_CFGR1_I2C1_DMA_RMP*/ + +#if defined(SYSCFG_CFGR1_ADC_DMA_RMP) +/** @defgroup SYSTEM_LL_EC_ADC1_RMP_DMA1 SYSCFG ADC1 DMA Remap + * @{ + */ +#define LL_SYSCFG_ADC1_RMP_DMA1_CH1 \ + (uint32_t)0x00000000U /*!< ADC DMA request mapped on DMA channel 1U */ +#define LL_SYSCFG_ADC1_RMP_DMA1_CH2 \ + SYSCFG_CFGR1_ADC_DMA_RMP /*!< ADC DMA request mapped on DMA channel 2U */ + /** + * @} + */ + +#endif /* SYSCFG_CFGR1_ADC_DMA_RMP */ + +#if defined(SYSCFG_CFGR1_TIM16_DMA_RMP) || defined(SYSCFG_CFGR1_TIM17_DMA_RMP) || \ + defined(SYSCFG_CFGR1_TIM1_DMA_RMP) || defined(SYSCFG_CFGR1_TIM2_DMA_RMP) || \ + defined(SYSCFG_CFGR1_TIM3_DMA_RMP) +/** @defgroup SYSTEM_LL_EC_TIM16_RMP_DMA1 SYSCFG TIM DMA Remap + * @{ + */ +#if defined(SYSCFG_CFGR1_TIM16_DMA_RMP) +#if defined(SYSCFG_CFGR1_TIM16_DMA_RMP2) +#define LL_SYSCFG_TIM16_RMP_DMA1_CH3 \ + (((SYSCFG_CFGR1_TIM16_DMA_RMP | SYSCFG_CFGR1_TIM16_DMA_RMP2) >> 8U) | \ + (uint32_t)0x00000000U) /*!< TIM16_CH1 and TIM16_UP DMA requests mapped on DMA \ + channel 3 */ +#define LL_SYSCFG_TIM16_RMP_DMA1_CH4 \ + (((SYSCFG_CFGR1_TIM16_DMA_RMP | SYSCFG_CFGR1_TIM16_DMA_RMP2) >> 8U) | \ + SYSCFG_CFGR1_TIM16_DMA_RMP) /*!< TIM16_CH1 and TIM16_UP DMA requests mapped on DMA \ + channel 4 */ +#define LL_SYSCFG_TIM16_RMP_DMA1_CH6 \ + ((SYSCFG_CFGR1_TIM16_DMA_RMP2 >> 8U) | \ + SYSCFG_CFGR1_TIM16_DMA_RMP2) /*!< TIM16_CH1 and TIM16_UP DMA requests mapped on DMA \ + channel 6 */ +#else +#define LL_SYSCFG_TIM16_RMP_DMA1_CH3 \ + ((SYSCFG_CFGR1_TIM16_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< TIM16_CH1 and TIM16_UP DMA requests mapped on DMA \ + channel 3 */ +#define LL_SYSCFG_TIM16_RMP_DMA1_CH4 \ + ((SYSCFG_CFGR1_TIM16_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_TIM16_DMA_RMP) /*!< TIM16_CH1 and TIM16_UP DMA requests mapped on DMA \ + channel 4 */ +#endif /* SYSCFG_CFGR1_TIM16_DMA_RMP2 */ +#endif /* SYSCFG_CFGR1_TIM16_DMA_RMP */ +#if defined(SYSCFG_CFGR1_TIM17_DMA_RMP) +#if defined(SYSCFG_CFGR1_TIM17_DMA_RMP2) +#define LL_SYSCFG_TIM17_RMP_DMA1_CH1 \ + (((SYSCFG_CFGR1_TIM17_DMA_RMP | SYSCFG_CFGR1_TIM17_DMA_RMP2) >> 8U) | \ + (uint32_t)0x00000000U) /*!< TIM17_CH1 and TIM17_UP DMA requests mapped on DMA \ + channel 1 */ +#define LL_SYSCFG_TIM17_RMP_DMA1_CH2 \ + (((SYSCFG_CFGR1_TIM17_DMA_RMP | SYSCFG_CFGR1_TIM17_DMA_RMP2) >> 8U) | \ + SYSCFG_CFGR1_TIM17_DMA_RMP) /*!< TIM17_CH1 and TIM17_UP DMA requests mapped on DMA \ + channel 2 */ +#define LL_SYSCFG_TIM17_RMP_DMA1_CH7 \ + ((SYSCFG_CFGR1_TIM17_DMA_RMP2 >> 8U) | \ + SYSCFG_CFGR1_TIM17_DMA_RMP2) /*!< TIM17_CH1 and TIM17_UP DMA requests mapped on DMA \ + channel 7 */ +#else +#define LL_SYSCFG_TIM17_RMP_DMA1_CH1 \ + ((SYSCFG_CFGR1_TIM17_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< TIM17_CH1 and TIM17_UP DMA requests mapped on DMA \ + channel 1 */ +#define LL_SYSCFG_TIM17_RMP_DMA1_CH2 \ + ((SYSCFG_CFGR1_TIM17_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_TIM17_DMA_RMP) /*!< TIM17_CH1 and TIM17_UP DMA requests mapped on DMA \ + channel 2 */ +#endif /* SYSCFG_CFGR1_TIM17_DMA_RMP2 */ +#endif /* SYSCFG_CFGR1_TIM17_DMA_RMP */ +#if defined(SYSCFG_CFGR1_TIM1_DMA_RMP) +#define LL_SYSCFG_TIM1_RMP_DMA1_CH234 \ + ((SYSCFG_CFGR1_TIM1_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< TIM1_CH1, TIM1_CH2 and TIM1_CH3 DMA requests mapped on \ + DMAchannel 2, 3 and 4 respectively */ +#define LL_SYSCFG_TIM1_RMP_DMA1_CH6 \ + ((SYSCFG_CFGR1_TIM1_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_TIM1_DMA_RMP) /*!< TIM1_CH1, TIM1_CH2 and TIM1_CH3 DMA requests mapped \ + on DMA channel 6 */ +#endif /*SYSCFG_CFGR1_TIM1_DMA_RMP*/ +#if defined(SYSCFG_CFGR1_TIM2_DMA_RMP) +#define LL_SYSCFG_TIM2_RMP_DMA1_CH34 \ + ((SYSCFG_CFGR1_TIM2_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< TIM2_CH2 and TIM2_CH4 DMA requests mapped on DMA \ + channel 3 and 4 respectively */ +#define LL_SYSCFG_TIM2_RMP_DMA1_CH7 \ + ((SYSCFG_CFGR1_TIM2_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_TIM2_DMA_RMP) /*!< TIM2_CH2 and TIM2_CH4 DMA requests mapped on DMA \ + channel 7 */ +#endif /*SYSCFG_CFGR1_TIM2_DMA_RMP*/ +#if defined(SYSCFG_CFGR1_TIM3_DMA_RMP) +#define LL_SYSCFG_TIM3_RMP_DMA1_CH4 \ + ((SYSCFG_CFGR1_TIM3_DMA_RMP >> 8U) | \ + (uint32_t)0x00000000U) /*!< TIM3_CH1 and TIM3_TRIG DMA requests mapped on DMA \ + channel 4 */ +#define LL_SYSCFG_TIM3_RMP_DMA1_CH6 \ + ((SYSCFG_CFGR1_TIM3_DMA_RMP >> 8U) | \ + SYSCFG_CFGR1_TIM3_DMA_RMP) /*!< TIM3_CH1 and TIM3_TRIG DMA requests mapped on DMA \ + channel 6 */ +#endif /*SYSCFG_CFGR1_TIM3_DMA_RMP*/ + /** + * @} + */ + +#endif /* SYSCFG_CFGR1_TIM16_DMA_RMP || SYSCFG_CFGR1_TIM17_DMA_RMP || \ + SYSCFG_CFGR1_TIM1_DMA_RMP || SYSCFG_CFGR1_TIM2_DMA_RMP || \ + SYSCFG_CFGR1_TIM3_DMA_RMP */ + +/** @defgroup SYSTEM_LL_EC_I2C_FASTMODEPLUS SYSCFG I2C FASTMODEPLUS + * @{ + */ +#define LL_SYSCFG_I2C_FASTMODEPLUS_PB6 \ + SYSCFG_CFGR1_I2C_FMP_PB6 /*!< I2C PB6 Fast mode plus */ +#define LL_SYSCFG_I2C_FASTMODEPLUS_PB7 \ + SYSCFG_CFGR1_I2C_FMP_PB7 /*!< I2C PB7 Fast mode plus */ +#define LL_SYSCFG_I2C_FASTMODEPLUS_PB8 \ + SYSCFG_CFGR1_I2C_FMP_PB8 /*!< I2C PB8 Fast mode plus */ +#define LL_SYSCFG_I2C_FASTMODEPLUS_PB9 \ + SYSCFG_CFGR1_I2C_FMP_PB9 /*!< I2C PB9 Fast mode plus */ +#if defined(SYSCFG_CFGR1_I2C_FMP_I2C1) +#define LL_SYSCFG_I2C_FASTMODEPLUS_I2C1 \ + SYSCFG_CFGR1_I2C_FMP_I2C1 /*!< Enable Fast Mode Plus on PB10, PB11, PF6 and PF7 */ +#endif /*SYSCFG_CFGR1_I2C_FMP_I2C1*/ +#if defined(SYSCFG_CFGR1_I2C_FMP_I2C2) +#define LL_SYSCFG_I2C_FASTMODEPLUS_I2C2 \ + SYSCFG_CFGR1_I2C_FMP_I2C2 /*!< Enable I2C2 Fast mode plus */ +#endif /*SYSCFG_CFGR1_I2C_FMP_I2C2*/ +#if defined(SYSCFG_CFGR1_I2C_FMP_PA9) +#define LL_SYSCFG_I2C_FASTMODEPLUS_PA9 \ + SYSCFG_CFGR1_I2C_FMP_PA9 /*!< Enable Fast Mode Plus on PA9 */ +#endif /*SYSCFG_CFGR1_I2C_FMP_PA9*/ +#if defined(SYSCFG_CFGR1_I2C_FMP_PA10) +#define LL_SYSCFG_I2C_FASTMODEPLUS_PA10 \ + SYSCFG_CFGR1_I2C_FMP_PA10 /*!< Enable Fast Mode Plus on PA10 */ +#endif /*SYSCFG_CFGR1_I2C_FMP_PA10*/ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_EXTI_PORT SYSCFG EXTI PORT + * @{ + */ +#define LL_SYSCFG_EXTI_PORTA (uint32_t)0U /*!< EXTI PORT A */ +#define LL_SYSCFG_EXTI_PORTB (uint32_t)1U /*!< EXTI PORT B */ +#define LL_SYSCFG_EXTI_PORTC (uint32_t)2U /*!< EXTI PORT C */ +#if defined(GPIOD_BASE) +#define LL_SYSCFG_EXTI_PORTD (uint32_t)3U /*!< EXTI PORT D */ +#endif /*GPIOD_BASE*/ +#if defined(GPIOE_BASE) +#define LL_SYSCFG_EXTI_PORTE (uint32_t)4U /*!< EXTI PORT E */ +#endif /*GPIOE_BASE*/ +#define LL_SYSCFG_EXTI_PORTF (uint32_t)5U /*!< EXTI PORT F */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_EXTI_LINE SYSCFG EXTI LINE + * @{ + */ +#define LL_SYSCFG_EXTI_LINE0 \ + (uint32_t)(0U << 16U | 0U) /*!< EXTI_POSITION_0 | EXTICR[0] */ +#define LL_SYSCFG_EXTI_LINE1 \ + (uint32_t)(4U << 16U | 0U) /*!< EXTI_POSITION_4 | EXTICR[0] */ +#define LL_SYSCFG_EXTI_LINE2 \ + (uint32_t)(8U << 16U | 0U) /*!< EXTI_POSITION_8 | EXTICR[0] */ +#define LL_SYSCFG_EXTI_LINE3 \ + (uint32_t)(12U << 16U | 0U) /*!< EXTI_POSITION_12 | EXTICR[0] */ +#define LL_SYSCFG_EXTI_LINE4 \ + (uint32_t)(0U << 16U | 1U) /*!< EXTI_POSITION_0 | EXTICR[1] */ +#define LL_SYSCFG_EXTI_LINE5 \ + (uint32_t)(4U << 16U | 1U) /*!< EXTI_POSITION_4 | EXTICR[1] */ +#define LL_SYSCFG_EXTI_LINE6 \ + (uint32_t)(8U << 16U | 1U) /*!< EXTI_POSITION_8 | EXTICR[1] */ +#define LL_SYSCFG_EXTI_LINE7 \ + (uint32_t)(12U << 16U | 1U) /*!< EXTI_POSITION_12 | EXTICR[1] */ +#define LL_SYSCFG_EXTI_LINE8 \ + (uint32_t)(0U << 16U | 2U) /*!< EXTI_POSITION_0 | EXTICR[2] */ +#define LL_SYSCFG_EXTI_LINE9 \ + (uint32_t)(4U << 16U | 2U) /*!< EXTI_POSITION_4 | EXTICR[2] */ +#define LL_SYSCFG_EXTI_LINE10 \ + (uint32_t)(8U << 16U | 2U) /*!< EXTI_POSITION_8 | EXTICR[2] */ +#define LL_SYSCFG_EXTI_LINE11 \ + (uint32_t)(12U << 16U | 2U) /*!< EXTI_POSITION_12 | EXTICR[2] */ +#define LL_SYSCFG_EXTI_LINE12 \ + (uint32_t)(0U << 16U | 3U) /*!< EXTI_POSITION_0 | EXTICR[3] */ +#define LL_SYSCFG_EXTI_LINE13 \ + (uint32_t)(4U << 16U | 3U) /*!< EXTI_POSITION_4 | EXTICR[3] */ +#define LL_SYSCFG_EXTI_LINE14 \ + (uint32_t)(8U << 16U | 3U) /*!< EXTI_POSITION_8 | EXTICR[3] */ +#define LL_SYSCFG_EXTI_LINE15 \ + (uint32_t)(12U << 16U | 3U) /*!< EXTI_POSITION_12 | EXTICR[3] */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_TIMBREAK SYSCFG TIMER BREAK + * @{ + */ +#if defined(SYSCFG_CFGR2_PVD_LOCK) +#define LL_SYSCFG_TIMBREAK_PVD \ + SYSCFG_CFGR2_PVD_LOCK /*!< Enables and locks the PVD connection \ + with TIM1/15/16U/17 Break Input and also \ + the PVDE and PLS bits of the Power Control Interface */ +#endif /*SYSCFG_CFGR2_PVD_LOCK*/ +#define LL_SYSCFG_TIMBREAK_SRAM_PARITY \ + SYSCFG_CFGR2_SRAM_PARITY_LOCK /*!< Enables and locks the SRAM_PARITY error signal \ + with Break Input of TIM1/15/16/17 */ +#define LL_SYSCFG_TIMBREAK_LOCKUP \ + SYSCFG_CFGR2_LOCKUP_LOCK /*!< Enables and locks the LOCKUP (Hardfault) output of \ + CortexM0 with Break Input of TIM1/15/16/17 */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_APB1_GRP1_STOP_IP DBGMCU APB1 GRP1 STOP IP + * @{ + */ +#if defined(DBGMCU_APB1_FZ_DBG_TIM2_STOP) +#define LL_DBGMCU_APB1_GRP1_TIM2_STOP \ + DBGMCU_APB1_FZ_DBG_TIM2_STOP /*!< TIM2 counter stopped when core is halted */ +#endif /*DBGMCU_APB1_FZ_DBG_TIM2_STOP*/ +#define LL_DBGMCU_APB1_GRP1_TIM3_STOP \ + DBGMCU_APB1_FZ_DBG_TIM3_STOP /*!< TIM3 counter stopped when core is halted */ +#if defined(DBGMCU_APB1_FZ_DBG_TIM6_STOP) +#define LL_DBGMCU_APB1_GRP1_TIM6_STOP \ + DBGMCU_APB1_FZ_DBG_TIM6_STOP /*!< TIM6 counter stopped when core is halted */ +#endif /*DBGMCU_APB1_FZ_DBG_TIM6_STOP*/ +#if defined(DBGMCU_APB1_FZ_DBG_TIM7_STOP) +#define LL_DBGMCU_APB1_GRP1_TIM7_STOP \ + DBGMCU_APB1_FZ_DBG_TIM7_STOP /*!< TIM7 counter stopped when core is halted */ +#endif /*DBGMCU_APB1_FZ_DBG_TIM7_STOP*/ +#define LL_DBGMCU_APB1_GRP1_TIM14_STOP \ + DBGMCU_APB1_FZ_DBG_TIM14_STOP /*!< TIM14 counter stopped when core is halted */ +#define LL_DBGMCU_APB1_GRP1_RTC_STOP \ + DBGMCU_APB1_FZ_DBG_RTC_STOP /*!< RTC Calendar frozen when core is halted */ +#define LL_DBGMCU_APB1_GRP1_WWDG_STOP \ + DBGMCU_APB1_FZ_DBG_WWDG_STOP /*!< Debug Window Watchdog stopped when Core is halted \ + */ +#define LL_DBGMCU_APB1_GRP1_IWDG_STOP \ + DBGMCU_APB1_FZ_DBG_IWDG_STOP /*!< Debug Independent Watchdog stopped when Core is \ + halted */ +#define LL_DBGMCU_APB1_GRP1_I2C1_STOP \ + DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT /*!< I2C1 SMBUS timeout mode stopped when Core \ + is halted */ +#if defined(DBGMCU_APB1_FZ_DBG_CAN_STOP) +#define LL_DBGMCU_APB1_GRP1_CAN_STOP \ + DBGMCU_APB1_FZ_DBG_CAN_STOP /*!< CAN debug stopped when Core is halted */ +#endif /*DBGMCU_APB1_FZ_DBG_CAN_STOP*/ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_APB1 GRP2_STOP_IP DBGMCU APB1 GRP2 STOP IP + * @{ + */ +#define LL_DBGMCU_APB1_GRP2_TIM1_STOP \ + DBGMCU_APB2_FZ_DBG_TIM1_STOP /*!< TIM1 counter stopped when core is halted */ +#if defined(DBGMCU_APB2_FZ_DBG_TIM15_STOP) +#define LL_DBGMCU_APB1_GRP2_TIM15_STOP \ + DBGMCU_APB2_FZ_DBG_TIM15_STOP /*!< TIM15 counter stopped when core is halted */ +#endif /*DBGMCU_APB2_FZ_DBG_TIM15_STOP*/ +#define LL_DBGMCU_APB1_GRP2_TIM16_STOP \ + DBGMCU_APB2_FZ_DBG_TIM16_STOP /*!< TIM16 counter stopped when core is halted */ +#define LL_DBGMCU_APB1_GRP2_TIM17_STOP \ + DBGMCU_APB2_FZ_DBG_TIM17_STOP /*!< TIM17 counter stopped when core is halted */ +/** + * @} + */ + +/** @defgroup SYSTEM_LL_EC_LATENCY FLASH LATENCY + * @{ + */ +#define LL_FLASH_LATENCY_0 0x00000000U /*!< FLASH Zero Latency cycle */ +#define LL_FLASH_LATENCY_1 FLASH_ACR_LATENCY /*!< FLASH One Latency cycle */ + /** + * @} + */ + + /** + * @} + */ + + /* Exported macro ------------------------------------------------------------*/ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup SYSTEM_LL_Exported_Functions SYSTEM Exported Functions + * @{ + */ + + /** @defgroup SYSTEM_LL_EF_SYSCFG SYSCFG + * @{ + */ + + /** + * @brief Set memory mapping at address 0x00000000 + * @rmtoll SYSCFG_CFGR1 MEM_MODE LL_SYSCFG_SetRemapMemory + * @param Memory This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_REMAP_FLASH + * @arg @ref LL_SYSCFG_REMAP_SYSTEMFLASH + * @arg @ref LL_SYSCFG_REMAP_SRAM + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetRemapMemory(uint32_t Memory) + { + MODIFY_REG(SYSCFG->CFGR1, SYSCFG_CFGR1_MEM_MODE, Memory); + } + + /** + * @brief Get memory mapping at address 0x00000000 + * @rmtoll SYSCFG_CFGR1 MEM_MODE LL_SYSCFG_GetRemapMemory + * @retval Returned value can be one of the following values: + * @arg @ref LL_SYSCFG_REMAP_FLASH + * @arg @ref LL_SYSCFG_REMAP_SYSTEMFLASH + * @arg @ref LL_SYSCFG_REMAP_SRAM + */ + __STATIC_INLINE uint32_t LL_SYSCFG_GetRemapMemory(void) + { + return (uint32_t)(READ_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_MEM_MODE)); + } + +#if defined(SYSCFG_CFGR1_IR_MOD) + /** + * @brief Set IR Modulation Envelope signal source. + * @rmtoll SYSCFG_CFGR1 IR_MOD LL_SYSCFG_SetIRModEnvelopeSignal + * @param Source This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_IR_MOD_TIM16 + * @arg @ref LL_SYSCFG_IR_MOD_USART1 + * @arg @ref LL_SYSCFG_IR_MOD_USART4 + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetIRModEnvelopeSignal(uint32_t Source) + { + MODIFY_REG(SYSCFG->CFGR1, SYSCFG_CFGR1_IR_MOD, Source); + } + + /** + * @brief Get IR Modulation Envelope signal source. + * @rmtoll SYSCFG_CFGR1 IR_MOD LL_SYSCFG_GetIRModEnvelopeSignal + * @retval Returned value can be one of the following values: + * @arg @ref LL_SYSCFG_IR_MOD_TIM16 + * @arg @ref LL_SYSCFG_IR_MOD_USART1 + * @arg @ref LL_SYSCFG_IR_MOD_USART4 + */ + __STATIC_INLINE uint32_t LL_SYSCFG_GetIRModEnvelopeSignal(void) + { + return (uint32_t)(READ_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_IR_MOD)); + } +#endif /* SYSCFG_CFGR1_IR_MOD */ + +#if defined(SYSCFG_CFGR1_USART1TX_DMA_RMP) || defined(SYSCFG_CFGR1_USART1RX_DMA_RMP) || \ + defined(SYSCFG_CFGR1_USART2_DMA_RMP) || defined(SYSCFG_CFGR1_USART3_DMA_RMP) + /** + * @brief Set DMA request remapping bits for USART + * @rmtoll SYSCFG_CFGR1 USART1TX_DMA_RMP LL_SYSCFG_SetRemapDMA_USART\n + * SYSCFG_CFGR1 USART1RX_DMA_RMP LL_SYSCFG_SetRemapDMA_USART\n + * SYSCFG_CFGR1 USART2_DMA_RMP LL_SYSCFG_SetRemapDMA_USART\n + * SYSCFG_CFGR1 USART3_DMA_RMP LL_SYSCFG_SetRemapDMA_USART + * @param Remap This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_USART1TX_RMP_DMA1CH2 (*) + * @arg @ref LL_SYSCFG_USART1TX_RMP_DMA1CH4 (*) + * @arg @ref LL_SYSCFG_USART1RX_RMP_DMA1CH3 (*) + * @arg @ref LL_SYSCFG_USART1RX_RMP_DMA1CH5 (*) + * @arg @ref LL_SYSCFG_USART2_RMP_DMA1CH54 (*) + * @arg @ref LL_SYSCFG_USART2_RMP_DMA1CH67 (*) + * @arg @ref LL_SYSCFG_USART3_RMP_DMA1CH67 (*) + * @arg @ref LL_SYSCFG_USART3_RMP_DMA1CH32 (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetRemapDMA_USART(uint32_t Remap) + { + MODIFY_REG(SYSCFG->CFGR1, (Remap & 0x00FF00FFU) << 8U, (Remap & 0xFF00FF00U)); + } +#endif /* SYSCFG_CFGR1_USART1TX_DMA_RMP || SYSCFG_CFGR1_USART1RX_DMA_RMP || \ + SYSCFG_CFGR1_USART2_DMA_RMP || SYSCFG_CFGR1_USART3_DMA_RMP */ + +#if defined(SYSCFG_CFGR1_SPI2_DMA_RMP) + /** + * @brief Set DMA request remapping bits for SPI + * @rmtoll SYSCFG_CFGR1 SPI2_DMA_RMP LL_SYSCFG_SetRemapDMA_SPI + * @param Remap This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_SPI2_RMP_DMA1_CH45 + * @arg @ref LL_SYSCFG_SPI2_RMP_DMA1_CH67 + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetRemapDMA_SPI(uint32_t Remap) + { + MODIFY_REG(SYSCFG->CFGR1, SYSCFG_CFGR1_SPI2_DMA_RMP, Remap); + } +#endif /* SYSCFG_CFGR1_SPI2_DMA_RMP */ + +#if defined(SYSCFG_CFGR1_I2C1_DMA_RMP) + /** + * @brief Set DMA request remapping bits for I2C + * @rmtoll SYSCFG_CFGR1 I2C1_DMA_RMP LL_SYSCFG_SetRemapDMA_I2C + * @param Remap This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_I2C1_RMP_DMA1_CH32 + * @arg @ref LL_SYSCFG_I2C1_RMP_DMA1_CH76 + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetRemapDMA_I2C(uint32_t Remap) + { + MODIFY_REG(SYSCFG->CFGR1, SYSCFG_CFGR1_I2C1_DMA_RMP, Remap); + } +#endif /* SYSCFG_CFGR1_I2C1_DMA_RMP */ + +#if defined(SYSCFG_CFGR1_ADC_DMA_RMP) + /** + * @brief Set DMA request remapping bits for ADC + * @rmtoll SYSCFG_CFGR1 ADC_DMA_RMP LL_SYSCFG_SetRemapDMA_ADC + * @param Remap This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_ADC1_RMP_DMA1_CH1 + * @arg @ref LL_SYSCFG_ADC1_RMP_DMA1_CH2 + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetRemapDMA_ADC(uint32_t Remap) + { + MODIFY_REG(SYSCFG->CFGR1, SYSCFG_CFGR1_ADC_DMA_RMP, Remap); + } +#endif /* SYSCFG_CFGR1_ADC_DMA_RMP */ + +#if defined(SYSCFG_CFGR1_TIM16_DMA_RMP) || defined(SYSCFG_CFGR1_TIM17_DMA_RMP) || \ + defined(SYSCFG_CFGR1_TIM1_DMA_RMP) || defined(SYSCFG_CFGR1_TIM2_DMA_RMP) || \ + defined(SYSCFG_CFGR1_TIM3_DMA_RMP) + /** + * @brief Set DMA request remapping bits for TIM + * @rmtoll SYSCFG_CFGR1 TIM16_DMA_RMP LL_SYSCFG_SetRemapDMA_TIM\n + * SYSCFG_CFGR1 TIM17_DMA_RMP LL_SYSCFG_SetRemapDMA_TIM\n + * SYSCFG_CFGR1 TIM16_DMA_RMP2 LL_SYSCFG_SetRemapDMA_TIM\n + * SYSCFG_CFGR1 TIM17_DMA_RMP2 LL_SYSCFG_SetRemapDMA_TIM\n + * SYSCFG_CFGR1 TIM1_DMA_RMP LL_SYSCFG_SetRemapDMA_TIM\n + * SYSCFG_CFGR1 TIM2_DMA_RMP LL_SYSCFG_SetRemapDMA_TIM\n + * SYSCFG_CFGR1 TIM3_DMA_RMP LL_SYSCFG_SetRemapDMA_TIM + * @param Remap This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_TIM16_RMP_DMA1_CH3 (*) + * @arg @ref LL_SYSCFG_TIM16_RMP_DMA1_CH4 (*) + * @arg @ref LL_SYSCFG_TIM16_RMP_DMA1_CH6 (*) + * @arg @ref LL_SYSCFG_TIM17_RMP_DMA1_CH1 (*) + * @arg @ref LL_SYSCFG_TIM17_RMP_DMA1_CH2 (*) + * @arg @ref LL_SYSCFG_TIM17_RMP_DMA1_CH7 (*) + * @arg @ref LL_SYSCFG_TIM1_RMP_DMA1_CH234 (*) + * @arg @ref LL_SYSCFG_TIM1_RMP_DMA1_CH6 (*) + * @arg @ref LL_SYSCFG_TIM2_RMP_DMA1_CH34 (*) + * @arg @ref LL_SYSCFG_TIM2_RMP_DMA1_CH7 (*) + * @arg @ref LL_SYSCFG_TIM3_RMP_DMA1_CH4 (*) + * @arg @ref LL_SYSCFG_TIM3_RMP_DMA1_CH6 (*) + * + * (*) value not defined in all devices. + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetRemapDMA_TIM(uint32_t Remap) + { + MODIFY_REG(SYSCFG->CFGR1, (Remap & 0x00FF00FFU) << 8U, (Remap & 0xFF00FF00U)); + } +#endif /* SYSCFG_CFGR1_TIM16_DMA_RMP || SYSCFG_CFGR1_TIM17_DMA_RMP || \ + SYSCFG_CFGR1_TIM1_DMA_RMP || SYSCFG_CFGR1_TIM2_DMA_RMP || \ + SYSCFG_CFGR1_TIM3_DMA_RMP */ + +#if defined(SYSCFG_CFGR1_PA11_PA12_RMP) + /** + * @brief Enable PIN pair PA11/12 mapped instead of PA9/10 (control the mapping of + * either PA9/10 or PA11/12 pin pair on small pin-count packages) + * @rmtoll SYSCFG_CFGR1 PA11_PA12_RMP LL_SYSCFG_EnablePinRemap + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_EnablePinRemap(void) + { + SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_PA11_PA12_RMP); + } + + /** + * @brief Disable PIN pair PA11/12 mapped instead of PA9/10 (control the mapping of + * either PA9/10 or PA11/12 pin pair on small pin-count packages) + * @rmtoll SYSCFG_CFGR1 PA11_PA12_RMP LL_SYSCFG_DisablePinRemap + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_DisablePinRemap(void) + { + CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_PA11_PA12_RMP); + } +#endif /* SYSCFG_CFGR1_PA11_PA12_RMP */ + + /** + * @brief Enable the I2C fast mode plus driving capability. + * @rmtoll SYSCFG_CFGR1 I2C_FMP_PB6 LL_SYSCFG_EnableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PB7 LL_SYSCFG_EnableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PB8 LL_SYSCFG_EnableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PB9 LL_SYSCFG_EnableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_I2C1 LL_SYSCFG_EnableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_I2C2 LL_SYSCFG_EnableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PA9 LL_SYSCFG_EnableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PA10 LL_SYSCFG_EnableFastModePlus + * @param ConfigFastModePlus This parameter can be a combination of the following + * values: + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PB6 + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PB7 + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PB8 + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PB9 + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_I2C1 (*) + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_I2C2 (*) + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PA9 (*) + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PA10 (*) + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_EnableFastModePlus(uint32_t ConfigFastModePlus) + { + SET_BIT(SYSCFG->CFGR1, ConfigFastModePlus); + } + + /** + * @brief Disable the I2C fast mode plus driving capability. + * @rmtoll SYSCFG_CFGR1 I2C_FMP_PB6 LL_SYSCFG_DisableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PB7 LL_SYSCFG_DisableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PB8 LL_SYSCFG_DisableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PB9 LL_SYSCFG_DisableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_I2C1 LL_SYSCFG_DisableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_I2C2 LL_SYSCFG_DisableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PA9 LL_SYSCFG_DisableFastModePlus\n + * SYSCFG_CFGR1 I2C_FMP_PA10 LL_SYSCFG_DisableFastModePlus + * @param ConfigFastModePlus This parameter can be a combination of the following + * values: + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PB6 + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PB7 + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PB8 + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PB9 + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_I2C1 (*) + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_I2C2 (*) + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PA9 (*) + * @arg @ref LL_SYSCFG_I2C_FASTMODEPLUS_PA10 (*) + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_DisableFastModePlus(uint32_t ConfigFastModePlus) + { + CLEAR_BIT(SYSCFG->CFGR1, ConfigFastModePlus); + } + + /** + * @brief Configure source input for the EXTI external interrupt. + * @rmtoll SYSCFG_EXTICR1 EXTI0 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR1 EXTI1 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR1 EXTI2 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR1 EXTI3 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR2 EXTI4 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR2 EXTI5 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR2 EXTI6 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR2 EXTI7 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR3 EXTI8 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR3 EXTI9 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR3 EXTI10 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR3 EXTI11 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR4 EXTI12 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR4 EXTI13 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR4 EXTI14 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR4 EXTI15 LL_SYSCFG_SetEXTISource + * @param Port This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_EXTI_PORTA + * @arg @ref LL_SYSCFG_EXTI_PORTB + * @arg @ref LL_SYSCFG_EXTI_PORTC + * @arg @ref LL_SYSCFG_EXTI_PORTD (*) + * @arg @ref LL_SYSCFG_EXTI_PORTE (*) + * @arg @ref LL_SYSCFG_EXTI_PORTF + * + * (*) value not defined in all devices + * @param Line This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_EXTI_LINE0 + * @arg @ref LL_SYSCFG_EXTI_LINE1 + * @arg @ref LL_SYSCFG_EXTI_LINE2 + * @arg @ref LL_SYSCFG_EXTI_LINE3 + * @arg @ref LL_SYSCFG_EXTI_LINE4 + * @arg @ref LL_SYSCFG_EXTI_LINE5 + * @arg @ref LL_SYSCFG_EXTI_LINE6 + * @arg @ref LL_SYSCFG_EXTI_LINE7 + * @arg @ref LL_SYSCFG_EXTI_LINE8 + * @arg @ref LL_SYSCFG_EXTI_LINE9 + * @arg @ref LL_SYSCFG_EXTI_LINE10 + * @arg @ref LL_SYSCFG_EXTI_LINE11 + * @arg @ref LL_SYSCFG_EXTI_LINE12 + * @arg @ref LL_SYSCFG_EXTI_LINE13 + * @arg @ref LL_SYSCFG_EXTI_LINE14 + * @arg @ref LL_SYSCFG_EXTI_LINE15 + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetEXTISource(uint32_t Port, uint32_t Line) + { + MODIFY_REG(SYSCFG->EXTICR[Line & 0xFF], SYSCFG_EXTICR1_EXTI0 << (Line >> 16), + Port << (Line >> 16)); + } + + /** + * @brief Get the configured defined for specific EXTI Line + * @rmtoll SYSCFG_EXTICR1 EXTI0 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR1 EXTI1 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR1 EXTI2 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR1 EXTI3 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR2 EXTI4 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR2 EXTI5 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR2 EXTI6 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR2 EXTI7 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR3 EXTI8 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR3 EXTI9 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR3 EXTI10 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR3 EXTI11 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR4 EXTI12 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR4 EXTI13 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR4 EXTI14 LL_SYSCFG_SetEXTISource\n + * SYSCFG_EXTICR4 EXTI15 LL_SYSCFG_SetEXTISource + * @param Line This parameter can be one of the following values: + * @arg @ref LL_SYSCFG_EXTI_LINE0 + * @arg @ref LL_SYSCFG_EXTI_LINE1 + * @arg @ref LL_SYSCFG_EXTI_LINE2 + * @arg @ref LL_SYSCFG_EXTI_LINE3 + * @arg @ref LL_SYSCFG_EXTI_LINE4 + * @arg @ref LL_SYSCFG_EXTI_LINE5 + * @arg @ref LL_SYSCFG_EXTI_LINE6 + * @arg @ref LL_SYSCFG_EXTI_LINE7 + * @arg @ref LL_SYSCFG_EXTI_LINE8 + * @arg @ref LL_SYSCFG_EXTI_LINE9 + * @arg @ref LL_SYSCFG_EXTI_LINE10 + * @arg @ref LL_SYSCFG_EXTI_LINE11 + * @arg @ref LL_SYSCFG_EXTI_LINE12 + * @arg @ref LL_SYSCFG_EXTI_LINE13 + * @arg @ref LL_SYSCFG_EXTI_LINE14 + * @arg @ref LL_SYSCFG_EXTI_LINE15 + * @retval Returned value can be one of the following values: + * @arg @ref LL_SYSCFG_EXTI_PORTA + * @arg @ref LL_SYSCFG_EXTI_PORTB + * @arg @ref LL_SYSCFG_EXTI_PORTC + * @arg @ref LL_SYSCFG_EXTI_PORTD (*) + * @arg @ref LL_SYSCFG_EXTI_PORTE (*) + * @arg @ref LL_SYSCFG_EXTI_PORTF + * + * (*) value not defined in all devices + */ + __STATIC_INLINE uint32_t LL_SYSCFG_GetEXTISource(uint32_t Line) + { + return (uint32_t)(READ_BIT(SYSCFG->EXTICR[Line & 0xFF], + (SYSCFG_EXTICR1_EXTI0 << (Line >> 16))) >> + (Line >> 16)); + } + +#if defined(SYSCFG_ITLINE0_SR_EWDG) + /** + * @brief Check if Window watchdog interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE0 SR_EWDG LL_SYSCFG_IsActiveFlag_WWDG + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_WWDG(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[0], SYSCFG_ITLINE0_SR_EWDG) == + (SYSCFG_ITLINE0_SR_EWDG)); + } +#endif /* SYSCFG_ITLINE0_SR_EWDG */ + +#if defined(SYSCFG_ITLINE1_SR_PVDOUT) + /** + * @brief Check if PVD supply monitoring interrupt occurred or not (EXTI line 16). + * @rmtoll SYSCFG_ITLINE1 SR_PVDOUT LL_SYSCFG_IsActiveFlag_PVDOUT + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_PVDOUT(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[1], SYSCFG_ITLINE1_SR_PVDOUT) == + (SYSCFG_ITLINE1_SR_PVDOUT)); + } +#endif /* SYSCFG_ITLINE1_SR_PVDOUT */ + +#if defined(SYSCFG_ITLINE1_SR_VDDIO2) + /** + * @brief Check if VDDIO2 supply monitoring interrupt occurred or not (EXTI line 31). + * @rmtoll SYSCFG_ITLINE1 SR_VDDIO2 LL_SYSCFG_IsActiveFlag_VDDIO2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_VDDIO2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[1], SYSCFG_ITLINE1_SR_VDDIO2) == + (SYSCFG_ITLINE1_SR_VDDIO2)); + } +#endif /* SYSCFG_ITLINE1_SR_VDDIO2 */ + +#if defined(SYSCFG_ITLINE2_SR_RTC_WAKEUP) + /** + * @brief Check if RTC Wake Up interrupt occurred or not (EXTI line 20). + * @rmtoll SYSCFG_ITLINE2 SR_RTC_WAKEUP LL_SYSCFG_IsActiveFlag_RTC_WAKEUP + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_RTC_WAKEUP(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[2], SYSCFG_ITLINE2_SR_RTC_WAKEUP) == + (SYSCFG_ITLINE2_SR_RTC_WAKEUP)); + } +#endif /* SYSCFG_ITLINE2_SR_RTC_WAKEUP */ + +#if defined(SYSCFG_ITLINE2_SR_RTC_TSTAMP) + /** + * @brief Check if RTC Tamper and TimeStamp interrupt occurred or not (EXTI line 19). + * @rmtoll SYSCFG_ITLINE2 SR_RTC_TSTAMP LL_SYSCFG_IsActiveFlag_RTC_TSTAMP + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_RTC_TSTAMP(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[2], SYSCFG_ITLINE2_SR_RTC_TSTAMP) == + (SYSCFG_ITLINE2_SR_RTC_TSTAMP)); + } +#endif /* SYSCFG_ITLINE2_SR_RTC_TSTAMP */ + +#if defined(SYSCFG_ITLINE2_SR_RTC_ALRA) + /** + * @brief Check if RTC Alarm interrupt occurred or not (EXTI line 17). + * @rmtoll SYSCFG_ITLINE2 SR_RTC_ALRA LL_SYSCFG_IsActiveFlag_RTC_ALRA + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_RTC_ALRA(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[2], SYSCFG_ITLINE2_SR_RTC_ALRA) == + (SYSCFG_ITLINE2_SR_RTC_ALRA)); + } +#endif /* SYSCFG_ITLINE2_SR_RTC_ALRA */ + +#if defined(SYSCFG_ITLINE3_SR_FLASH_ITF) + /** + * @brief Check if Flash interface interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE3 SR_FLASH_ITF LL_SYSCFG_IsActiveFlag_FLASH_ITF + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_FLASH_ITF(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[3], SYSCFG_ITLINE3_SR_FLASH_ITF) == + (SYSCFG_ITLINE3_SR_FLASH_ITF)); + } +#endif /* SYSCFG_ITLINE3_SR_FLASH_ITF */ + +#if defined(SYSCFG_ITLINE4_SR_CRS) + /** + * @brief Check if Clock recovery system interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE4 SR_CRS LL_SYSCFG_IsActiveFlag_CRS + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_CRS(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[4], SYSCFG_ITLINE4_SR_CRS) == + (SYSCFG_ITLINE4_SR_CRS)); + } +#endif /* SYSCFG_ITLINE4_SR_CRS */ + +#if defined(SYSCFG_ITLINE4_SR_CLK_CTRL) + /** + * @brief Check if Reset and clock control interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE4 SR_CLK_CTRL LL_SYSCFG_IsActiveFlag_CLK_CTRL + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_CLK_CTRL(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[4], SYSCFG_ITLINE4_SR_CLK_CTRL) == + (SYSCFG_ITLINE4_SR_CLK_CTRL)); + } +#endif /* SYSCFG_ITLINE4_SR_CLK_CTRL */ + +#if defined(SYSCFG_ITLINE5_SR_EXTI0) + /** + * @brief Check if EXTI line 0 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE5 SR_EXTI0 LL_SYSCFG_IsActiveFlag_EXTI0 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI0(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[5], SYSCFG_ITLINE5_SR_EXTI0) == + (SYSCFG_ITLINE5_SR_EXTI0)); + } +#endif /* SYSCFG_ITLINE5_SR_EXTI0 */ + +#if defined(SYSCFG_ITLINE5_SR_EXTI1) + /** + * @brief Check if EXTI line 1 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE5 SR_EXTI1 LL_SYSCFG_IsActiveFlag_EXTI1 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI1(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[5], SYSCFG_ITLINE5_SR_EXTI1) == + (SYSCFG_ITLINE5_SR_EXTI1)); + } +#endif /* SYSCFG_ITLINE5_SR_EXTI1 */ + +#if defined(SYSCFG_ITLINE6_SR_EXTI2) + /** + * @brief Check if EXTI line 2 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE6 SR_EXTI2 LL_SYSCFG_IsActiveFlag_EXTI2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[6], SYSCFG_ITLINE6_SR_EXTI2) == + (SYSCFG_ITLINE6_SR_EXTI2)); + } +#endif /* SYSCFG_ITLINE6_SR_EXTI2 */ + +#if defined(SYSCFG_ITLINE6_SR_EXTI3) + /** + * @brief Check if EXTI line 3 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE6 SR_EXTI3 LL_SYSCFG_IsActiveFlag_EXTI3 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI3(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[6], SYSCFG_ITLINE6_SR_EXTI3) == + (SYSCFG_ITLINE6_SR_EXTI3)); + } +#endif /* SYSCFG_ITLINE6_SR_EXTI3 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI4) + /** + * @brief Check if EXTI line 4 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI4 LL_SYSCFG_IsActiveFlag_EXTI4 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI4(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI4) == + (SYSCFG_ITLINE7_SR_EXTI4)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI4 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI5) + /** + * @brief Check if EXTI line 5 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI5 LL_SYSCFG_IsActiveFlag_EXTI5 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI5(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI5) == + (SYSCFG_ITLINE7_SR_EXTI5)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI5 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI6) + /** + * @brief Check if EXTI line 6 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI6 LL_SYSCFG_IsActiveFlag_EXTI6 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI6(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI6) == + (SYSCFG_ITLINE7_SR_EXTI6)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI6 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI7) + /** + * @brief Check if EXTI line 7 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI7 LL_SYSCFG_IsActiveFlag_EXTI7 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI7(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI7) == + (SYSCFG_ITLINE7_SR_EXTI7)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI7 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI8) + /** + * @brief Check if EXTI line 8 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI8 LL_SYSCFG_IsActiveFlag_EXTI8 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI8(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI8) == + (SYSCFG_ITLINE7_SR_EXTI8)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI8 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI9) + /** + * @brief Check if EXTI line 9 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI9 LL_SYSCFG_IsActiveFlag_EXTI9 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI9(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI9) == + (SYSCFG_ITLINE7_SR_EXTI9)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI9 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI10) + /** + * @brief Check if EXTI line 10 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI10 LL_SYSCFG_IsActiveFlag_EXTI10 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI10(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI10) == + (SYSCFG_ITLINE7_SR_EXTI10)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI10 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI11) + /** + * @brief Check if EXTI line 11 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI11 LL_SYSCFG_IsActiveFlag_EXTI11 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI11(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI11) == + (SYSCFG_ITLINE7_SR_EXTI11)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI11 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI12) + /** + * @brief Check if EXTI line 12 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI12 LL_SYSCFG_IsActiveFlag_EXTI12 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI12(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI12) == + (SYSCFG_ITLINE7_SR_EXTI12)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI12 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI13) + /** + * @brief Check if EXTI line 13 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI13 LL_SYSCFG_IsActiveFlag_EXTI13 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI13(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI13) == + (SYSCFG_ITLINE7_SR_EXTI13)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI13 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI14) + /** + * @brief Check if EXTI line 14 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI14 LL_SYSCFG_IsActiveFlag_EXTI14 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI14(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI14) == + (SYSCFG_ITLINE7_SR_EXTI14)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI14 */ + +#if defined(SYSCFG_ITLINE7_SR_EXTI15) + /** + * @brief Check if EXTI line 15 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE7 SR_EXTI15 LL_SYSCFG_IsActiveFlag_EXTI15 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_EXTI15(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[7], SYSCFG_ITLINE7_SR_EXTI15) == + (SYSCFG_ITLINE7_SR_EXTI15)); + } +#endif /* SYSCFG_ITLINE7_SR_EXTI15 */ + +#if defined(SYSCFG_ITLINE8_SR_TSC_EOA) + /** + * @brief Check if Touch sensing controller end of acquisition interrupt occurred or + * not. + * @rmtoll SYSCFG_ITLINE8 SR_TSC_EOA LL_SYSCFG_IsActiveFlag_TSC_EOA + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TSC_EOA(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[8], SYSCFG_ITLINE8_SR_TSC_EOA) == + (SYSCFG_ITLINE8_SR_TSC_EOA)); + } +#endif /* SYSCFG_ITLINE8_SR_TSC_EOA */ + +#if defined(SYSCFG_ITLINE8_SR_TSC_MCE) + /** + * @brief Check if Touch sensing controller max counterror interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE8 SR_TSC_MCE LL_SYSCFG_IsActiveFlag_TSC_MCE + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TSC_MCE(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[8], SYSCFG_ITLINE8_SR_TSC_MCE) == + (SYSCFG_ITLINE8_SR_TSC_MCE)); + } +#endif /* SYSCFG_ITLINE8_SR_TSC_MCE */ + +#if defined(SYSCFG_ITLINE9_SR_DMA1_CH1) + /** + * @brief Check if DMA1 channel 1 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE9 SR_DMA1_CH1 LL_SYSCFG_IsActiveFlag_DMA1_CH1 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA1_CH1(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[9], SYSCFG_ITLINE9_SR_DMA1_CH1) == + (SYSCFG_ITLINE9_SR_DMA1_CH1)); + } +#endif /* SYSCFG_ITLINE9_SR_DMA1_CH1 */ + +#if defined(SYSCFG_ITLINE10_SR_DMA1_CH2) + /** + * @brief Check if DMA1 channel 2 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE10 SR_DMA1_CH2 LL_SYSCFG_IsActiveFlag_DMA1_CH2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA1_CH2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[10], SYSCFG_ITLINE10_SR_DMA1_CH2) == + (SYSCFG_ITLINE10_SR_DMA1_CH2)); + } +#endif /* SYSCFG_ITLINE10_SR_DMA1_CH2 */ + +#if defined(SYSCFG_ITLINE10_SR_DMA1_CH3) + /** + * @brief Check if DMA1 channel 3 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE10 SR_DMA1_CH3 LL_SYSCFG_IsActiveFlag_DMA1_CH3 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA1_CH3(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[10], SYSCFG_ITLINE10_SR_DMA1_CH3) == + (SYSCFG_ITLINE10_SR_DMA1_CH3)); + } +#endif /* SYSCFG_ITLINE10_SR_DMA1_CH3 */ + +#if defined(SYSCFG_ITLINE10_SR_DMA2_CH1) + /** + * @brief Check if DMA2 channel 1 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE10 SR_DMA2_CH1 LL_SYSCFG_IsActiveFlag_DMA2_CH1 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA2_CH1(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[10], SYSCFG_ITLINE10_SR_DMA2_CH1) == + (SYSCFG_ITLINE10_SR_DMA2_CH1)); + } +#endif /* SYSCFG_ITLINE10_SR_DMA2_CH1 */ + +#if defined(SYSCFG_ITLINE10_SR_DMA2_CH2) + /** + * @brief Check if DMA2 channel 2 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE10 SR_DMA2_CH2 LL_SYSCFG_IsActiveFlag_DMA2_CH2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA2_CH2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[10], SYSCFG_ITLINE10_SR_DMA2_CH2) == + (SYSCFG_ITLINE10_SR_DMA2_CH2)); + } +#endif /* SYSCFG_ITLINE10_SR_DMA2_CH2 */ + +#if defined(SYSCFG_ITLINE11_SR_DMA1_CH4) + /** + * @brief Check if DMA1 channel 4 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE11 SR_DMA1_CH4 LL_SYSCFG_IsActiveFlag_DMA1_CH4 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA1_CH4(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[11], SYSCFG_ITLINE11_SR_DMA1_CH4) == + (SYSCFG_ITLINE11_SR_DMA1_CH4)); + } +#endif /* SYSCFG_ITLINE11_SR_DMA1_CH4 */ + +#if defined(SYSCFG_ITLINE11_SR_DMA1_CH5) + /** + * @brief Check if DMA1 channel 5 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE11 SR_DMA1_CH5 LL_SYSCFG_IsActiveFlag_DMA1_CH5 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA1_CH5(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[11], SYSCFG_ITLINE11_SR_DMA1_CH5) == + (SYSCFG_ITLINE11_SR_DMA1_CH5)); + } +#endif /* SYSCFG_ITLINE11_SR_DMA1_CH5 */ + +#if defined(SYSCFG_ITLINE11_SR_DMA1_CH6) + /** + * @brief Check if DMA1 channel 6 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE11 SR_DMA1_CH6 LL_SYSCFG_IsActiveFlag_DMA1_CH6 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA1_CH6(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[11], SYSCFG_ITLINE11_SR_DMA1_CH6) == + (SYSCFG_ITLINE11_SR_DMA1_CH6)); + } +#endif /* SYSCFG_ITLINE11_SR_DMA1_CH6 */ + +#if defined(SYSCFG_ITLINE11_SR_DMA1_CH7) + /** + * @brief Check if DMA1 channel 7 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE11 SR_DMA1_CH7 LL_SYSCFG_IsActiveFlag_DMA1_CH7 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA1_CH7(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[11], SYSCFG_ITLINE11_SR_DMA1_CH7) == + (SYSCFG_ITLINE11_SR_DMA1_CH7)); + } +#endif /* SYSCFG_ITLINE11_SR_DMA1_CH7 */ + +#if defined(SYSCFG_ITLINE11_SR_DMA2_CH3) + /** + * @brief Check if DMA2 channel 3 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE11 SR_DMA2_CH3 LL_SYSCFG_IsActiveFlag_DMA2_CH3 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA2_CH3(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[11], SYSCFG_ITLINE11_SR_DMA2_CH3) == + (SYSCFG_ITLINE11_SR_DMA2_CH3)); + } +#endif /* SYSCFG_ITLINE11_SR_DMA2_CH3 */ + +#if defined(SYSCFG_ITLINE11_SR_DMA2_CH4) + /** + * @brief Check if DMA2 channel 4 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE11 SR_DMA2_CH4 LL_SYSCFG_IsActiveFlag_DMA2_CH4 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA2_CH4(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[11], SYSCFG_ITLINE11_SR_DMA2_CH4) == + (SYSCFG_ITLINE11_SR_DMA2_CH4)); + } +#endif /* SYSCFG_ITLINE11_SR_DMA2_CH4 */ + +#if defined(SYSCFG_ITLINE11_SR_DMA2_CH5) + /** + * @brief Check if DMA2 channel 5 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE11 SR_DMA2_CH5 LL_SYSCFG_IsActiveFlag_DMA2_CH5 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DMA2_CH5(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[11], SYSCFG_ITLINE11_SR_DMA2_CH5) == + (SYSCFG_ITLINE11_SR_DMA2_CH5)); + } +#endif /* SYSCFG_ITLINE11_SR_DMA2_CH5 */ + +#if defined(SYSCFG_ITLINE12_SR_ADC) + /** + * @brief Check if ADC interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE12 SR_ADC LL_SYSCFG_IsActiveFlag_ADC + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_ADC(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[12], SYSCFG_ITLINE12_SR_ADC) == + (SYSCFG_ITLINE12_SR_ADC)); + } +#endif /* SYSCFG_ITLINE12_SR_ADC */ + +#if defined(SYSCFG_ITLINE12_SR_COMP1) + /** + * @brief Check if Comparator 1 interrupt occurred or not (EXTI line 21). + * @rmtoll SYSCFG_ITLINE12 SR_COMP1 LL_SYSCFG_IsActiveFlag_COMP1 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_COMP1(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[12], SYSCFG_ITLINE12_SR_COMP1) == + (SYSCFG_ITLINE12_SR_COMP1)); + } +#endif /* SYSCFG_ITLINE12_SR_COMP1 */ + +#if defined(SYSCFG_ITLINE12_SR_COMP2) + /** + * @brief Check if Comparator 2 interrupt occurred or not (EXTI line 22). + * @rmtoll SYSCFG_ITLINE12 SR_COMP2 LL_SYSCFG_IsActiveFlag_COMP2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_COMP2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[12], SYSCFG_ITLINE12_SR_COMP2) == + (SYSCFG_ITLINE12_SR_COMP2)); + } +#endif /* SYSCFG_ITLINE12_SR_COMP2 */ + +#if defined(SYSCFG_ITLINE13_SR_TIM1_BRK) + /** + * @brief Check if Timer 1 break interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE13 SR_TIM1_BRK LL_SYSCFG_IsActiveFlag_TIM1_BRK + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM1_BRK(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[13], SYSCFG_ITLINE13_SR_TIM1_BRK) == + (SYSCFG_ITLINE13_SR_TIM1_BRK)); + } +#endif /* SYSCFG_ITLINE13_SR_TIM1_BRK */ + +#if defined(SYSCFG_ITLINE13_SR_TIM1_UPD) + /** + * @brief Check if Timer 1 update interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE13 SR_TIM1_UPD LL_SYSCFG_IsActiveFlag_TIM1_UPD + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM1_UPD(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[13], SYSCFG_ITLINE13_SR_TIM1_UPD) == + (SYSCFG_ITLINE13_SR_TIM1_UPD)); + } +#endif /* SYSCFG_ITLINE13_SR_TIM1_UPD */ + +#if defined(SYSCFG_ITLINE13_SR_TIM1_TRG) + /** + * @brief Check if Timer 1 trigger interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE13 SR_TIM1_TRG LL_SYSCFG_IsActiveFlag_TIM1_TRG + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM1_TRG(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[13], SYSCFG_ITLINE13_SR_TIM1_TRG) == + (SYSCFG_ITLINE13_SR_TIM1_TRG)); + } +#endif /* SYSCFG_ITLINE13_SR_TIM1_TRG */ + +#if defined(SYSCFG_ITLINE13_SR_TIM1_CCU) + /** + * @brief Check if Timer 1 commutation interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE13 SR_TIM1_CCU LL_SYSCFG_IsActiveFlag_TIM1_CCU + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM1_CCU(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[13], SYSCFG_ITLINE13_SR_TIM1_CCU) == + (SYSCFG_ITLINE13_SR_TIM1_CCU)); + } +#endif /* SYSCFG_ITLINE13_SR_TIM1_CCU */ + +#if defined(SYSCFG_ITLINE14_SR_TIM1_CC) + /** + * @brief Check if Timer 1 capture compare interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE14 SR_TIM1_CC LL_SYSCFG_IsActiveFlag_TIM1_CC + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM1_CC(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[14], SYSCFG_ITLINE14_SR_TIM1_CC) == + (SYSCFG_ITLINE14_SR_TIM1_CC)); + } +#endif /* SYSCFG_ITLINE14_SR_TIM1_CC */ + +#if defined(SYSCFG_ITLINE15_SR_TIM2_GLB) + /** + * @brief Check if Timer 2 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE15 SR_TIM2_GLB LL_SYSCFG_IsActiveFlag_TIM2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[15], SYSCFG_ITLINE15_SR_TIM2_GLB) == + (SYSCFG_ITLINE15_SR_TIM2_GLB)); + } +#endif /* SYSCFG_ITLINE15_SR_TIM2_GLB */ + +#if defined(SYSCFG_ITLINE16_SR_TIM3_GLB) + /** + * @brief Check if Timer 3 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE16 SR_TIM3_GLB LL_SYSCFG_IsActiveFlag_TIM3 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM3(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[16], SYSCFG_ITLINE16_SR_TIM3_GLB) == + (SYSCFG_ITLINE16_SR_TIM3_GLB)); + } +#endif /* SYSCFG_ITLINE16_SR_TIM3_GLB */ + +#if defined(SYSCFG_ITLINE17_SR_DAC) + /** + * @brief Check if DAC underrun interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE17 SR_DAC LL_SYSCFG_IsActiveFlag_DAC + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_DAC(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[17], SYSCFG_ITLINE17_SR_DAC) == + (SYSCFG_ITLINE17_SR_DAC)); + } +#endif /* SYSCFG_ITLINE17_SR_DAC */ + +#if defined(SYSCFG_ITLINE17_SR_TIM6_GLB) + /** + * @brief Check if Timer 6 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE17 SR_TIM6_GLB LL_SYSCFG_IsActiveFlag_TIM6 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM6(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[17], SYSCFG_ITLINE17_SR_TIM6_GLB) == + (SYSCFG_ITLINE17_SR_TIM6_GLB)); + } +#endif /* SYSCFG_ITLINE17_SR_TIM6_GLB */ + +#if defined(SYSCFG_ITLINE18_SR_TIM7_GLB) + /** + * @brief Check if Timer 7 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE18 SR_TIM7_GLB LL_SYSCFG_IsActiveFlag_TIM7 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM7(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[18], SYSCFG_ITLINE18_SR_TIM7_GLB) == + (SYSCFG_ITLINE18_SR_TIM7_GLB)); + } +#endif /* SYSCFG_ITLINE18_SR_TIM7_GLB */ + +#if defined(SYSCFG_ITLINE19_SR_TIM14_GLB) + /** + * @brief Check if Timer 14 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE19 SR_TIM14_GLB LL_SYSCFG_IsActiveFlag_TIM14 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM14(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[19], SYSCFG_ITLINE19_SR_TIM14_GLB) == + (SYSCFG_ITLINE19_SR_TIM14_GLB)); + } +#endif /* SYSCFG_ITLINE19_SR_TIM14_GLB */ + +#if defined(SYSCFG_ITLINE20_SR_TIM15_GLB) + /** + * @brief Check if Timer 15 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE20 SR_TIM15_GLB LL_SYSCFG_IsActiveFlag_TIM15 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM15(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[20], SYSCFG_ITLINE20_SR_TIM15_GLB) == + (SYSCFG_ITLINE20_SR_TIM15_GLB)); + } +#endif /* SYSCFG_ITLINE20_SR_TIM15_GLB */ + +#if defined(SYSCFG_ITLINE21_SR_TIM16_GLB) + /** + * @brief Check if Timer 16 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE21 SR_TIM16_GLB LL_SYSCFG_IsActiveFlag_TIM16 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM16(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[21], SYSCFG_ITLINE21_SR_TIM16_GLB) == + (SYSCFG_ITLINE21_SR_TIM16_GLB)); + } +#endif /* SYSCFG_ITLINE21_SR_TIM16_GLB */ + +#if defined(SYSCFG_ITLINE22_SR_TIM17_GLB) + /** + * @brief Check if Timer 17 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE22 SR_TIM17_GLB LL_SYSCFG_IsActiveFlag_TIM17 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_TIM17(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[22], SYSCFG_ITLINE22_SR_TIM17_GLB) == + (SYSCFG_ITLINE22_SR_TIM17_GLB)); + } +#endif /* SYSCFG_ITLINE22_SR_TIM17_GLB */ + +#if defined(SYSCFG_ITLINE23_SR_I2C1_GLB) + /** + * @brief Check if I2C1 interrupt occurred or not, combined with EXTI line 23. + * @rmtoll SYSCFG_ITLINE23 SR_I2C1_GLB LL_SYSCFG_IsActiveFlag_I2C1 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_I2C1(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[23], SYSCFG_ITLINE23_SR_I2C1_GLB) == + (SYSCFG_ITLINE23_SR_I2C1_GLB)); + } +#endif /* SYSCFG_ITLINE23_SR_I2C1_GLB */ + +#if defined(SYSCFG_ITLINE24_SR_I2C2_GLB) + /** + * @brief Check if I2C2 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE24 SR_I2C2_GLB LL_SYSCFG_IsActiveFlag_I2C2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_I2C2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[24], SYSCFG_ITLINE24_SR_I2C2_GLB) == + (SYSCFG_ITLINE24_SR_I2C2_GLB)); + } +#endif /* SYSCFG_ITLINE24_SR_I2C2_GLB */ + +#if defined(SYSCFG_ITLINE25_SR_SPI1) + /** + * @brief Check if SPI1 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE25 SR_SPI1 LL_SYSCFG_IsActiveFlag_SPI1 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_SPI1(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[25], SYSCFG_ITLINE25_SR_SPI1) == + (SYSCFG_ITLINE25_SR_SPI1)); + } +#endif /* SYSCFG_ITLINE25_SR_SPI1 */ + +#if defined(SYSCFG_ITLINE26_SR_SPI2) + /** + * @brief Check if SPI2 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE26 SR_SPI2 LL_SYSCFG_IsActiveFlag_SPI2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_SPI2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[26], SYSCFG_ITLINE26_SR_SPI2) == + (SYSCFG_ITLINE26_SR_SPI2)); + } +#endif /* SYSCFG_ITLINE26_SR_SPI2 */ + +#if defined(SYSCFG_ITLINE27_SR_USART1_GLB) + /** + * @brief Check if USART1 interrupt occurred or not, combined with EXTI line 25. + * @rmtoll SYSCFG_ITLINE27 SR_USART1_GLB LL_SYSCFG_IsActiveFlag_USART1 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_USART1(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[27], SYSCFG_ITLINE27_SR_USART1_GLB) == + (SYSCFG_ITLINE27_SR_USART1_GLB)); + } +#endif /* SYSCFG_ITLINE27_SR_USART1_GLB */ + +#if defined(SYSCFG_ITLINE28_SR_USART2_GLB) + /** + * @brief Check if USART2 interrupt occurred or not, combined with EXTI line 26. + * @rmtoll SYSCFG_ITLINE28 SR_USART2_GLB LL_SYSCFG_IsActiveFlag_USART2 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_USART2(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[28], SYSCFG_ITLINE28_SR_USART2_GLB) == + (SYSCFG_ITLINE28_SR_USART2_GLB)); + } +#endif /* SYSCFG_ITLINE28_SR_USART2_GLB */ + +#if defined(SYSCFG_ITLINE29_SR_USART3_GLB) + /** + * @brief Check if USART3 interrupt occurred or not, combined with EXTI line 28. + * @rmtoll SYSCFG_ITLINE29 SR_USART3_GLB LL_SYSCFG_IsActiveFlag_USART3 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_USART3(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[29], SYSCFG_ITLINE29_SR_USART3_GLB) == + (SYSCFG_ITLINE29_SR_USART3_GLB)); + } +#endif /* SYSCFG_ITLINE29_SR_USART3_GLB */ + +#if defined(SYSCFG_ITLINE29_SR_USART4_GLB) + /** + * @brief Check if USART4 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE29 SR_USART4_GLB LL_SYSCFG_IsActiveFlag_USART4 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_USART4(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[29], SYSCFG_ITLINE29_SR_USART4_GLB) == + (SYSCFG_ITLINE29_SR_USART4_GLB)); + } +#endif /* SYSCFG_ITLINE29_SR_USART4_GLB */ + +#if defined(SYSCFG_ITLINE29_SR_USART5_GLB) + /** + * @brief Check if USART5 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE29 SR_USART5_GLB LL_SYSCFG_IsActiveFlag_USART5 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_USART5(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[29], SYSCFG_ITLINE29_SR_USART5_GLB) == + (SYSCFG_ITLINE29_SR_USART5_GLB)); + } +#endif /* SYSCFG_ITLINE29_SR_USART5_GLB */ + +#if defined(SYSCFG_ITLINE29_SR_USART6_GLB) + /** + * @brief Check if USART6 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE29 SR_USART6_GLB LL_SYSCFG_IsActiveFlag_USART6 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_USART6(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[29], SYSCFG_ITLINE29_SR_USART6_GLB) == + (SYSCFG_ITLINE29_SR_USART6_GLB)); + } +#endif /* SYSCFG_ITLINE29_SR_USART6_GLB */ + +#if defined(SYSCFG_ITLINE29_SR_USART7_GLB) + /** + * @brief Check if USART7 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE29 SR_USART7_GLB LL_SYSCFG_IsActiveFlag_USART7 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_USART7(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[29], SYSCFG_ITLINE29_SR_USART7_GLB) == + (SYSCFG_ITLINE29_SR_USART7_GLB)); + } +#endif /* SYSCFG_ITLINE29_SR_USART7_GLB */ + +#if defined(SYSCFG_ITLINE29_SR_USART8_GLB) + /** + * @brief Check if USART8 interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE29 SR_USART8_GLB LL_SYSCFG_IsActiveFlag_USART8 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_USART8(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[29], SYSCFG_ITLINE29_SR_USART8_GLB) == + (SYSCFG_ITLINE29_SR_USART8_GLB)); + } +#endif /* SYSCFG_ITLINE29_SR_USART8_GLB */ + +#if defined(SYSCFG_ITLINE30_SR_CAN) + /** + * @brief Check if CAN interrupt occurred or not. + * @rmtoll SYSCFG_ITLINE30 SR_CAN LL_SYSCFG_IsActiveFlag_CAN + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_CAN(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[30], SYSCFG_ITLINE30_SR_CAN) == + (SYSCFG_ITLINE30_SR_CAN)); + } +#endif /* SYSCFG_ITLINE30_SR_CAN */ + +#if defined(SYSCFG_ITLINE30_SR_CEC) + /** + * @brief Check if CEC interrupt occurred or not, combined with EXTI line 27. + * @rmtoll SYSCFG_ITLINE30 SR_CEC LL_SYSCFG_IsActiveFlag_CEC + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_CEC(void) + { + return (READ_BIT(SYSCFG->IT_LINE_SR[30], SYSCFG_ITLINE30_SR_CEC) == + (SYSCFG_ITLINE30_SR_CEC)); + } +#endif /* SYSCFG_ITLINE30_SR_CEC */ + + /** + * @brief Set connections to TIMx Break inputs + * @rmtoll SYSCFG_CFGR2 LOCKUP_LOCK LL_SYSCFG_SetTIMBreakInputs\n + * SYSCFG_CFGR2 SRAM_PARITY_LOCK LL_SYSCFG_SetTIMBreakInputs\n + * SYSCFG_CFGR2 PVD_LOCK LL_SYSCFG_SetTIMBreakInputs + * @param Break This parameter can be a combination of the following values: + * @arg @ref LL_SYSCFG_TIMBREAK_PVD (*) + * @arg @ref LL_SYSCFG_TIMBREAK_SRAM_PARITY + * @arg @ref LL_SYSCFG_TIMBREAK_LOCKUP + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_SetTIMBreakInputs(uint32_t Break) + { +#if defined(SYSCFG_CFGR2_PVD_LOCK) + MODIFY_REG(SYSCFG->CFGR2, + SYSCFG_CFGR2_LOCKUP_LOCK | SYSCFG_CFGR2_SRAM_PARITY_LOCK | + SYSCFG_CFGR2_PVD_LOCK, + Break); +#else + MODIFY_REG(SYSCFG->CFGR2, + SYSCFG_CFGR2_LOCKUP_LOCK | SYSCFG_CFGR2_SRAM_PARITY_LOCK, Break); +#endif /*SYSCFG_CFGR2_PVD_LOCK*/ + } + + /** + * @brief Get connections to TIMx Break inputs + * @rmtoll SYSCFG_CFGR2 LOCKUP_LOCK LL_SYSCFG_GetTIMBreakInputs\n + * SYSCFG_CFGR2 SRAM_PARITY_LOCK LL_SYSCFG_GetTIMBreakInputs\n + * SYSCFG_CFGR2 PVD_LOCK LL_SYSCFG_GetTIMBreakInputs + * @retval Returned value can be can be a combination of the following values: + * @arg @ref LL_SYSCFG_TIMBREAK_PVD (*) + * @arg @ref LL_SYSCFG_TIMBREAK_SRAM_PARITY + * @arg @ref LL_SYSCFG_TIMBREAK_LOCKUP + * + * (*) value not defined in all devices + */ + __STATIC_INLINE uint32_t LL_SYSCFG_GetTIMBreakInputs(void) + { +#if defined(SYSCFG_CFGR2_PVD_LOCK) + return (uint32_t)(READ_BIT(SYSCFG->CFGR2, SYSCFG_CFGR2_LOCKUP_LOCK | + SYSCFG_CFGR2_SRAM_PARITY_LOCK | + SYSCFG_CFGR2_PVD_LOCK)); +#else + return (uint32_t)(READ_BIT( + SYSCFG->CFGR2, SYSCFG_CFGR2_LOCKUP_LOCK | SYSCFG_CFGR2_SRAM_PARITY_LOCK)); +#endif /*SYSCFG_CFGR2_PVD_LOCK*/ + } + + /** + * @brief Check if SRAM parity error detected + * @rmtoll SYSCFG_CFGR2 SRAM_PEF LL_SYSCFG_IsActiveFlag_SP + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_SYSCFG_IsActiveFlag_SP(void) + { + return (READ_BIT(SYSCFG->CFGR2, SYSCFG_CFGR2_SRAM_PEF) == + (SYSCFG_CFGR2_SRAM_PEF)); + } + + /** + * @brief Clear SRAM parity error flag + * @rmtoll SYSCFG_CFGR2 SRAM_PEF LL_SYSCFG_ClearFlag_SP + * @retval None + */ + __STATIC_INLINE void LL_SYSCFG_ClearFlag_SP(void) + { + SET_BIT(SYSCFG->CFGR2, SYSCFG_CFGR2_SRAM_PEF); + } + + /** + * @} + */ + + /** @defgroup SYSTEM_LL_EF_DBGMCU DBGMCU + * @{ + */ + + /** + * @brief Return the device identifier + * @note For STM32F03x devices, the device ID is 0x444 + * @note For STM32F04x devices, the device ID is 0x445. + * @note For STM32F05x devices, the device ID is 0x440 + * @note For STM32F07x devices, the device ID is 0x448 + * @note For STM32F09x devices, the device ID is 0x442 + * @rmtoll DBGMCU_IDCODE DEV_ID LL_DBGMCU_GetDeviceID + * @retval Values between Min_Data=0x00 and Max_Data=0xFFF + */ + __STATIC_INLINE uint32_t LL_DBGMCU_GetDeviceID(void) + { + return (uint32_t)(READ_BIT(DBGMCU->IDCODE, DBGMCU_IDCODE_DEV_ID)); + } + + /** + * @brief Return the device revision identifier + * @note This field indicates the revision of the device. + For example, it is read as 0x1000 for Revision 1.0. + * @rmtoll DBGMCU_IDCODE REV_ID LL_DBGMCU_GetRevisionID + * @retval Values between Min_Data=0x00 and Max_Data=0xFFFF + */ + __STATIC_INLINE uint32_t LL_DBGMCU_GetRevisionID(void) + { + return (uint32_t)(READ_BIT(DBGMCU->IDCODE, DBGMCU_IDCODE_REV_ID) >> + DBGMCU_IDCODE_REV_ID_Pos); + } + + /** + * @brief Enable the Debug Module during STOP mode + * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_EnableDBGStopMode + * @retval None + */ + __STATIC_INLINE void LL_DBGMCU_EnableDBGStopMode(void) + { + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); + } + + /** + * @brief Disable the Debug Module during STOP mode + * @rmtoll DBGMCU_CR DBG_STOP LL_DBGMCU_DisableDBGStopMode + * @retval None + */ + __STATIC_INLINE void LL_DBGMCU_DisableDBGStopMode(void) + { + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); + } + + /** + * @brief Enable the Debug Module during STANDBY mode + * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_EnableDBGStandbyMode + * @retval None + */ + __STATIC_INLINE void LL_DBGMCU_EnableDBGStandbyMode(void) + { + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); + } + + /** + * @brief Disable the Debug Module during STANDBY mode + * @rmtoll DBGMCU_CR DBG_STANDBY LL_DBGMCU_DisableDBGStandbyMode + * @retval None + */ + __STATIC_INLINE void LL_DBGMCU_DisableDBGStandbyMode(void) + { + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); + } + + /** + * @brief Freeze APB1 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB1FZ DBG_TIM2_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_TIM3_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_TIM6_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_TIM7_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_TIM14_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_RTC_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_WWDG_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_IWDG_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_I2C1_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_FreezePeriph\n + * DBGMCU_APB1FZ DBG_CAN_STOP LL_DBGMCU_APB1_GRP1_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_RTC_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_CAN_STOP (*) + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_DBGMCU_APB1_GRP1_FreezePeriph(uint32_t Periphs) + { + SET_BIT(DBGMCU->APB1FZ, Periphs); + } + + /** + * @brief Unfreeze APB1 peripherals (group1 peripherals) + * @rmtoll DBGMCU_APB1FZ DBG_TIM2_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_TIM3_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_TIM6_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_TIM7_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_TIM14_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_RTC_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_WWDG_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_IWDG_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_I2C1_SMBUS_TIMEOUT LL_DBGMCU_APB1_GRP1_UnFreezePeriph\n + * DBGMCU_APB1FZ DBG_CAN_STOP LL_DBGMCU_APB1_GRP1_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM2_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM3_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM6_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM7_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP1_TIM14_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_RTC_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_WWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_IWDG_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_I2C1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP1_CAN_STOP (*) + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_DBGMCU_APB1_GRP1_UnFreezePeriph(uint32_t Periphs) + { + CLEAR_BIT(DBGMCU->APB1FZ, Periphs); + } + + /** + * @brief Freeze APB1 peripherals (group2 peripherals) + * @rmtoll DBGMCU_APB2FZ DBG_TIM1_STOP LL_DBGMCU_APB1_GRP2_FreezePeriph\n + * DBGMCU_APB2FZ DBG_TIM15_STOP LL_DBGMCU_APB1_GRP2_FreezePeriph\n + * DBGMCU_APB2FZ DBG_TIM16_STOP LL_DBGMCU_APB1_GRP2_FreezePeriph\n + * DBGMCU_APB2FZ DBG_TIM17_STOP LL_DBGMCU_APB1_GRP2_FreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB1_GRP2_TIM1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP2_TIM15_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP2_TIM16_STOP + * @arg @ref LL_DBGMCU_APB1_GRP2_TIM17_STOP + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_DBGMCU_APB1_GRP2_FreezePeriph(uint32_t Periphs) + { + SET_BIT(DBGMCU->APB2FZ, Periphs); + } + + /** + * @brief Unfreeze APB1 peripherals (group2 peripherals) + * @rmtoll DBGMCU_APB2FZ DBG_TIM1_STOP LL_DBGMCU_APB1_GRP2_UnFreezePeriph\n + * DBGMCU_APB2FZ DBG_TIM15_STOP LL_DBGMCU_APB1_GRP2_UnFreezePeriph\n + * DBGMCU_APB2FZ DBG_TIM16_STOP LL_DBGMCU_APB1_GRP2_UnFreezePeriph\n + * DBGMCU_APB2FZ DBG_TIM17_STOP LL_DBGMCU_APB1_GRP2_UnFreezePeriph + * @param Periphs This parameter can be a combination of the following values: + * @arg @ref LL_DBGMCU_APB1_GRP2_TIM1_STOP + * @arg @ref LL_DBGMCU_APB1_GRP2_TIM15_STOP (*) + * @arg @ref LL_DBGMCU_APB1_GRP2_TIM16_STOP + * @arg @ref LL_DBGMCU_APB1_GRP2_TIM17_STOP + * + * (*) value not defined in all devices + * @retval None + */ + __STATIC_INLINE void LL_DBGMCU_APB1_GRP2_UnFreezePeriph(uint32_t Periphs) + { + CLEAR_BIT(DBGMCU->APB2FZ, Periphs); + } + /** + * @} + */ + + /** @defgroup SYSTEM_LL_EF_FLASH FLASH + * @{ + */ + + /** + * @brief Set FLASH Latency + * @rmtoll FLASH_ACR LATENCY LL_FLASH_SetLatency + * @param Latency This parameter can be one of the following values: + * @arg @ref LL_FLASH_LATENCY_0 + * @arg @ref LL_FLASH_LATENCY_1 + * @retval None + */ + __STATIC_INLINE void LL_FLASH_SetLatency(uint32_t Latency) + { + MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, Latency); + } + + /** + * @brief Get FLASH Latency + * @rmtoll FLASH_ACR LATENCY LL_FLASH_GetLatency + * @retval Returned value can be one of the following values: + * @arg @ref LL_FLASH_LATENCY_0 + * @arg @ref LL_FLASH_LATENCY_1 + */ + __STATIC_INLINE uint32_t LL_FLASH_GetLatency(void) + { + return (uint32_t)(READ_BIT(FLASH->ACR, FLASH_ACR_LATENCY)); + } + + /** + * @brief Enable Prefetch + * @rmtoll FLASH_ACR PRFTBE LL_FLASH_EnablePrefetch + * @retval None + */ + __STATIC_INLINE void LL_FLASH_EnablePrefetch(void) + { + SET_BIT(FLASH->ACR, FLASH_ACR_PRFTBE); + } + + /** + * @brief Disable Prefetch + * @rmtoll FLASH_ACR PRFTBE LL_FLASH_DisablePrefetch + * @retval None + */ + __STATIC_INLINE void LL_FLASH_DisablePrefetch(void) + { + CLEAR_BIT(FLASH->ACR, FLASH_ACR_PRFTBE); + } + + /** + * @brief Check if Prefetch buffer is enabled + * @rmtoll FLASH_ACR PRFTBS LL_FLASH_IsPrefetchEnabled + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_FLASH_IsPrefetchEnabled(void) + { + return (READ_BIT(FLASH->ACR, FLASH_ACR_PRFTBS) == (FLASH_ACR_PRFTBS)); + } + + + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* defined (FLASH) || defined (SYSCFG) || defined (DBGMCU) */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_SYSTEM_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_tim.c b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_tim.c new file mode 100644 index 0000000000..b4e4e25271 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_tim.c @@ -0,0 +1,1203 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_tim.c + * @author MCD Application Team + * @brief TIM LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +#if defined(USE_FULL_LL_DRIVER) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_ll_tim.h" + +#include "stm32f0xx_ll_bus.h" + +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +/** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(TIM1) || defined(TIM2) || defined(TIM3) || defined(TIM14) || \ + defined(TIM15) || defined(TIM16) || defined(TIM17) || defined(TIM6) || defined(TIM7) + +/** @addtogroup TIM_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup TIM_LL_Private_Macros + * @{ + */ +#define IS_LL_TIM_COUNTERMODE(__VALUE__) \ + (((__VALUE__) == LL_TIM_COUNTERMODE_UP) || \ + ((__VALUE__) == LL_TIM_COUNTERMODE_DOWN) || \ + ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP) || \ + ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_DOWN) || \ + ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP_DOWN)) + +#define IS_LL_TIM_CLOCKDIVISION(__VALUE__) \ + (((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV1) || \ + ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV2) || \ + ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV4)) + +#define IS_LL_TIM_OCMODE(__VALUE__) \ + (((__VALUE__) == LL_TIM_OCMODE_FROZEN) || ((__VALUE__) == LL_TIM_OCMODE_ACTIVE) || \ + ((__VALUE__) == LL_TIM_OCMODE_INACTIVE) || ((__VALUE__) == LL_TIM_OCMODE_TOGGLE) || \ + ((__VALUE__) == LL_TIM_OCMODE_FORCED_INACTIVE) || \ + ((__VALUE__) == LL_TIM_OCMODE_FORCED_ACTIVE) || \ + ((__VALUE__) == LL_TIM_OCMODE_PWM1) || ((__VALUE__) == LL_TIM_OCMODE_PWM2)) + +#define IS_LL_TIM_OCSTATE(__VALUE__) \ + (((__VALUE__) == LL_TIM_OCSTATE_DISABLE) || ((__VALUE__) == LL_TIM_OCSTATE_ENABLE)) + +#define IS_LL_TIM_OCPOLARITY(__VALUE__) \ + (((__VALUE__) == LL_TIM_OCPOLARITY_HIGH) || ((__VALUE__) == LL_TIM_OCPOLARITY_LOW)) + +#define IS_LL_TIM_OCIDLESTATE(__VALUE__) \ + (((__VALUE__) == LL_TIM_OCIDLESTATE_LOW) || ((__VALUE__) == LL_TIM_OCIDLESTATE_HIGH)) + +#define IS_LL_TIM_ACTIVEINPUT(__VALUE__) \ + (((__VALUE__) == LL_TIM_ACTIVEINPUT_DIRECTTI) || \ + ((__VALUE__) == LL_TIM_ACTIVEINPUT_INDIRECTTI) || \ + ((__VALUE__) == LL_TIM_ACTIVEINPUT_TRC)) + +#define IS_LL_TIM_ICPSC(__VALUE__) \ + (((__VALUE__) == LL_TIM_ICPSC_DIV1) || ((__VALUE__) == LL_TIM_ICPSC_DIV2) || \ + ((__VALUE__) == LL_TIM_ICPSC_DIV4) || ((__VALUE__) == LL_TIM_ICPSC_DIV8)) + +#define IS_LL_TIM_IC_FILTER(__VALUE__) \ + (((__VALUE__) == LL_TIM_IC_FILTER_FDIV1) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N2) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N4) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N8) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N6) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N8) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N6) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N8) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N6) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N8) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N5) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N6) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N8) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N5) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N6) || \ + ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N8)) + +#define IS_LL_TIM_IC_POLARITY(__VALUE__) \ + (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) || \ + ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING) || \ + ((__VALUE__) == LL_TIM_IC_POLARITY_BOTHEDGE)) + +#define IS_LL_TIM_ENCODERMODE(__VALUE__) \ + (((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI1) || \ + ((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI2) || \ + ((__VALUE__) == LL_TIM_ENCODERMODE_X4_TI12)) + +#define IS_LL_TIM_IC_POLARITY_ENCODER(__VALUE__) \ + (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) || \ + ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING)) + +#define IS_LL_TIM_OSSR_STATE(__VALUE__) \ + (((__VALUE__) == LL_TIM_OSSR_DISABLE) || ((__VALUE__) == LL_TIM_OSSR_ENABLE)) + +#define IS_LL_TIM_OSSI_STATE(__VALUE__) \ + (((__VALUE__) == LL_TIM_OSSI_DISABLE) || ((__VALUE__) == LL_TIM_OSSI_ENABLE)) + +#define IS_LL_TIM_LOCK_LEVEL(__VALUE__) \ + (((__VALUE__) == LL_TIM_LOCKLEVEL_OFF) || ((__VALUE__) == LL_TIM_LOCKLEVEL_1) || \ + ((__VALUE__) == LL_TIM_LOCKLEVEL_2) || ((__VALUE__) == LL_TIM_LOCKLEVEL_3)) + +#define IS_LL_TIM_BREAK_STATE(__VALUE__) \ + (((__VALUE__) == LL_TIM_BREAK_DISABLE) || ((__VALUE__) == LL_TIM_BREAK_ENABLE)) + +#define IS_LL_TIM_BREAK_POLARITY(__VALUE__) \ + (((__VALUE__) == LL_TIM_BREAK_POLARITY_LOW) || \ + ((__VALUE__) == LL_TIM_BREAK_POLARITY_HIGH)) + +#define IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(__VALUE__) \ + (((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_DISABLE) || \ + ((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_ENABLE)) +/** + * @} + */ + + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup TIM_LL_Private_Functions TIM Private Functions + * @{ + */ +static ErrorStatus OC1Config(TIM_TypeDef *TIMx, + const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC2Config(TIM_TypeDef *TIMx, + const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC3Config(TIM_TypeDef *TIMx, + const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus OC4Config(TIM_TypeDef *TIMx, + const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct); +static ErrorStatus IC1Config(TIM_TypeDef *TIMx, + const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC2Config(TIM_TypeDef *TIMx, + const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC3Config(TIM_TypeDef *TIMx, + const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +static ErrorStatus IC4Config(TIM_TypeDef *TIMx, + const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIM_LL_Exported_Functions + * @{ + */ + +/** @addtogroup TIM_LL_EF_Init + * @{ + */ + +/** + * @brief Set TIMx registers to their reset values. + * @param TIMx Timer instance + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: invalid TIMx instance + */ +ErrorStatus LL_TIM_DeInit(const TIM_TypeDef *TIMx) +{ + ErrorStatus result = SUCCESS; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(TIMx)); + + if (TIMx == TIM1) + { + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM1); + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM1); + } +#if defined(TIM2) + else if (TIMx == TIM2) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2); + } +#endif /* TIM2 */ +#if defined(TIM3) + else if (TIMx == TIM3) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM3); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM3); + } +#endif /* TIM3 */ +#if defined(TIM5) + else if (TIMx == TIM5) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM5); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM5); + } +#endif /* TIM5 */ +#if defined(TIM6) + else if (TIMx == TIM6) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM6); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM6); + } +#endif /* TIM6 */ +#if defined(TIM7) + else if (TIMx == TIM7) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM7); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM7); + } +#endif /* TIM7 */ +#if defined(TIM8) + else if (TIMx == TIM8) + { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_TIM8); + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_TIM8); + } +#endif /* TIM8 */ +#if defined(TIM14) + else if (TIMx == TIM14) + { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM14); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM14); + } +#endif /* TIM14 */ +#if defined(TIM15) + else if (TIMx == TIM15) + { + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM15); + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM15); + } +#endif /* TIM15 */ +#if defined(TIM16) + else if (TIMx == TIM16) + { + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM16); + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM16); + } +#endif /* TIM16 */ +#if defined(TIM17) + else if (TIMx == TIM17) + { + LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM17); + LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM17); + } +#endif /* TIM17 */ + else + { + result = ERROR; + } + + return result; +} + +/** + * @brief Set the fields of the time base unit configuration data structure + * to their default values. + * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (time base unit + * configuration data structure) + * @retval None + */ +void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct) +{ + /* Set the default configuration */ + TIM_InitStruct->Prescaler = (uint16_t)0x0000; + TIM_InitStruct->CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct->Autoreload = 0xFFFFFFFFU; + TIM_InitStruct->ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + TIM_InitStruct->RepetitionCounter = 0x00000000U; +} + +/** + * @brief Configure the TIMx time base unit. + * @param TIMx Timer Instance + * @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure + * (TIMx time base unit configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, const LL_TIM_InitTypeDef *TIM_InitStruct) +{ + uint32_t tmpcr1; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_COUNTERMODE(TIM_InitStruct->CounterMode)); + assert_param(IS_LL_TIM_CLOCKDIVISION(TIM_InitStruct->ClockDivision)); + + tmpcr1 = LL_TIM_ReadReg(TIMx, CR1); + + if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx)) + { + /* Select the Counter Mode */ + MODIFY_REG(tmpcr1, (TIM_CR1_DIR | TIM_CR1_CMS), TIM_InitStruct->CounterMode); + } + + if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx)) + { + /* Set the clock division */ + MODIFY_REG(tmpcr1, TIM_CR1_CKD, TIM_InitStruct->ClockDivision); + } + + /* Write to TIMx CR1 */ + LL_TIM_WriteReg(TIMx, CR1, tmpcr1); + + /* Set the Autoreload value */ + LL_TIM_SetAutoReload(TIMx, TIM_InitStruct->Autoreload); + + /* Set the Prescaler value */ + LL_TIM_SetPrescaler(TIMx, TIM_InitStruct->Prescaler); + + if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx)) + { + /* Set the Repetition Counter value */ + LL_TIM_SetRepetitionCounter(TIMx, TIM_InitStruct->RepetitionCounter); + } + + /* Generate an update event to reload the Prescaler + and the repetition counter value (if applicable) immediately */ + LL_TIM_GenerateEvent_UPDATE(TIMx); + + return SUCCESS; +} + +/** + * @brief Set the fields of the TIMx output channel configuration data + * structure to their default values. + * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure + * (the output channel configuration data structure) + * @retval None + */ +void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct) +{ + /* Set the default configuration */ + TIM_OC_InitStruct->OCMode = LL_TIM_OCMODE_FROZEN; + TIM_OC_InitStruct->OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct->OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct->CompareValue = 0x00000000U; + TIM_OC_InitStruct->OCPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct->OCNPolarity = LL_TIM_OCPOLARITY_HIGH; + TIM_OC_InitStruct->OCIdleState = LL_TIM_OCIDLESTATE_LOW; + TIM_OC_InitStruct->OCNIdleState = LL_TIM_OCIDLESTATE_LOW; +} + +/** + * @brief Configure the TIMx output channel. + * @param TIMx Timer Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (TIMx + * output channel configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx output channel is initialized + * - ERROR: TIMx output channel is not initialized + */ +ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, + const LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct) +{ + ErrorStatus result = ERROR; + + switch (Channel) + { + case LL_TIM_CHANNEL_CH1: + result = OC1Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH2: + result = OC2Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH3: + result = OC3Config(TIMx, TIM_OC_InitStruct); + break; + case LL_TIM_CHANNEL_CH4: + result = OC4Config(TIMx, TIM_OC_InitStruct); + break; + default: + break; + } + + return result; +} + +/** + * @brief Set the fields of the TIMx input channel configuration data + * structure to their default values. + * @param TIM_ICInitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (the input + * channel configuration data structure) + * @retval None + */ +void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Set the default configuration */ + TIM_ICInitStruct->ICPolarity = LL_TIM_IC_POLARITY_RISING; + TIM_ICInitStruct->ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_ICInitStruct->ICPrescaler = LL_TIM_ICPSC_DIV1; + TIM_ICInitStruct->ICFilter = LL_TIM_IC_FILTER_FDIV1; +} + +/** + * @brief Configure the TIMx input channel. + * @param TIMx Timer Instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param TIM_IC_InitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (TIMx input + * channel configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx output channel is initialized + * - ERROR: TIMx output channel is not initialized + */ +ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, + const LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct) +{ + ErrorStatus result = ERROR; + + switch (Channel) + { + case LL_TIM_CHANNEL_CH1: + result = IC1Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH2: + result = IC2Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH3: + result = IC3Config(TIMx, TIM_IC_InitStruct); + break; + case LL_TIM_CHANNEL_CH4: + result = IC4Config(TIMx, TIM_IC_InitStruct); + break; + default: + break; + } + + return result; +} + +/** + * @brief Fills each TIM_EncoderInitStruct field with its default value + * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure + * (encoder interface configuration data structure) + * @retval None + */ +void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct) +{ + /* Set the default configuration */ + TIM_EncoderInitStruct->EncoderMode = LL_TIM_ENCODERMODE_X2_TI1; + TIM_EncoderInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING; + TIM_EncoderInitStruct->IC1ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_EncoderInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1; + TIM_EncoderInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1; + TIM_EncoderInitStruct->IC2Polarity = LL_TIM_IC_POLARITY_RISING; + TIM_EncoderInitStruct->IC2ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI; + TIM_EncoderInitStruct->IC2Prescaler = LL_TIM_ICPSC_DIV1; + TIM_EncoderInitStruct->IC2Filter = LL_TIM_IC_FILTER_FDIV1; +} + +/** + * @brief Configure the encoder interface of the timer instance. + * @param TIMx Timer Instance + * @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure + * (TIMx encoder interface configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, + const LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_ENCODERMODE(TIM_EncoderInitStruct->EncoderMode)); + assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC1Polarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC1ActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC1Prescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC1Filter)); + assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC2Polarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC2ActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC2Prescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC2Filter)); + + /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */ + TIMx->CCER &= (uint32_t) ~(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Configure TI1 */ + tmpccmr1 &= (uint32_t) ~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1ActiveInput >> 16U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Filter >> 16U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Prescaler >> 16U); + + /* Configure TI2 */ + tmpccmr1 &= (uint32_t) ~(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2ActiveInput >> 8U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Filter >> 8U); + tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Prescaler >> 8U); + + /* Set TI1 and TI2 polarity and enable TI1 and TI2 */ + tmpccer &= + (uint32_t) ~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC1Polarity); + tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC2Polarity << 4U); + tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Set encoder mode */ + LL_TIM_SetEncoderMode(TIMx, TIM_EncoderInitStruct->EncoderMode); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Set the fields of the TIMx Hall sensor interface configuration data + * structure to their default values. + * @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef + * structure (HALL sensor interface configuration data structure) + * @retval None + */ +void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct) +{ + /* Set the default configuration */ + TIM_HallSensorInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING; + TIM_HallSensorInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1; + TIM_HallSensorInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1; + TIM_HallSensorInitStruct->CommutationDelay = 0U; +} + +/** + * @brief Configure the Hall sensor interface of the timer instance. + * @note TIMx CH1, CH2 and CH3 inputs connected through a XOR + * to the TI1 input channel + * @note TIMx slave mode controller is configured in reset mode. + Selected internal trigger is TI1F_ED. + * @note Channel 1 is configured as input, IC1 is mapped on TRC. + * @note Captured value stored in TIMx_CCR1 correspond to the time elapsed + * between 2 changes on the inputs. It gives information about motor speed. + * @note Channel 2 is configured in output PWM 2 mode. + * @note Compare value stored in TIMx_CCR2 corresponds to the commutation delay. + * @note OC2REF is selected as trigger output on TRGO. + * @note LL_TIM_IC_POLARITY_BOTHEDGE must not be used for TI1 when it is used + * when TIMx operates in Hall sensor interface mode. + * @param TIMx Timer Instance + * @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef + structure (TIMx HALL sensor + * interface configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_HALLSENSOR_Init( + TIM_TypeDef *TIMx, const LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct) +{ + uint32_t tmpcr2; + uint32_t tmpccmr1; + uint32_t tmpccer; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_HallSensorInitStruct->IC1Polarity)); + assert_param(IS_LL_TIM_ICPSC(TIM_HallSensorInitStruct->IC1Prescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_HallSensorInitStruct->IC1Filter)); + + /* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */ + TIMx->CCER &= (uint32_t) ~(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx SMCR register value */ + tmpsmcr = LL_TIM_ReadReg(TIMx, SMCR); + + /* Connect TIMx_CH1, CH2 and CH3 pins to the TI1 input */ + tmpcr2 |= TIM_CR2_TI1S; + + /* OC2REF signal is used as trigger output (TRGO) */ + tmpcr2 |= LL_TIM_TRGO_OC2REF; + + /* Configure the slave mode controller */ + tmpsmcr &= (uint32_t) ~(TIM_SMCR_TS | TIM_SMCR_SMS); + tmpsmcr |= LL_TIM_TS_TI1F_ED; + tmpsmcr |= LL_TIM_SLAVEMODE_RESET; + + /* Configure input channel 1 */ + tmpccmr1 &= (uint32_t) ~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC); + tmpccmr1 |= (uint32_t)(LL_TIM_ACTIVEINPUT_TRC >> 16U); + tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Filter >> 16U); + tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Prescaler >> 16U); + + /* Configure input channel 2 */ + tmpccmr1 &= (uint32_t) ~(TIM_CCMR1_OC2M | TIM_CCMR1_OC2FE | TIM_CCMR1_OC2PE | + TIM_CCMR1_OC2CE); + tmpccmr1 |= (uint32_t)(LL_TIM_OCMODE_PWM2 << 8U); + + /* Set Channel 1 polarity and enable Channel 1 and Channel2 */ + tmpccer &= + (uint32_t) ~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (uint32_t)(TIM_HallSensorInitStruct->IC1Polarity); + tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E); + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx SMCR */ + LL_TIM_WriteReg(TIMx, SMCR, tmpsmcr); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + /* Write to TIMx CCR2 */ + LL_TIM_OC_SetCompareCH2(TIMx, TIM_HallSensorInitStruct->CommutationDelay); + + return SUCCESS; +} + +/** + * @brief Set the fields of the Break and Dead Time configuration data structure + * to their default values. + * @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break + * and Dead Time configuration data structure) + * @retval None + */ +void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct) +{ + /* Set the default configuration */ + TIM_BDTRInitStruct->OSSRState = LL_TIM_OSSR_DISABLE; + TIM_BDTRInitStruct->OSSIState = LL_TIM_OSSI_DISABLE; + TIM_BDTRInitStruct->LockLevel = LL_TIM_LOCKLEVEL_OFF; + TIM_BDTRInitStruct->DeadTime = (uint8_t)0x00; + TIM_BDTRInitStruct->BreakState = LL_TIM_BREAK_DISABLE; + TIM_BDTRInitStruct->BreakPolarity = LL_TIM_BREAK_POLARITY_LOW; + TIM_BDTRInitStruct->AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE; +} + +/** + * @brief Configure the Break and Dead Time feature of the timer instance. + * @note As the bits AOE, BKP, BKE, OSSR, OSSI and DTG[7:0] can be write-locked + * depending on the LOCK configuration, it can be necessary to configure all of + * them during the first write access to the TIMx_BDTR register. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @param TIMx Timer Instance + * @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break + * and Dead Time configuration data structure) + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Break and Dead Time is initialized + * - ERROR: not applicable + */ +ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, + const LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct) +{ + uint32_t tmpbdtr = 0; + + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OSSR_STATE(TIM_BDTRInitStruct->OSSRState)); + assert_param(IS_LL_TIM_OSSI_STATE(TIM_BDTRInitStruct->OSSIState)); + assert_param(IS_LL_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->LockLevel)); + assert_param(IS_LL_TIM_BREAK_STATE(TIM_BDTRInitStruct->BreakState)); + assert_param(IS_LL_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->BreakPolarity)); + assert_param(IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->AutomaticOutput)); + + /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + + /* Set the BDTR bits */ + MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, TIM_BDTRInitStruct->DeadTime); + MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, TIM_BDTRInitStruct->LockLevel); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, TIM_BDTRInitStruct->OSSIState); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, TIM_BDTRInitStruct->OSSRState); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, TIM_BDTRInitStruct->BreakState); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, TIM_BDTRInitStruct->BreakPolarity); + MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, TIM_BDTRInitStruct->AutomaticOutput); + + /* Set TIMx_BDTR */ + LL_TIM_WriteReg(TIMx, BDTR, tmpbdtr); + + return SUCCESS; +} +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup TIM_LL_Private_Functions TIM Private Functions + * @brief Private functions + * @{ + */ +/** + * @brief Configure the TIMx output channel 1. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 1 configuration data + * structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC1Config(TIM_TypeDef *TIMx, + const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC1S); + + /* Set the Output Compare Mode */ + MODIFY_REG(tmpccmr1, TIM_CCMR1_OC1M, TIM_OCInitStruct->OCMode); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC1P, TIM_OCInitStruct->OCPolarity); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC1E, TIM_OCInitStruct->OCState); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + + /* Set the complementary output Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC1NP, TIM_OCInitStruct->OCNPolarity << 2U); + + /* Set the complementary output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC1NE, TIM_OCInitStruct->OCNState << 2U); + + /* Set the Output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS1, TIM_OCInitStruct->OCIdleState); + + /* Set the complementary output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS1N, TIM_OCInitStruct->OCNIdleState << 1U); + } + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH1(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 2. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 2 configuration data + * structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC2Config(TIM_TypeDef *TIMx, + const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC2E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC2S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr1, TIM_CCMR1_OC2M, TIM_OCInitStruct->OCMode << 8U); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity << 4U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC2E, TIM_OCInitStruct->OCState << 4U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + + /* Set the complementary output Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC2NP, TIM_OCInitStruct->OCNPolarity << 6U); + + /* Set the complementary output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC2NE, TIM_OCInitStruct->OCNState << 6U); + + /* Set the Output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS2, TIM_OCInitStruct->OCIdleState << 2U); + + /* Set the complementary output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS2N, TIM_OCInitStruct->OCNIdleState << 3U); + } + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR1 */ + LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH2(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 3. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 3 configuration data + * structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC3Config(TIM_TypeDef *TIMx, + const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + + /* Disable the Channel 3: Reset the CC3E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC3E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC3S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr2, TIM_CCMR2_OC3M, TIM_OCInitStruct->OCMode); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC3P, TIM_OCInitStruct->OCPolarity << 8U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC3E, TIM_OCInitStruct->OCState << 8U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity)); + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState)); + + /* Set the complementary output Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC3NP, TIM_OCInitStruct->OCNPolarity << 10U); + + /* Set the complementary output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC3NE, TIM_OCInitStruct->OCNState << 10U); + + /* Set the Output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS3, TIM_OCInitStruct->OCIdleState << 4U); + + /* Set the complementary output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS3N, TIM_OCInitStruct->OCNIdleState << 5U); + } + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR2 */ + LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH3(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx output channel 4. + * @param TIMx Timer Instance + * @param TIM_OCInitStruct pointer to the the TIMx output channel 4 configuration data + * structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus OC4Config(TIM_TypeDef *TIMx, + const LL_TIM_OC_InitTypeDef *TIM_OCInitStruct) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode)); + assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState)); + assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + CLEAR_BIT(TIMx->CCER, TIM_CCER_CC4E); + + /* Get the TIMx CCER register value */ + tmpccer = LL_TIM_ReadReg(TIMx, CCER); + + /* Get the TIMx CR2 register value */ + tmpcr2 = LL_TIM_ReadReg(TIMx, CR2); + + /* Get the TIMx CCMR2 register value */ + tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2); + + /* Reset Capture/Compare selection Bits */ + CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC4S); + + /* Select the Output Compare Mode */ + MODIFY_REG(tmpccmr2, TIM_CCMR2_OC4M, TIM_OCInitStruct->OCMode << 8U); + + /* Set the Output Compare Polarity */ + MODIFY_REG(tmpccer, TIM_CCER_CC4P, TIM_OCInitStruct->OCPolarity << 12U); + + /* Set the Output State */ + MODIFY_REG(tmpccer, TIM_CCER_CC4E, TIM_OCInitStruct->OCState << 12U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState)); + + /* Set the Output Idle state */ + MODIFY_REG(tmpcr2, TIM_CR2_OIS4, TIM_OCInitStruct->OCIdleState << 6U); + } + + /* Write to TIMx CR2 */ + LL_TIM_WriteReg(TIMx, CR2, tmpcr2); + + /* Write to TIMx CCMR2 */ + LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2); + + /* Set the Capture Compare Register value */ + LL_TIM_OC_SetCompareCH4(TIMx, TIM_OCInitStruct->CompareValue); + + /* Write to TIMx CCER */ + LL_TIM_WriteReg(TIMx, CCER, tmpccer); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 1. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 1 configuration data + * structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC1Config(TIM_TypeDef *TIMx, + const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC1E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR1, (TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | + TIM_ICInitStruct->ICPrescaler) >> + 16U); + + /* Select the Polarity and set the CC1E Bit */ + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P | TIM_CCER_CC1NP), + (TIM_ICInitStruct->ICPolarity | TIM_CCER_CC1E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 2. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 2 configuration data + * structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC2Config(TIM_TypeDef *TIMx, + const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC2E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR1, (TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | + TIM_ICInitStruct->ICPrescaler) >> + 8U); + + /* Select the Polarity and set the CC2E Bit */ + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC2P | TIM_CCER_CC2NP), + ((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 3. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 3 configuration data + * structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC3Config(TIM_TypeDef *TIMx, + const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC3E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR2, (TIM_CCMR2_CC3S | TIM_CCMR2_IC3F | TIM_CCMR2_IC3PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | + TIM_ICInitStruct->ICPrescaler) >> + 16U); + + /* Select the Polarity and set the CC3E Bit */ + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC3P | TIM_CCER_CC3NP), + ((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E)); + + return SUCCESS; +} + +/** + * @brief Configure the TIMx input channel 4. + * @param TIMx Timer Instance + * @param TIM_ICInitStruct pointer to the the TIMx input channel 4 configuration data + * structure + * @retval An ErrorStatus enumeration value: + * - SUCCESS: TIMx registers are de-initialized + * - ERROR: not applicable + */ +static ErrorStatus IC4Config(TIM_TypeDef *TIMx, + const LL_TIM_IC_InitTypeDef *TIM_ICInitStruct) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(TIMx)); + assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity)); + assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput)); + assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler)); + assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter)); + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= (uint32_t)~TIM_CCER_CC4E; + + /* Select the Input and set the filter and the prescaler value */ + MODIFY_REG(TIMx->CCMR2, (TIM_CCMR2_CC4S | TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC), + (TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | + TIM_ICInitStruct->ICPrescaler) >> + 8U); + + /* Select the Polarity and set the CC4E Bit */ + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC4P | TIM_CCER_CC4NP), + ((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E)); + + return SUCCESS; +} + + +/** + * @} + */ + +/** + * @} + */ + +#endif /* TIM1 || TIM2 || TIM3 || TIM14 || TIM15 || TIM16 || TIM17 || TIM6 || TIM7 */ + +/** + * @} + */ + +#endif /* USE_FULL_LL_DRIVER */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_tim.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_tim.h new file mode 100644 index 0000000000..ddca39f67a --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_tim.h @@ -0,0 +1,4428 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_tim.h + * @author MCD Application Team + * @brief Header file of TIM LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_TIM_H +#define __STM32F0xx_LL_TIM_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(TIM1) || defined(TIM2) || defined(TIM3) || defined(TIM14) || \ + defined(TIM15) || defined(TIM16) || defined(TIM17) || defined(TIM6) || defined(TIM7) + + /** @defgroup TIM_LL TIM + * @{ + */ + + /* Private types -------------------------------------------------------------*/ + /* Private variables ---------------------------------------------------------*/ + /** @defgroup TIM_LL_Private_Variables TIM Private Variables + * @{ + */ + static const uint8_t OFFSET_TAB_CCMRx[] = { + 0x00U, /* 0: TIMx_CH1 */ + 0x00U, /* 1: TIMx_CH1N */ + 0x00U, /* 2: TIMx_CH2 */ + 0x00U, /* 3: TIMx_CH2N */ + 0x04U, /* 4: TIMx_CH3 */ + 0x04U, /* 5: TIMx_CH3N */ + 0x04U /* 6: TIMx_CH4 */ + }; + + static const uint8_t SHIFT_TAB_OCxx[] = { + 0U, /* 0: OC1M, OC1FE, OC1PE */ + 0U, /* 1: - NA */ + 8U, /* 2: OC2M, OC2FE, OC2PE */ + 0U, /* 3: - NA */ + 0U, /* 4: OC3M, OC3FE, OC3PE */ + 0U, /* 5: - NA */ + 8U /* 6: OC4M, OC4FE, OC4PE */ + }; + + static const uint8_t SHIFT_TAB_ICxx[] = { + 0U, /* 0: CC1S, IC1PSC, IC1F */ + 0U, /* 1: - NA */ + 8U, /* 2: CC2S, IC2PSC, IC2F */ + 0U, /* 3: - NA */ + 0U, /* 4: CC3S, IC3PSC, IC3F */ + 0U, /* 5: - NA */ + 8U /* 6: CC4S, IC4PSC, IC4F */ + }; + + static const uint8_t SHIFT_TAB_CCxP[] = { + 0U, /* 0: CC1P */ + 2U, /* 1: CC1NP */ + 4U, /* 2: CC2P */ + 6U, /* 3: CC2NP */ + 8U, /* 4: CC3P */ + 10U, /* 5: CC3NP */ + 12U /* 6: CC4P */ + }; + + static const uint8_t SHIFT_TAB_OISx[] = { + 0U, /* 0: OIS1 */ + 1U, /* 1: OIS1N */ + 2U, /* 2: OIS2 */ + 3U, /* 3: OIS2N */ + 4U, /* 4: OIS3 */ + 5U, /* 5: OIS3N */ + 6U /* 6: OIS4 */ + }; + /** + * @} + */ + + /* Private constants ---------------------------------------------------------*/ + /** @defgroup TIM_LL_Private_Constants TIM Private Constants + * @{ + */ + + +#define TIMx_OR_RMP_SHIFT 16U +#define TIMx_OR_RMP_MASK 0x0000FFFFU +#define TIM14_OR_RMP_MASK (TIM14_OR_TI1_RMP << TIMx_OR_RMP_SHIFT) + +/* Mask used to set the TDG[x:0] of the DTG bits of the TIMx_BDTR register */ +#define DT_DELAY_1 ((uint8_t)0x7F) +#define DT_DELAY_2 ((uint8_t)0x3F) +#define DT_DELAY_3 ((uint8_t)0x1F) +#define DT_DELAY_4 ((uint8_t)0x1F) + +/* Mask used to set the DTG[7:5] bits of the DTG bits of the TIMx_BDTR register */ +#define DT_RANGE_1 ((uint8_t)0x00) +#define DT_RANGE_2 ((uint8_t)0x80) +#define DT_RANGE_3 ((uint8_t)0xC0) +#define DT_RANGE_4 ((uint8_t)0xE0) + + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Macros TIM Private Macros + * @{ + */ +/** @brief Convert channel id into channel index. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval none + */ +#define TIM_GET_CHANNEL_INDEX(__CHANNEL__) \ + (((__CHANNEL__) == LL_TIM_CHANNEL_CH1) ? 0U \ + : ((__CHANNEL__) == LL_TIM_CHANNEL_CH1N) ? 1U \ + : ((__CHANNEL__) == LL_TIM_CHANNEL_CH2) ? 2U \ + : ((__CHANNEL__) == LL_TIM_CHANNEL_CH2N) ? 3U \ + : ((__CHANNEL__) == LL_TIM_CHANNEL_CH3) ? 4U \ + : ((__CHANNEL__) == LL_TIM_CHANNEL_CH3N) ? 5U \ + : 6U) + +/** @brief Calculate the deadtime sampling period(in ps). + * @param __TIMCLK__ timer input clock frequency (in Hz). + * @param __CKD__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @retval none + */ +#define TIM_CALC_DTS(__TIMCLK__, __CKD__) \ + (((__CKD__) == LL_TIM_CLOCKDIVISION_DIV1) \ + ? ((uint64_t)1000000000000U / (__TIMCLK__)) \ + : ((__CKD__) == LL_TIM_CLOCKDIVISION_DIV2) \ + ? ((uint64_t)1000000000000U / ((__TIMCLK__) >> 1U)) \ + : ((uint64_t)1000000000000U / ((__TIMCLK__) >> 2U))) +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup TIM_LL_ES_INIT TIM Exported Init structure + * @{ + */ + + /** + * @brief TIM Time Base configuration structure definition. + */ + typedef struct + { + uint16_t + Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between Min_Data=0x0000 and + Max_Data=0xFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetPrescaler().*/ + + uint32_t + CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_LL_EC_COUNTERMODE. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_SetCounterMode().*/ + + uint32_t + Autoreload; /*!< Specifies the auto reload value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between Min_Data=0x0000 and + Max_Data=0xFFFF. Some timer instances may support 32 bits + counters. In that case this parameter must be a number between + 0x0000 and 0xFFFFFFFF. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_SetAutoReload().*/ + + uint32_t ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref + TIM_LL_EC_CLOCKDIVISION. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_SetClockDivision().*/ + + uint32_t + RepetitionCounter; /*!< Specifies the repetition counter value. Each time the + RCR downcounter reaches zero, an update event is + generated and counting restarts from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned + mode GP timers: this parameter must be a number between + Min_Data = 0x00 and Max_Data = 0xFF. Advanced timers: + this parameter must be a number between Min_Data = + 0x0000 and Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_SetRepetitionCounter().*/ + } LL_TIM_InitTypeDef; + + /** + * @brief TIM Output Compare configuration structure definition. + */ + typedef struct + { + uint32_t + OCMode; /*!< Specifies the output mode. + This parameter can be a value of @ref TIM_LL_EC_OCMODE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetMode().*/ + + uint32_t + OCState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_LL_EC_OCSTATE. + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_CC_EnableChannel() or @ref + LL_TIM_CC_DisableChannel().*/ + + uint32_t + OCNState; /*!< Specifies the TIM complementary Output Compare state. + This parameter can be a value of @ref TIM_LL_EC_OCSTATE. + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_CC_EnableChannel() or @ref + LL_TIM_CC_DisableChannel().*/ + + uint32_t CompareValue; /*!< Specifies the Compare value to be loaded into the + Capture Compare Register. This parameter can be a number + between Min_Data=0x0000 and Max_Data=0xFFFF. + + This feature can be modified afterwards using unitary + function LL_TIM_OC_SetCompareCHx (x=1..6).*/ + + uint32_t + OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_LL_EC_OCPOLARITY. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_OC_SetPolarity().*/ + + uint32_t + OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_LL_EC_OCPOLARITY. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_OC_SetPolarity().*/ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle + state. This parameter can be a value of @ref + TIM_LL_EC_OCIDLESTATE. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_OC_SetIdleState().*/ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle + state. This parameter can be a value of @ref + TIM_LL_EC_OCIDLESTATE. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_OC_SetIdleState().*/ + } LL_TIM_OC_InitTypeDef; + + /** + * @brief TIM Input Capture configuration structure definition. + */ + + typedef struct + { + uint32_t + ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t ICActiveInput; /*!< Specifies the input. + This parameter can be a value of @ref + TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t + ICFilter; /*!< Specifies the input capture filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + } LL_TIM_IC_InitTypeDef; + + + /** + * @brief TIM Encoder interface configuration structure definition. + */ + typedef struct + { + uint32_t + EncoderMode; /*!< Specifies the encoder resolution (x2 or x4). + This parameter can be a value of @ref TIM_LL_EC_ENCODERMODE. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_SetEncoderMode().*/ + + uint32_t + IC1Polarity; /*!< Specifies the active edge of TI1 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC1ActiveInput; /*!< Specifies the TI1 input source + This parameter can be a value of @ref + TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using + unitary function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t IC1Prescaler; /*!< Specifies the TI1 input prescaler value. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t + IC1Filter; /*!< Specifies the TI1 input filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + + uint32_t + IC2Polarity; /*!< Specifies the active edge of TI2 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC2ActiveInput; /*!< Specifies the TI2 input source + This parameter can be a value of @ref + TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using + unitary function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t IC2Prescaler; /*!< Specifies the TI2 input prescaler value. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t + IC2Filter; /*!< Specifies the TI2 input filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + + } LL_TIM_ENCODER_InitTypeDef; + + /** + * @brief TIM Hall sensor interface configuration structure definition. + */ + typedef struct + { + uint32_t + IC1Polarity; /*!< Specifies the active edge of TI1 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC1Prescaler; /*!< Specifies the TI1 input prescaler value. + Prescaler must be set to get a maximum counter period + longer than the time interval between 2 consecutive + changes on the Hall inputs. This parameter can be a + value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t + IC1Filter; /*!< Specifies the TI1 input filter. + This parameter can be a value of + @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + + uint32_t + CommutationDelay; /*!< Specifies the compare value to be loaded into the + Capture Compare Register. A positive pulse (TRGO event) + is generated with a programmable delay every time a + change occurs on the Hall inputs. This parameter can be a + number between Min_Data = 0x0000 and Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_OC_SetCompareCH2().*/ + } LL_TIM_HALLSENSOR_InitTypeDef; + + /** + * @brief BDTR (Break and Dead Time) structure definition + */ + typedef struct + { + uint32_t + OSSRState; /*!< Specifies the Off-State selection used in Run mode. + This parameter can be a value of @ref TIM_LL_EC_OSSR + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetOffStates() + + @note This bit-field cannot be modified as long as LOCK level + 2 has been programmed. */ + + uint32_t + OSSIState; /*!< Specifies the Off-State used in Idle state. + This parameter can be a value of @ref TIM_LL_EC_OSSI + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetOffStates() + + @note This bit-field cannot be modified as long as LOCK level + 2 has been programmed. */ + + uint32_t LockLevel; /*!< Specifies the LOCK level parameters. + This parameter can be a value of @ref TIM_LL_EC_LOCKLEVEL + + @note The LOCK bits can be written only once after the + reset. Once the TIMx_BDTR register has been written, their + content is frozen until the next reset.*/ + + uint8_t + DeadTime; /*!< Specifies the delay time between the switching-off and the + switching-on of the outputs. + This parameter can be a number between Min_Data = 0x00 and + Max_Data = 0xFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetDeadTime() + + @note This bit-field can not be modified as long as LOCK level + 1, 2 or 3 has been programmed. */ + + uint16_t + BreakState; /*!< Specifies whether the TIM Break input is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_BREAK_ENABLE + + This feature can be modified afterwards using unitary + functions + @ref LL_TIM_EnableBRK() or @ref LL_TIM_DisableBRK() + + @note This bit-field can not be modified as long as LOCK + level 1 has been programmed. */ + + uint32_t BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. + This parameter can be a value of @ref + TIM_LL_EC_BREAK_POLARITY + + This feature can be modified afterwards using unitary + function + @ref LL_TIM_ConfigBRK() + + @note This bit-field can not be modified as long as + LOCK level 1 has been programmed. */ + + uint32_t AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature + is enabled or not. This parameter can be a value of + @ref TIM_LL_EC_AUTOMATICOUTPUT_ENABLE + + This feature can be modified afterwards using + unitary functions + @ref LL_TIM_EnableAutomaticOutput() or @ref + LL_TIM_DisableAutomaticOutput() + + @note This bit-field can not be modified as long as + LOCK level 1 has been programmed. */ + } LL_TIM_BDTR_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_LL_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_TIM_ReadReg function. + * @{ + */ +#define LL_TIM_SR_UIF TIM_SR_UIF /*!< Update interrupt flag */ +#define LL_TIM_SR_CC1IF TIM_SR_CC1IF /*!< Capture/compare 1 interrupt flag */ +#define LL_TIM_SR_CC2IF TIM_SR_CC2IF /*!< Capture/compare 2 interrupt flag */ +#define LL_TIM_SR_CC3IF TIM_SR_CC3IF /*!< Capture/compare 3 interrupt flag */ +#define LL_TIM_SR_CC4IF TIM_SR_CC4IF /*!< Capture/compare 4 interrupt flag */ +#define LL_TIM_SR_COMIF TIM_SR_COMIF /*!< COM interrupt flag */ +#define LL_TIM_SR_TIF TIM_SR_TIF /*!< Trigger interrupt flag */ +#define LL_TIM_SR_BIF TIM_SR_BIF /*!< Break interrupt flag */ +#define LL_TIM_SR_CC1OF TIM_SR_CC1OF /*!< Capture/Compare 1 overcapture flag */ +#define LL_TIM_SR_CC2OF TIM_SR_CC2OF /*!< Capture/Compare 2 overcapture flag */ +#define LL_TIM_SR_CC3OF TIM_SR_CC3OF /*!< Capture/Compare 3 overcapture flag */ +#define LL_TIM_SR_CC4OF TIM_SR_CC4OF /*!< Capture/Compare 4 overcapture flag */ + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_EC_BREAK_ENABLE Break Enable + * @{ + */ +#define LL_TIM_BREAK_DISABLE 0x00000000U /*!< Break function disabled */ +#define LL_TIM_BREAK_ENABLE TIM_BDTR_BKE /*!< Break function enabled */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_AUTOMATICOUTPUT_ENABLE Automatic output enable + * @{ + */ +#define LL_TIM_AUTOMATICOUTPUT_DISABLE \ + 0x00000000U /*!< MOE can be set only by software \ + */ +#define LL_TIM_AUTOMATICOUTPUT_ENABLE \ + TIM_BDTR_AOE /*!< MOE can be set by software or automatically at the next update \ + event */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup TIM_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_TIM_ReadReg and LL_TIM_WriteReg + * functions. + * @{ + */ +#define LL_TIM_DIER_UIE TIM_DIER_UIE /*!< Update interrupt enable */ +#define LL_TIM_DIER_CC1IE TIM_DIER_CC1IE /*!< Capture/compare 1 interrupt enable */ +#define LL_TIM_DIER_CC2IE TIM_DIER_CC2IE /*!< Capture/compare 2 interrupt enable */ +#define LL_TIM_DIER_CC3IE TIM_DIER_CC3IE /*!< Capture/compare 3 interrupt enable */ +#define LL_TIM_DIER_CC4IE TIM_DIER_CC4IE /*!< Capture/compare 4 interrupt enable */ +#define LL_TIM_DIER_COMIE TIM_DIER_COMIE /*!< COM interrupt enable */ +#define LL_TIM_DIER_TIE TIM_DIER_TIE /*!< Trigger interrupt enable */ +#define LL_TIM_DIER_BIE TIM_DIER_BIE /*!< Break interrupt enable */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_UPDATESOURCE Update Source + * @{ + */ +#define LL_TIM_UPDATESOURCE_REGULAR \ + 0x00000000U /*!< Counter overflow/underflow, Setting the UG bit or Update generation \ + through the slave mode controller generates an update request */ +#define LL_TIM_UPDATESOURCE_COUNTER \ + TIM_CR1_URS /*!< Only counter overflow/underflow generates an update request */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ONEPULSEMODE One Pulse Mode + * @{ + */ +#define LL_TIM_ONEPULSEMODE_SINGLE \ + TIM_CR1_OPM /*!< Counter stops counting at the next update event */ +#define LL_TIM_ONEPULSEMODE_REPETITIVE \ + 0x00000000U /*!< Counter is not stopped at update event */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_COUNTERMODE Counter Mode + * @{ + */ +#define LL_TIM_COUNTERMODE_UP 0x00000000U /*!TIMx_CCRy else active.*/ +#define LL_TIM_OCMODE_PWM2 \ + (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | \ + TIM_CCMR1_OC1M_0) /*!TIMx_CCRy else inactive*/ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_OCPOLARITY Output Configuration Polarity + * @{ + */ +#define LL_TIM_OCPOLARITY_HIGH 0x00000000U /*!< OCxactive high*/ +#define LL_TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< OCxactive low*/ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_OCIDLESTATE Output Configuration Idle State + * @{ + */ +#define LL_TIM_OCIDLESTATE_LOW \ + 0x00000000U /*!__REG__, (__VALUE__)) + +/** + * @brief Read a value in TIM register. + * @param __INSTANCE__ TIM Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_TIM_ReadReg(__INSTANCE__, __REG__) READ_REG((__INSTANCE__)->__REG__) +/** + * @} + */ + +/** + * @brief HELPER macro calculating DTG[0:7] in the TIMx_BDTR register to achieve the + * requested dead time duration. + * @note ex: @ref __LL_TIM_CALC_DEADTIME (80000000, @ref LL_TIM_GetClockDivision (), 120); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CKD__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @param __DT__ deadtime duration (in ns) + * @retval DTG[0:7] + */ +#define __LL_TIM_CALC_DEADTIME(__TIMCLK__, __CKD__, __DT__) \ + ((((uint64_t)((__DT__)*1000U)) < \ + ((DT_DELAY_1 + 1U) * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) \ + ? (uint8_t)(((uint64_t)((__DT__)*1000U) / \ + TIM_CALC_DTS((__TIMCLK__), (__CKD__))) & \ + DT_DELAY_1) \ + : (((uint64_t)((__DT__)*1000U)) < \ + ((64U + (DT_DELAY_2 + 1U)) * 2U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) \ + ? (uint8_t)(DT_RANGE_2 | \ + ((uint8_t)((uint8_t)((((uint64_t)((__DT__)*1000U)) / \ + TIM_CALC_DTS((__TIMCLK__), (__CKD__))) >> \ + 1U) - \ + (uint8_t)64) & \ + DT_DELAY_2)) \ + : (((uint64_t)((__DT__)*1000U)) < \ + ((32U + (DT_DELAY_3 + 1U)) * 8U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) \ + ? (uint8_t)(DT_RANGE_3 | \ + ((uint8_t)((uint8_t)(((((uint64_t)(__DT__)*1000U)) / \ + TIM_CALC_DTS((__TIMCLK__), (__CKD__))) >> \ + 3U) - \ + (uint8_t)32) & \ + DT_DELAY_3)) \ + : (((uint64_t)((__DT__)*1000U)) < \ + ((32U + (DT_DELAY_4 + 1U)) * 16U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) \ + ? (uint8_t)(DT_RANGE_4 | \ + ((uint8_t)((uint8_t)(((((uint64_t)(__DT__)*1000U)) / \ + TIM_CALC_DTS((__TIMCLK__), (__CKD__))) >> \ + 4U) - \ + (uint8_t)32) & \ + DT_DELAY_4)) \ + : 0U) + +/** + * @brief HELPER macro calculating the prescaler value to achieve the required counter + * clock frequency. + * @note ex: @ref __LL_TIM_CALC_PSC (80000000, 1000000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CNTCLK__ counter clock frequency (in Hz) + * @retval Prescaler value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PSC(__TIMCLK__, __CNTCLK__) \ + (((__TIMCLK__) >= (__CNTCLK__)) \ + ? (uint32_t)((((__TIMCLK__) + (__CNTCLK__) / 2U) / (__CNTCLK__)) - 1U) \ + : 0U) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required output + * signal frequency. + * @note ex: @ref __LL_TIM_CALC_ARR (1000000, @ref LL_TIM_GetPrescaler (), 10000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __FREQ__ output signal frequency (in Hz) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_ARR(__TIMCLK__, __PSC__, __FREQ__) \ + ((((__TIMCLK__) / ((__PSC__) + 1U)) >= (__FREQ__)) \ + ? (((__TIMCLK__) / ((__FREQ__) * ((__PSC__) + 1U))) - 1U) \ + : 0U) + +/** + * @brief HELPER macro calculating the compare value required to achieve the required + * timer output compare active/inactive delay. + * @note ex: @ref __LL_TIM_CALC_DELAY (1000000, @ref LL_TIM_GetPrescaler (), 10); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @retval Compare value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_DELAY(__TIMCLK__, __PSC__, __DELAY__) \ + ((uint32_t)(((uint64_t)(__TIMCLK__) * (uint64_t)(__DELAY__)) / \ + ((uint64_t)1000000U * (uint64_t)((__PSC__) + 1U)))) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required pulse + * duration (when the timer operates in one pulse mode). + * @note ex: @ref __LL_TIM_CALC_PULSE (1000000, @ref LL_TIM_GetPrescaler (), 10, 20); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @param __PULSE__ pulse duration (in us) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PULSE(__TIMCLK__, __PSC__, __DELAY__, __PULSE__) \ + ((uint32_t)(__LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__PULSE__)) + \ + __LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__DELAY__)))) + +/** + * @brief HELPER macro retrieving the ratio of the input capture prescaler + * @note ex: @ref __LL_TIM_GET_ICPSC_RATIO (@ref LL_TIM_IC_GetPrescaler ()); + * @param __ICPSC__ This parameter can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + * @retval Input capture prescaler ratio (1, 2, 4 or 8) + */ +#define __LL_TIM_GET_ICPSC_RATIO(__ICPSC__) \ + ((uint32_t)(0x01U << (((__ICPSC__) >> 16U) >> TIM_CCMR1_IC1PSC_Pos))) + + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup TIM_LL_Exported_Functions TIM Exported Functions + * @{ + */ + + /** @defgroup TIM_LL_EF_Time_Base Time Base configuration + * @{ + */ + /** + * @brief Enable timer counter. + * @rmtoll CR1 CEN LL_TIM_EnableCounter + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableCounter(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->CR1, TIM_CR1_CEN); + } + + /** + * @brief Disable timer counter. + * @rmtoll CR1 CEN LL_TIM_DisableCounter + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableCounter(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->CR1, TIM_CR1_CEN); + } + + /** + * @brief Indicates whether the timer counter is enabled. + * @rmtoll CR1 CEN LL_TIM_IsEnabledCounter + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledCounter(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->CR1, TIM_CR1_CEN) == (TIM_CR1_CEN)) ? 1UL : 0UL); + } + + /** + * @brief Enable update event generation. + * @rmtoll CR1 UDIS LL_TIM_EnableUpdateEvent + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableUpdateEvent(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->CR1, TIM_CR1_UDIS); + } + + /** + * @brief Disable update event generation. + * @rmtoll CR1 UDIS LL_TIM_DisableUpdateEvent + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableUpdateEvent(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->CR1, TIM_CR1_UDIS); + } + + /** + * @brief Indicates whether update event generation is enabled. + * @rmtoll CR1 UDIS LL_TIM_IsEnabledUpdateEvent + * @param TIMx Timer instance + * @retval Inverted state of bit (0 or 1). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledUpdateEvent(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->CR1, TIM_CR1_UDIS) == (uint32_t)RESET) ? 1UL : 0UL); + } + + /** + * @brief Set update event source + * @note Update event source set to LL_TIM_UPDATESOURCE_REGULAR: any of the following + * events generate an update interrupt or DMA request if enabled: + * - Counter overflow/underflow + * - Setting the UG bit + * - Update generation through the slave mode controller + * @note Update event source set to LL_TIM_UPDATESOURCE_COUNTER: only counter + * overflow/underflow generates an update interrupt or DMA request if enabled. + * @rmtoll CR1 URS LL_TIM_SetUpdateSource + * @param TIMx Timer instance + * @param UpdateSource This parameter can be one of the following values: + * @arg @ref LL_TIM_UPDATESOURCE_REGULAR + * @arg @ref LL_TIM_UPDATESOURCE_COUNTER + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetUpdateSource(TIM_TypeDef *TIMx, uint32_t UpdateSource) + { + MODIFY_REG(TIMx->CR1, TIM_CR1_URS, UpdateSource); + } + + /** + * @brief Get actual event update source + * @rmtoll CR1 URS LL_TIM_GetUpdateSource + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_UPDATESOURCE_REGULAR + * @arg @ref LL_TIM_UPDATESOURCE_COUNTER + */ + __STATIC_INLINE uint32_t LL_TIM_GetUpdateSource(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_URS)); + } + + /** + * @brief Set one pulse mode (one shot v.s. repetitive). + * @rmtoll CR1 OPM LL_TIM_SetOnePulseMode + * @param TIMx Timer instance + * @param OnePulseMode This parameter can be one of the following values: + * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE + * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetOnePulseMode(TIM_TypeDef *TIMx, uint32_t OnePulseMode) + { + MODIFY_REG(TIMx->CR1, TIM_CR1_OPM, OnePulseMode); + } + + /** + * @brief Get actual one pulse mode. + * @rmtoll CR1 OPM LL_TIM_GetOnePulseMode + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE + * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE + */ + __STATIC_INLINE uint32_t LL_TIM_GetOnePulseMode(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_OPM)); + } + + /** + * @brief Set the timer counter counting mode. + * @note Macro IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to + * check whether or not the counter mode selection feature is supported + * by a timer instance. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * @rmtoll CR1 DIR LL_TIM_SetCounterMode\n + * CR1 CMS LL_TIM_SetCounterMode + * @param TIMx Timer instance + * @param CounterMode This parameter can be one of the following values: + * @arg @ref LL_TIM_COUNTERMODE_UP + * @arg @ref LL_TIM_COUNTERMODE_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP + * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetCounterMode(TIM_TypeDef *TIMx, uint32_t CounterMode) + { + MODIFY_REG(TIMx->CR1, (TIM_CR1_DIR | TIM_CR1_CMS), CounterMode); + } + + /** + * @brief Get actual counter mode. + * @note Macro IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to + * check whether or not the counter mode selection feature is supported + * by a timer instance. + * @rmtoll CR1 DIR LL_TIM_GetCounterMode\n + * CR1 CMS LL_TIM_GetCounterMode + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_COUNTERMODE_UP + * @arg @ref LL_TIM_COUNTERMODE_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP + * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN + */ + __STATIC_INLINE uint32_t LL_TIM_GetCounterMode(const TIM_TypeDef *TIMx) + { + uint32_t counter_mode; + + counter_mode = (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CMS)); + + if (counter_mode == 0U) + { + counter_mode = (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); + } + + return counter_mode; + } + + /** + * @brief Enable auto-reload (ARR) preload. + * @rmtoll CR1 ARPE LL_TIM_EnableARRPreload + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableARRPreload(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->CR1, TIM_CR1_ARPE); + } + + /** + * @brief Disable auto-reload (ARR) preload. + * @rmtoll CR1 ARPE LL_TIM_DisableARRPreload + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableARRPreload(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->CR1, TIM_CR1_ARPE); + } + + /** + * @brief Indicates whether auto-reload (ARR) preload is enabled. + * @rmtoll CR1 ARPE LL_TIM_IsEnabledARRPreload + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledARRPreload(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->CR1, TIM_CR1_ARPE) == (TIM_CR1_ARPE)) ? 1UL : 0UL); + } + + /** + * @brief Set the division ratio between the timer clock and the sampling clock used + * by the dead-time generators (when supported) and the digital filters. + * @note Macro IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * whether or not the clock division feature is supported by the timer + * instance. + * @rmtoll CR1 CKD LL_TIM_SetClockDivision + * @param TIMx Timer instance + * @param ClockDivision This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetClockDivision(TIM_TypeDef *TIMx, + uint32_t ClockDivision) + { + MODIFY_REG(TIMx->CR1, TIM_CR1_CKD, ClockDivision); + } + + /** + * @brief Get the actual division ratio between the timer clock and the sampling + * clock used by the dead-time generators (when supported) and the digital filters. + * @note Macro IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * whether or not the clock division feature is supported by the timer + * instance. + * @rmtoll CR1 CKD LL_TIM_GetClockDivision + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + */ + __STATIC_INLINE uint32_t LL_TIM_GetClockDivision(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CKD)); + } + + /** + * @brief Set the counter value. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @rmtoll CNT CNT LL_TIM_SetCounter + * @param TIMx Timer instance + * @param Counter Counter value (between Min_Data=0 and Max_Data=0xFFFF or + * 0xFFFFFFFF) + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetCounter(TIM_TypeDef *TIMx, uint32_t Counter) + { + WRITE_REG(TIMx->CNT, Counter); + } + + /** + * @brief Get the counter value. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @rmtoll CNT CNT LL_TIM_GetCounter + * @param TIMx Timer instance + * @retval Counter value (between Min_Data=0 and Max_Data=0xFFFF or 0xFFFFFFFF) + */ + __STATIC_INLINE uint32_t LL_TIM_GetCounter(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CNT)); + } + + /** + * @brief Get the current direction of the counter + * @rmtoll CR1 DIR LL_TIM_GetDirection + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_COUNTERDIRECTION_UP + * @arg @ref LL_TIM_COUNTERDIRECTION_DOWN + */ + __STATIC_INLINE uint32_t LL_TIM_GetDirection(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); + } + + /** + * @brief Set the prescaler value. + * @note The counter clock frequency CK_CNT is equal to fCK_PSC / (PSC[15:0] + 1). + * @note The prescaler can be changed on the fly as this control register is buffered. + * The new prescaler ratio is taken into account at the next update event. + * @note Helper macro @ref __LL_TIM_CALC_PSC can be used to calculate the Prescaler + * parameter + * @rmtoll PSC PSC LL_TIM_SetPrescaler + * @param TIMx Timer instance + * @param Prescaler between Min_Data=0 and Max_Data=65535 + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Prescaler) + { + WRITE_REG(TIMx->PSC, Prescaler); + } + + /** + * @brief Get the prescaler value. + * @rmtoll PSC PSC LL_TIM_GetPrescaler + * @param TIMx Timer instance + * @retval Prescaler value between Min_Data=0 and Max_Data=65535 + */ + __STATIC_INLINE uint32_t LL_TIM_GetPrescaler(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->PSC)); + } + + /** + * @brief Set the auto-reload value. + * @note The counter is blocked while the auto-reload value is null. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Helper macro @ref __LL_TIM_CALC_ARR can be used to calculate the AutoReload + * parameter + * @rmtoll ARR ARR LL_TIM_SetAutoReload + * @param TIMx Timer instance + * @param AutoReload between Min_Data=0 and Max_Data=65535 + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetAutoReload(TIM_TypeDef *TIMx, uint32_t AutoReload) + { + WRITE_REG(TIMx->ARR, AutoReload); + } + + /** + * @brief Get the auto-reload value. + * @rmtoll ARR ARR LL_TIM_GetAutoReload + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @param TIMx Timer instance + * @retval Auto-reload value + */ + __STATIC_INLINE uint32_t LL_TIM_GetAutoReload(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->ARR)); + } + + /** + * @brief Set the repetition counter value. + * @note Macro IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a repetition counter. + * @rmtoll RCR REP LL_TIM_SetRepetitionCounter + * @param TIMx Timer instance + * @param RepetitionCounter between Min_Data=0 and Max_Data=255 or 65535 for advanced + * timer. + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetRepetitionCounter(TIM_TypeDef *TIMx, + uint32_t RepetitionCounter) + { + WRITE_REG(TIMx->RCR, RepetitionCounter); + } + + /** + * @brief Get the repetition counter value. + * @note Macro IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a repetition counter. + * @rmtoll RCR REP LL_TIM_GetRepetitionCounter + * @param TIMx Timer instance + * @retval Repetition counter value + */ + __STATIC_INLINE uint32_t LL_TIM_GetRepetitionCounter(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->RCR)); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_Capture_Compare Capture Compare configuration + * @{ + */ + /** + * @brief Enable the capture/compare control bits (CCxE, CCxNE and OCxM) preload. + * @note CCxE, CCxNE and OCxM bits are preloaded, after having been written, + * they are updated only when a commutation event (COM) occurs. + * @note Only on channels that have a complementary output. + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCPC LL_TIM_CC_EnablePreload + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_CC_EnablePreload(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->CR2, TIM_CR2_CCPC); + } + + /** + * @brief Disable the capture/compare control bits (CCxE, CCxNE and OCxM) preload. + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCPC LL_TIM_CC_DisablePreload + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_CC_DisablePreload(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->CR2, TIM_CR2_CCPC); + } + + /** + * @brief Set the updated source of the capture/compare control bits (CCxE, CCxNE and + * OCxM). + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCUS LL_TIM_CC_SetUpdate + * @param TIMx Timer instance + * @param CCUpdateSource This parameter can be one of the following values: + * @arg @ref LL_TIM_CCUPDATESOURCE_COMG_ONLY + * @arg @ref LL_TIM_CCUPDATESOURCE_COMG_AND_TRGI + * @retval None + */ + __STATIC_INLINE void LL_TIM_CC_SetUpdate(TIM_TypeDef *TIMx, uint32_t CCUpdateSource) + { + MODIFY_REG(TIMx->CR2, TIM_CR2_CCUS, CCUpdateSource); + } + + /** + * @brief Set the trigger of the capture/compare DMA request. + * @rmtoll CR2 CCDS LL_TIM_CC_SetDMAReqTrigger + * @param TIMx Timer instance + * @param DMAReqTrigger This parameter can be one of the following values: + * @arg @ref LL_TIM_CCDMAREQUEST_CC + * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE + * @retval None + */ + __STATIC_INLINE void LL_TIM_CC_SetDMAReqTrigger(TIM_TypeDef *TIMx, + uint32_t DMAReqTrigger) + { + MODIFY_REG(TIMx->CR2, TIM_CR2_CCDS, DMAReqTrigger); + } + + /** + * @brief Get actual trigger of the capture/compare DMA request. + * @rmtoll CR2 CCDS LL_TIM_CC_GetDMAReqTrigger + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_CCDMAREQUEST_CC + * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE + */ + __STATIC_INLINE uint32_t LL_TIM_CC_GetDMAReqTrigger(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_BIT(TIMx->CR2, TIM_CR2_CCDS)); + } + + /** + * @brief Set the lock level to freeze the + * configuration of several capture/compare parameters. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * the lock mechanism is supported by a timer instance. + * @rmtoll BDTR LOCK LL_TIM_CC_SetLockLevel + * @param TIMx Timer instance + * @param LockLevel This parameter can be one of the following values: + * @arg @ref LL_TIM_LOCKLEVEL_OFF + * @arg @ref LL_TIM_LOCKLEVEL_1 + * @arg @ref LL_TIM_LOCKLEVEL_2 + * @arg @ref LL_TIM_LOCKLEVEL_3 + * @retval None + */ + __STATIC_INLINE void LL_TIM_CC_SetLockLevel(TIM_TypeDef *TIMx, uint32_t LockLevel) + { + MODIFY_REG(TIMx->BDTR, TIM_BDTR_LOCK, LockLevel); + } + + /** + * @brief Enable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_EnableChannel\n + * CCER CC1NE LL_TIM_CC_EnableChannel\n + * CCER CC2E LL_TIM_CC_EnableChannel\n + * CCER CC2NE LL_TIM_CC_EnableChannel\n + * CCER CC3E LL_TIM_CC_EnableChannel\n + * CCER CC3NE LL_TIM_CC_EnableChannel\n + * CCER CC4E LL_TIM_CC_EnableChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_CC_EnableChannel(TIM_TypeDef *TIMx, uint32_t Channels) + { + SET_BIT(TIMx->CCER, Channels); + } + + /** + * @brief Disable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_DisableChannel\n + * CCER CC1NE LL_TIM_CC_DisableChannel\n + * CCER CC2E LL_TIM_CC_DisableChannel\n + * CCER CC2NE LL_TIM_CC_DisableChannel\n + * CCER CC3E LL_TIM_CC_DisableChannel\n + * CCER CC3NE LL_TIM_CC_DisableChannel\n + * CCER CC4E LL_TIM_CC_DisableChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_CC_DisableChannel(TIM_TypeDef *TIMx, uint32_t Channels) + { + CLEAR_BIT(TIMx->CCER, Channels); + } + + /** + * @brief Indicate whether channel(s) is(are) enabled. + * @rmtoll CCER CC1E LL_TIM_CC_IsEnabledChannel\n + * CCER CC1NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC2E LL_TIM_CC_IsEnabledChannel\n + * CCER CC2NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC3E LL_TIM_CC_IsEnabledChannel\n + * CCER CC3NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC4E LL_TIM_CC_IsEnabledChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_CC_IsEnabledChannel(const TIM_TypeDef *TIMx, + uint32_t Channels) + { + return ((READ_BIT(TIMx->CCER, Channels) == (Channels)) ? 1UL : 0UL); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_Output_Channel Output channel configuration + * @{ + */ + /** + * @brief Configure an output channel. + * @rmtoll CCMR1 CC1S LL_TIM_OC_ConfigOutput\n + * CCMR1 CC2S LL_TIM_OC_ConfigOutput\n + * CCMR2 CC3S LL_TIM_OC_ConfigOutput\n + * CCMR2 CC4S LL_TIM_OC_ConfigOutput\n + * CCER CC1P LL_TIM_OC_ConfigOutput\n + * CCER CC2P LL_TIM_OC_ConfigOutput\n + * CCER CC3P LL_TIM_OC_ConfigOutput\n + * CCER CC4P LL_TIM_OC_ConfigOutput\n + * CR2 OIS1 LL_TIM_OC_ConfigOutput\n + * CR2 OIS2 LL_TIM_OC_ConfigOutput\n + * CR2 OIS3 LL_TIM_OC_ConfigOutput\n + * CR2 OIS4 LL_TIM_OC_ConfigOutput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Configuration This parameter must be a combination of all the following + * values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH or @ref LL_TIM_OCPOLARITY_LOW + * @arg @ref LL_TIM_OCIDLESTATE_LOW or @ref LL_TIM_OCIDLESTATE_HIGH + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_ConfigOutput(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t Configuration) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_CC1S << SHIFT_TAB_OCxx[iChannel])); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), + (Configuration & TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]); + MODIFY_REG(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel]), + (Configuration & TIM_CR2_OIS1) << SHIFT_TAB_OISx[iChannel]); + } + + /** + * @brief Define the behavior of the output reference signal OCxREF from which + * OCx and OCxN (when relevant) are derived. + * @rmtoll CCMR1 OC1M LL_TIM_OC_SetMode\n + * CCMR1 OC2M LL_TIM_OC_SetMode\n + * CCMR2 OC3M LL_TIM_OC_SetMode\n + * CCMR2 OC4M LL_TIM_OC_SetMode + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_TIM_OCMODE_FROZEN + * @arg @ref LL_TIM_OCMODE_ACTIVE + * @arg @ref LL_TIM_OCMODE_INACTIVE + * @arg @ref LL_TIM_OCMODE_TOGGLE + * @arg @ref LL_TIM_OCMODE_FORCED_INACTIVE + * @arg @ref LL_TIM_OCMODE_FORCED_ACTIVE + * @arg @ref LL_TIM_OCMODE_PWM1 + * @arg @ref LL_TIM_OCMODE_PWM2 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_SetMode(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t Mode) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel]), + Mode << SHIFT_TAB_OCxx[iChannel]); + } + + /** + * @brief Get the output compare mode of an output channel. + * @rmtoll CCMR1 OC1M LL_TIM_OC_GetMode\n + * CCMR1 OC2M LL_TIM_OC_GetMode\n + * CCMR2 OC3M LL_TIM_OC_GetMode\n + * CCMR2 OC4M LL_TIM_OC_GetMode + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCMODE_FROZEN + * @arg @ref LL_TIM_OCMODE_ACTIVE + * @arg @ref LL_TIM_OCMODE_INACTIVE + * @arg @ref LL_TIM_OCMODE_TOGGLE + * @arg @ref LL_TIM_OCMODE_FORCED_INACTIVE + * @arg @ref LL_TIM_OCMODE_FORCED_ACTIVE + * @arg @ref LL_TIM_OCMODE_PWM1 + * @arg @ref LL_TIM_OCMODE_PWM2 + */ + __STATIC_INLINE uint32_t LL_TIM_OC_GetMode(const TIM_TypeDef *TIMx, uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)(( + uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return (READ_BIT(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) + << SHIFT_TAB_OCxx[iChannel])) >> + SHIFT_TAB_OCxx[iChannel]); + } + + /** + * @brief Set the polarity of an output channel. + * @rmtoll CCER CC1P LL_TIM_OC_SetPolarity\n + * CCER CC1NP LL_TIM_OC_SetPolarity\n + * CCER CC2P LL_TIM_OC_SetPolarity\n + * CCER CC2NP LL_TIM_OC_SetPolarity\n + * CCER CC3P LL_TIM_OC_SetPolarity\n + * CCER CC3NP LL_TIM_OC_SetPolarity\n + * CCER CC4P LL_TIM_OC_SetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH + * @arg @ref LL_TIM_OCPOLARITY_LOW + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t Polarity) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), + Polarity << SHIFT_TAB_CCxP[iChannel]); + } + + /** + * @brief Get the polarity of an output channel. + * @rmtoll CCER CC1P LL_TIM_OC_GetPolarity\n + * CCER CC1NP LL_TIM_OC_GetPolarity\n + * CCER CC2P LL_TIM_OC_GetPolarity\n + * CCER CC2NP LL_TIM_OC_GetPolarity\n + * CCER CC3P LL_TIM_OC_GetPolarity\n + * CCER CC3NP LL_TIM_OC_GetPolarity\n + * CCER CC4P LL_TIM_OC_GetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH + * @arg @ref LL_TIM_OCPOLARITY_LOW + */ + __STATIC_INLINE uint32_t LL_TIM_OC_GetPolarity(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel])) >> + SHIFT_TAB_CCxP[iChannel]); + } + + /** + * @brief Set the IDLE state of an output channel + * @note This function is significant only for the timer instances + * supporting the break feature. Macro IS_TIM_BREAK_INSTANCE(TIMx) + * can be used to check whether or not a timer instance provides + * a break input. + * @rmtoll CR2 OIS1 LL_TIM_OC_SetIdleState\n + * CR2 OIS1N LL_TIM_OC_SetIdleState\n + * CR2 OIS2 LL_TIM_OC_SetIdleState\n + * CR2 OIS2N LL_TIM_OC_SetIdleState\n + * CR2 OIS3 LL_TIM_OC_SetIdleState\n + * CR2 OIS3N LL_TIM_OC_SetIdleState\n + * CR2 OIS4 LL_TIM_OC_SetIdleState + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param IdleState This parameter can be one of the following values: + * @arg @ref LL_TIM_OCIDLESTATE_LOW + * @arg @ref LL_TIM_OCIDLESTATE_HIGH + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_SetIdleState(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t IdleState) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel]), + IdleState << SHIFT_TAB_OISx[iChannel]); + } + + /** + * @brief Get the IDLE state of an output channel + * @rmtoll CR2 OIS1 LL_TIM_OC_GetIdleState\n + * CR2 OIS1N LL_TIM_OC_GetIdleState\n + * CR2 OIS2 LL_TIM_OC_GetIdleState\n + * CR2 OIS2N LL_TIM_OC_GetIdleState\n + * CR2 OIS3 LL_TIM_OC_GetIdleState\n + * CR2 OIS3N LL_TIM_OC_GetIdleState\n + * CR2 OIS4 LL_TIM_OC_GetIdleState + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCIDLESTATE_LOW + * @arg @ref LL_TIM_OCIDLESTATE_HIGH + */ + __STATIC_INLINE uint32_t LL_TIM_OC_GetIdleState(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel])) >> + SHIFT_TAB_OISx[iChannel]); + } + + /** + * @brief Enable fast mode for the output channel. + * @note Acts only if the channel is configured in PWM1 or PWM2 mode. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_EnableFast\n + * CCMR1 OC2FE LL_TIM_OC_EnableFast\n + * CCMR2 OC3FE LL_TIM_OC_EnableFast\n + * CCMR2 OC4FE LL_TIM_OC_EnableFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_EnableFast(TIM_TypeDef *TIMx, uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); + } + + /** + * @brief Disable fast mode for the output channel. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_DisableFast\n + * CCMR1 OC2FE LL_TIM_OC_DisableFast\n + * CCMR2 OC3FE LL_TIM_OC_DisableFast\n + * CCMR2 OC4FE LL_TIM_OC_DisableFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_DisableFast(TIM_TypeDef *TIMx, uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); + } + + /** + * @brief Indicates whether fast mode is enabled for the output channel. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_IsEnabledFast\n + * CCMR1 OC2FE LL_TIM_OC_IsEnabledFast\n + * CCMR2 OC3FE LL_TIM_OC_IsEnabledFast\n + * CCMR2 OC4FE LL_TIM_OC_IsEnabledFast\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledFast(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)(( + uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); + } + + /** + * @brief Enable compare register (TIMx_CCRx) preload for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_EnablePreload\n + * CCMR1 OC2PE LL_TIM_OC_EnablePreload\n + * CCMR2 OC3PE LL_TIM_OC_EnablePreload\n + * CCMR2 OC4PE LL_TIM_OC_EnablePreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_EnablePreload(TIM_TypeDef *TIMx, uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); + } + + /** + * @brief Disable compare register (TIMx_CCRx) preload for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_DisablePreload\n + * CCMR1 OC2PE LL_TIM_OC_DisablePreload\n + * CCMR2 OC3PE LL_TIM_OC_DisablePreload\n + * CCMR2 OC4PE LL_TIM_OC_DisablePreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_DisablePreload(TIM_TypeDef *TIMx, uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); + } + + /** + * @brief Indicates whether compare register (TIMx_CCRx) preload is enabled for the + * output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_IsEnabledPreload\n + * CCMR1 OC2PE LL_TIM_OC_IsEnabledPreload\n + * CCMR2 OC3PE LL_TIM_OC_IsEnabledPreload\n + * CCMR2 OC4PE LL_TIM_OC_IsEnabledPreload\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledPreload(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)(( + uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); + } + + /** + * @brief Enable clearing the output channel on an external event. + * @note This function can only be used in Output compare and PWM modes. It does not + * work in Forced mode. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_EnableClear\n + * CCMR1 OC2CE LL_TIM_OC_EnableClear\n + * CCMR2 OC3CE LL_TIM_OC_EnableClear\n + * CCMR2 OC4CE LL_TIM_OC_EnableClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_EnableClear(TIM_TypeDef *TIMx, uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); + } + + /** + * @brief Disable clearing the output channel on an external event. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_DisableClear\n + * CCMR1 OC2CE LL_TIM_OC_DisableClear\n + * CCMR2 OC3CE LL_TIM_OC_DisableClear\n + * CCMR2 OC4CE LL_TIM_OC_DisableClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_DisableClear(TIM_TypeDef *TIMx, uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); + } + + /** + * @brief Indicates clearing the output channel on an external event is enabled for + * the output channel. + * @note This function enables clearing the output channel on an external event. + * @note This function can only be used in Output compare and PWM modes. It does not + * work in Forced mode. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_IsEnabledClear\n + * CCMR1 OC2CE LL_TIM_OC_IsEnabledClear\n + * CCMR2 OC3CE LL_TIM_OC_IsEnabledClear\n + * CCMR2 OC4CE LL_TIM_OC_IsEnabledClear\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledClear(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)(( + uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); + } + + /** + * @brief Set the dead-time delay (delay inserted between the rising edge of the + * OCxREF signal and the rising edge of the Ocx and OCxN signals). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * dead-time insertion feature is supported by a timer instance. + * @note Helper macro @ref __LL_TIM_CALC_DEADTIME can be used to calculate the + * DeadTime parameter + * @rmtoll BDTR DTG LL_TIM_OC_SetDeadTime + * @param TIMx Timer instance + * @param DeadTime between Min_Data=0 and Max_Data=255 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_SetDeadTime(TIM_TypeDef *TIMx, uint32_t DeadTime) + { + MODIFY_REG(TIMx->BDTR, TIM_BDTR_DTG, DeadTime); + } + + /** + * @brief Set compare value for output channel 1 (TIMx_CCR1). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and + * 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * output channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_OC_SetCompareCH1 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_SetCompareCH1(TIM_TypeDef *TIMx, uint32_t CompareValue) + { + WRITE_REG(TIMx->CCR1, CompareValue); + } + + /** + * @brief Set compare value for output channel 2 (TIMx_CCR2). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and + * 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * output channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_OC_SetCompareCH2 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_SetCompareCH2(TIM_TypeDef *TIMx, uint32_t CompareValue) + { + WRITE_REG(TIMx->CCR2, CompareValue); + } + + /** + * @brief Set compare value for output channel 3 (TIMx_CCR3). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and + * 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * output channel is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_OC_SetCompareCH3 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_SetCompareCH3(TIM_TypeDef *TIMx, uint32_t CompareValue) + { + WRITE_REG(TIMx->CCR3, CompareValue); + } + + /** + * @brief Set compare value for output channel 4 (TIMx_CCR4). + * @note In 32-bit timer implementations compare value can be between 0x00000000 and + * 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * output channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_OC_SetCompareCH4 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ + __STATIC_INLINE void LL_TIM_OC_SetCompareCH4(TIM_TypeDef *TIMx, uint32_t CompareValue) + { + WRITE_REG(TIMx->CCR4, CompareValue); + } + + /** + * @brief Get compare value (TIMx_CCR1) set for output channel 1. + * @note In 32-bit timer implementations returned compare value can be between + * 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * output channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_OC_GetCompareCH1 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ + __STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH1(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CCR1)); + } + + /** + * @brief Get compare value (TIMx_CCR2) set for output channel 2. + * @note In 32-bit timer implementations returned compare value can be between + * 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * output channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_OC_GetCompareCH2 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ + __STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH2(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CCR2)); + } + + /** + * @brief Get compare value (TIMx_CCR3) set for output channel 3. + * @note In 32-bit timer implementations returned compare value can be between + * 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * output channel 3 is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_OC_GetCompareCH3 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ + __STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH3(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CCR3)); + } + + /** + * @brief Get compare value (TIMx_CCR4) set for output channel 4. + * @note In 32-bit timer implementations returned compare value can be between + * 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * output channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_OC_GetCompareCH4 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ + __STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH4(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CCR4)); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_Input_Channel Input channel configuration + * @{ + */ + /** + * @brief Configure input channel. + * @rmtoll CCMR1 CC1S LL_TIM_IC_Config\n + * CCMR1 IC1PSC LL_TIM_IC_Config\n + * CCMR1 IC1F LL_TIM_IC_Config\n + * CCMR1 CC2S LL_TIM_IC_Config\n + * CCMR1 IC2PSC LL_TIM_IC_Config\n + * CCMR1 IC2F LL_TIM_IC_Config\n + * CCMR2 CC3S LL_TIM_IC_Config\n + * CCMR2 IC3PSC LL_TIM_IC_Config\n + * CCMR2 IC3F LL_TIM_IC_Config\n + * CCMR2 CC4S LL_TIM_IC_Config\n + * CCMR2 IC4PSC LL_TIM_IC_Config\n + * CCMR2 IC4F LL_TIM_IC_Config\n + * CCER CC1P LL_TIM_IC_Config\n + * CCER CC1NP LL_TIM_IC_Config\n + * CCER CC2P LL_TIM_IC_Config\n + * CCER CC2NP LL_TIM_IC_Config\n + * CCER CC3P LL_TIM_IC_Config\n + * CCER CC3NP LL_TIM_IC_Config\n + * CCER CC4P LL_TIM_IC_Config\n + * CCER CC4NP LL_TIM_IC_Config + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Configuration This parameter must be a combination of all the following + * values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI or @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * or @ref LL_TIM_ACTIVEINPUT_TRC + * @arg @ref LL_TIM_ICPSC_DIV1 or ... or @ref LL_TIM_ICPSC_DIV8 + * @arg @ref LL_TIM_IC_FILTER_FDIV1 or ... or @ref LL_TIM_IC_FILTER_FDIV32_N8 + * @arg @ref LL_TIM_IC_POLARITY_RISING or @ref LL_TIM_IC_POLARITY_FALLING or + * @ref LL_TIM_IC_POLARITY_BOTHEDGE + * @retval None + */ + __STATIC_INLINE void LL_TIM_IC_Config(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t Configuration) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, + ((TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S) + << SHIFT_TAB_ICxx[iChannel]), + ((Configuration >> 16U) & + (TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S)) + << SHIFT_TAB_ICxx[iChannel]); + MODIFY_REG(TIMx->CCER, + ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + (Configuration & (TIM_CCER_CC1NP | TIM_CCER_CC1P)) + << SHIFT_TAB_CCxP[iChannel]); + } + + /** + * @brief Set the active input. + * @rmtoll CCMR1 CC1S LL_TIM_IC_SetActiveInput\n + * CCMR1 CC2S LL_TIM_IC_SetActiveInput\n + * CCMR2 CC3S LL_TIM_IC_SetActiveInput\n + * CCMR2 CC4S LL_TIM_IC_SetActiveInput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICActiveInput This parameter can be one of the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_TRC + * @retval None + */ + __STATIC_INLINE void LL_TIM_IC_SetActiveInput(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t ICActiveInput) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), + (ICActiveInput >> 16U) << SHIFT_TAB_ICxx[iChannel]); + } + + /** + * @brief Get the current active input. + * @rmtoll CCMR1 CC1S LL_TIM_IC_GetActiveInput\n + * CCMR1 CC2S LL_TIM_IC_GetActiveInput\n + * CCMR2 CC3S LL_TIM_IC_GetActiveInput\n + * CCMR2 CC4S LL_TIM_IC_GetActiveInput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_TRC + */ + __STATIC_INLINE uint32_t LL_TIM_IC_GetActiveInput(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)(( + uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel])) >> + SHIFT_TAB_ICxx[iChannel]) + << 16U); + } + + /** + * @brief Set the prescaler of input channel. + * @rmtoll CCMR1 IC1PSC LL_TIM_IC_SetPrescaler\n + * CCMR1 IC2PSC LL_TIM_IC_SetPrescaler\n + * CCMR2 IC3PSC LL_TIM_IC_SetPrescaler\n + * CCMR2 IC4PSC LL_TIM_IC_SetPrescaler + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + * @retval None + */ + __STATIC_INLINE void LL_TIM_IC_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t ICPrescaler) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel]), + (ICPrescaler >> 16U) << SHIFT_TAB_ICxx[iChannel]); + } + + /** + * @brief Get the current prescaler value acting on an input channel. + * @rmtoll CCMR1 IC1PSC LL_TIM_IC_GetPrescaler\n + * CCMR1 IC2PSC LL_TIM_IC_GetPrescaler\n + * CCMR2 IC3PSC LL_TIM_IC_GetPrescaler\n + * CCMR2 IC4PSC LL_TIM_IC_GetPrescaler + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + */ + __STATIC_INLINE uint32_t LL_TIM_IC_GetPrescaler(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)(( + uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel])) >> + SHIFT_TAB_ICxx[iChannel]) + << 16U); + } + + /** + * @brief Set the input filter duration. + * @rmtoll CCMR1 IC1F LL_TIM_IC_SetFilter\n + * CCMR1 IC2F LL_TIM_IC_SetFilter\n + * CCMR2 IC3F LL_TIM_IC_SetFilter\n + * CCMR2 IC4F LL_TIM_IC_SetFilter + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_IC_FILTER_FDIV1 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 + * @retval None + */ + __STATIC_INLINE void LL_TIM_IC_SetFilter(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t ICFilter) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel]), + (ICFilter >> 16U) << SHIFT_TAB_ICxx[iChannel]); + } + + /** + * @brief Get the input filter duration. + * @rmtoll CCMR1 IC1F LL_TIM_IC_GetFilter\n + * CCMR1 IC2F LL_TIM_IC_GetFilter\n + * CCMR2 IC3F LL_TIM_IC_GetFilter\n + * CCMR2 IC4F LL_TIM_IC_GetFilter + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_IC_FILTER_FDIV1 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 + */ + __STATIC_INLINE uint32_t LL_TIM_IC_GetFilter(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)(( + uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel])) >> + SHIFT_TAB_ICxx[iChannel]) + << 16U); + } + + /** + * @brief Set the input channel polarity. + * @rmtoll CCER CC1P LL_TIM_IC_SetPolarity\n + * CCER CC1NP LL_TIM_IC_SetPolarity\n + * CCER CC2P LL_TIM_IC_SetPolarity\n + * CCER CC2NP LL_TIM_IC_SetPolarity\n + * CCER CC3P LL_TIM_IC_SetPolarity\n + * CCER CC3NP LL_TIM_IC_SetPolarity\n + * CCER CC4P LL_TIM_IC_SetPolarity\n + * CCER CC4NP LL_TIM_IC_SetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_IC_POLARITY_RISING + * @arg @ref LL_TIM_IC_POLARITY_FALLING + * @arg @ref LL_TIM_IC_POLARITY_BOTHEDGE + * @retval None + */ + __STATIC_INLINE void LL_TIM_IC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, + uint32_t ICPolarity) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CCER, + ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + ICPolarity << SHIFT_TAB_CCxP[iChannel]); + } + + /** + * @brief Get the current input channel polarity. + * @rmtoll CCER CC1P LL_TIM_IC_GetPolarity\n + * CCER CC1NP LL_TIM_IC_GetPolarity\n + * CCER CC2P LL_TIM_IC_GetPolarity\n + * CCER CC2NP LL_TIM_IC_GetPolarity\n + * CCER CC3P LL_TIM_IC_GetPolarity\n + * CCER CC3NP LL_TIM_IC_GetPolarity\n + * CCER CC4P LL_TIM_IC_GetPolarity\n + * CCER CC4NP LL_TIM_IC_GetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_IC_POLARITY_RISING + * @arg @ref LL_TIM_IC_POLARITY_FALLING + * @arg @ref LL_TIM_IC_POLARITY_BOTHEDGE + */ + __STATIC_INLINE uint32_t LL_TIM_IC_GetPolarity(const TIM_TypeDef *TIMx, + uint32_t Channel) + { + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) + << SHIFT_TAB_CCxP[iChannel])) >> + SHIFT_TAB_CCxP[iChannel]); + } + + /** + * @brief Connect the TIMx_CH1, CH2 and CH3 pins to the TI1 input (XOR combination). + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_EnableXORCombination + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_IC_EnableXORCombination(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->CR2, TIM_CR2_TI1S); + } + + /** + * @brief Disconnect the TIMx_CH1, CH2 and CH3 pins from the TI1 input. + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_DisableXORCombination + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_IC_DisableXORCombination(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->CR2, TIM_CR2_TI1S); + } + + /** + * @brief Indicates whether the TIMx_CH1, CH2 and CH3 pins are connectected to the + * TI1 input. + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_IsEnabledXORCombination + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IC_IsEnabledXORCombination(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->CR2, TIM_CR2_TI1S) == (TIM_CR2_TI1S)) ? 1UL : 0UL); + } + + /** + * @brief Get captured value for input channel 1. + * @note In 32-bit timer implementations returned captured value can be between + * 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * input channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_IC_GetCaptureCH1 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ + __STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH1(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CCR1)); + } + + /** + * @brief Get captured value for input channel 2. + * @note In 32-bit timer implementations returned captured value can be between + * 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * input channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_IC_GetCaptureCH2 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ + __STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH2(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CCR2)); + } + + /** + * @brief Get captured value for input channel 3. + * @note In 32-bit timer implementations returned captured value can be between + * 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * input channel 3 is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_IC_GetCaptureCH3 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ + __STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH3(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CCR3)); + } + + /** + * @brief Get captured value for input channel 4. + * @note In 32-bit timer implementations returned captured value can be between + * 0x00000000 and 0xFFFFFFFF. + * @note Macro IS_TIM_32B_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a 32 bits counter. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * input channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_IC_GetCaptureCH4 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ + __STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH4(const TIM_TypeDef *TIMx) + { + return (uint32_t)(READ_REG(TIMx->CCR4)); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_Clock_Selection Counter clock selection + * @{ + */ + /** + * @brief Enable external clock mode 2. + * @note When external clock mode 2 is enabled the counter is clocked by any active + * edge on the ETRF signal. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_EnableExternalClock + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableExternalClock(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->SMCR, TIM_SMCR_ECE); + } + + /** + * @brief Disable external clock mode 2. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_DisableExternalClock + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableExternalClock(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_ECE); + } + + /** + * @brief Indicate whether external clock mode 2 is enabled. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_IsEnabledExternalClock + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledExternalClock(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_ECE) == (TIM_SMCR_ECE)) ? 1UL : 0UL); + } + + /** + * @brief Set the clock source of the counter clock. + * @note when selected clock source is external clock mode 1, the timer input + * the external clock is applied is selected by calling the @ref + * LL_TIM_SetTriggerInput() function. This timer input must be configured by calling + * the @ref LL_TIM_IC_Config() function. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode1. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR SMS LL_TIM_SetClockSource\n + * SMCR ECE LL_TIM_SetClockSource + * @param TIMx Timer instance + * @param ClockSource This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKSOURCE_INTERNAL + * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE1 + * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE2 + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetClockSource(TIM_TypeDef *TIMx, uint32_t ClockSource) + { + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS | TIM_SMCR_ECE, ClockSource); + } + + /** + * @brief Set the encoder interface mode. + * @note Macro IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the encoder mode. + * @rmtoll SMCR SMS LL_TIM_SetEncoderMode + * @param TIMx Timer instance + * @param EncoderMode This parameter can be one of the following values: + * @arg @ref LL_TIM_ENCODERMODE_X2_TI1 + * @arg @ref LL_TIM_ENCODERMODE_X2_TI2 + * @arg @ref LL_TIM_ENCODERMODE_X4_TI12 + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetEncoderMode(TIM_TypeDef *TIMx, uint32_t EncoderMode) + { + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, EncoderMode); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_Timer_Synchronization Timer synchronisation configuration + * @{ + */ + /** + * @brief Set the trigger output (TRGO) used for timer synchronization . + * @note Macro IS_TIM_MASTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance can operate as a master timer. + * @rmtoll CR2 MMS LL_TIM_SetTriggerOutput + * @param TIMx Timer instance + * @param TimerSynchronization This parameter can be one of the following values: + * @arg @ref LL_TIM_TRGO_RESET + * @arg @ref LL_TIM_TRGO_ENABLE + * @arg @ref LL_TIM_TRGO_UPDATE + * @arg @ref LL_TIM_TRGO_CC1IF + * @arg @ref LL_TIM_TRGO_OC1REF + * @arg @ref LL_TIM_TRGO_OC2REF + * @arg @ref LL_TIM_TRGO_OC3REF + * @arg @ref LL_TIM_TRGO_OC4REF + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetTriggerOutput(TIM_TypeDef *TIMx, + uint32_t TimerSynchronization) + { + MODIFY_REG(TIMx->CR2, TIM_CR2_MMS, TimerSynchronization); + } + + /** + * @brief Set the synchronization mode of a slave timer. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR SMS LL_TIM_SetSlaveMode + * @param TIMx Timer instance + * @param SlaveMode This parameter can be one of the following values: + * @arg @ref LL_TIM_SLAVEMODE_DISABLED + * @arg @ref LL_TIM_SLAVEMODE_RESET + * @arg @ref LL_TIM_SLAVEMODE_GATED + * @arg @ref LL_TIM_SLAVEMODE_TRIGGER + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetSlaveMode(TIM_TypeDef *TIMx, uint32_t SlaveMode) + { + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, SlaveMode); + } + + /** + * @brief Set the selects the trigger input to be used to synchronize the counter. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR TS LL_TIM_SetTriggerInput + * @param TIMx Timer instance + * @param TriggerInput This parameter can be one of the following values: + * @arg @ref LL_TIM_TS_ITR0 + * @arg @ref LL_TIM_TS_ITR1 + * @arg @ref LL_TIM_TS_ITR2 + * @arg @ref LL_TIM_TS_ITR3 + * @arg @ref LL_TIM_TS_TI1F_ED + * @arg @ref LL_TIM_TS_TI1FP1 + * @arg @ref LL_TIM_TS_TI2FP2 + * @arg @ref LL_TIM_TS_ETRF + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetTriggerInput(TIM_TypeDef *TIMx, uint32_t TriggerInput) + { + MODIFY_REG(TIMx->SMCR, TIM_SMCR_TS, TriggerInput); + } + + /** + * @brief Enable the Master/Slave mode. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_EnableMasterSlaveMode + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableMasterSlaveMode(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->SMCR, TIM_SMCR_MSM); + } + + /** + * @brief Disable the Master/Slave mode. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_DisableMasterSlaveMode + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableMasterSlaveMode(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_MSM); + } + + /** + * @brief Indicates whether the Master/Slave mode is enabled. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_IsEnabledMasterSlaveMode + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledMasterSlaveMode(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_MSM) == (TIM_SMCR_MSM)) ? 1UL : 0UL); + } + + /** + * @brief Configure the external trigger (ETR) input. + * @note Macro IS_TIM_ETR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an external trigger input. + * @rmtoll SMCR ETP LL_TIM_ConfigETR\n + * SMCR ETPS LL_TIM_ConfigETR\n + * SMCR ETF LL_TIM_ConfigETR + * @param TIMx Timer instance + * @param ETRPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_POLARITY_NONINVERTED + * @arg @ref LL_TIM_ETR_POLARITY_INVERTED + * @param ETRPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_PRESCALER_DIV1 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV2 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV4 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV8 + * @param ETRFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_FILTER_FDIV1 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N8 + * @retval None + */ + __STATIC_INLINE void LL_TIM_ConfigETR(TIM_TypeDef *TIMx, uint32_t ETRPolarity, + uint32_t ETRPrescaler, uint32_t ETRFilter) + { + MODIFY_REG(TIMx->SMCR, TIM_SMCR_ETP | TIM_SMCR_ETPS | TIM_SMCR_ETF, + ETRPolarity | ETRPrescaler | ETRFilter); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_Break_Function Break function configuration + * @{ + */ + /** + * @brief Enable the break function. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR BKE LL_TIM_EnableBRK + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableBRK(TIM_TypeDef *TIMx) + { + __IO uint32_t tmpreg; + SET_BIT(TIMx->BDTR, TIM_BDTR_BKE); + /* Note: Any write operation to this bit takes a delay of 1 APB clock cycle to + * become effective. */ + tmpreg = READ_REG(TIMx->BDTR); + (void)(tmpreg); + } + + /** + * @brief Disable the break function. + * @rmtoll BDTR BKE LL_TIM_DisableBRK + * @param TIMx Timer instance + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableBRK(TIM_TypeDef *TIMx) + { + __IO uint32_t tmpreg; + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_BKE); + /* Note: Any write operation to this bit takes a delay of 1 APB clock cycle to + * become effective. */ + tmpreg = READ_REG(TIMx->BDTR); + (void)(tmpreg); + } + + /** + * @brief Configure the break input. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR BKP LL_TIM_ConfigBRK + * @param TIMx Timer instance + * @param BreakPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_POLARITY_LOW + * @arg @ref LL_TIM_BREAK_POLARITY_HIGH + * @retval None + */ + __STATIC_INLINE void LL_TIM_ConfigBRK(TIM_TypeDef *TIMx, uint32_t BreakPolarity) + { + __IO uint32_t tmpreg; + MODIFY_REG(TIMx->BDTR, TIM_BDTR_BKP, BreakPolarity); + /* Note: Any write operation to BKP bit takes a delay of 1 APB clock cycle to + * become effective. */ + tmpreg = READ_REG(TIMx->BDTR); + (void)(tmpreg); + } + + /** + * @brief Select the outputs off state (enabled v.s. disabled) in Idle and Run modes. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR OSSI LL_TIM_SetOffStates\n + * BDTR OSSR LL_TIM_SetOffStates + * @param TIMx Timer instance + * @param OffStateIdle This parameter can be one of the following values: + * @arg @ref LL_TIM_OSSI_DISABLE + * @arg @ref LL_TIM_OSSI_ENABLE + * @param OffStateRun This parameter can be one of the following values: + * @arg @ref LL_TIM_OSSR_DISABLE + * @arg @ref LL_TIM_OSSR_ENABLE + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetOffStates(TIM_TypeDef *TIMx, uint32_t OffStateIdle, + uint32_t OffStateRun) + { + MODIFY_REG(TIMx->BDTR, TIM_BDTR_OSSI | TIM_BDTR_OSSR, OffStateIdle | OffStateRun); + } + + /** + * @brief Enable automatic output (MOE can be set by software or automatically when a + * break input is active). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_EnableAutomaticOutput + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableAutomaticOutput(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->BDTR, TIM_BDTR_AOE); + } + + /** + * @brief Disable automatic output (MOE can be set only by software). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_DisableAutomaticOutput + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableAutomaticOutput(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_AOE); + } + + /** + * @brief Indicate whether automatic output is enabled. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_IsEnabledAutomaticOutput + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledAutomaticOutput(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->BDTR, TIM_BDTR_AOE) == (TIM_BDTR_AOE)) ? 1UL : 0UL); + } + + /** + * @brief Enable the outputs (set the MOE bit in TIMx_BDTR register). + * @note The MOE bit in TIMx_BDTR register allows to enable /disable the outputs by + * software and is reset in case of break or break2 event + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_EnableAllOutputs + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableAllOutputs(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->BDTR, TIM_BDTR_MOE); + } + + /** + * @brief Disable the outputs (reset the MOE bit in TIMx_BDTR register). + * @note The MOE bit in TIMx_BDTR register allows to enable /disable the outputs by + * software and is reset in case of break or break2 event. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_DisableAllOutputs + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableAllOutputs(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_MOE); + } + + /** + * @brief Indicates whether outputs are enabled. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_IsEnabledAllOutputs + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledAllOutputs(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->BDTR, TIM_BDTR_MOE) == (TIM_BDTR_MOE)) ? 1UL : 0UL); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_DMA_Burst_Mode DMA burst mode configuration + * @{ + */ + /** + * @brief Configures the timer DMA burst feature. + * @note Macro IS_TIM_DMABURST_INSTANCE(TIMx) can be used to check whether or + * not a timer instance supports the DMA burst mode. + * @rmtoll DCR DBL LL_TIM_ConfigDMABurst\n + * DCR DBA LL_TIM_ConfigDMABurst + * @param TIMx Timer instance + * @param DMABurstBaseAddress This parameter can be one of the following values: + * @arg @ref LL_TIM_DMABURST_BASEADDR_CR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_SMCR + * @arg @ref LL_TIM_DMABURST_BASEADDR_DIER + * @arg @ref LL_TIM_DMABURST_BASEADDR_SR + * @arg @ref LL_TIM_DMABURST_BASEADDR_EGR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCER + * @arg @ref LL_TIM_DMABURST_BASEADDR_CNT + * @arg @ref LL_TIM_DMABURST_BASEADDR_PSC + * @arg @ref LL_TIM_DMABURST_BASEADDR_ARR + * @arg @ref LL_TIM_DMABURST_BASEADDR_RCR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR3 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR4 + * @arg @ref LL_TIM_DMABURST_BASEADDR_BDTR + * @param DMABurstLength This parameter can be one of the following values: + * @arg @ref LL_TIM_DMABURST_LENGTH_1TRANSFER + * @arg @ref LL_TIM_DMABURST_LENGTH_2TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_3TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_4TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_5TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_6TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_7TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_8TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_9TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_10TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_11TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_12TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_13TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_14TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_15TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_16TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_17TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_18TRANSFERS + * @retval None + */ + __STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef *TIMx, + uint32_t DMABurstBaseAddress, + uint32_t DMABurstLength) + { + MODIFY_REG(TIMx->DCR, (TIM_DCR_DBL | TIM_DCR_DBA), + (DMABurstBaseAddress | DMABurstLength)); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_Timer_Inputs_Remapping Timer input remapping + * @{ + */ + /** + * @brief Remap TIM inputs (input channel, internal/external triggers). + * @note Macro IS_TIM_REMAP_INSTANCE(TIMx) can be used to check whether or not + * a some timer inputs can be remapped. + * @rmtoll TIM14_OR TI1_RMP LL_TIM_SetRemap + * @param TIMx Timer instance + * @param Remap This parameter can be one of the following values: + * @arg @ref LL_TIM_TIM14_TI1_RMP_GPIO + * @arg @ref LL_TIM_TIM14_TI1_RMP_RTC_CLK + * @arg @ref LL_TIM_TIM14_TI1_RMP_HSE + * @arg @ref LL_TIM_TIM14_TI1_RMP_MCO + * + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetRemap(TIM_TypeDef *TIMx, uint32_t Remap) + { + MODIFY_REG(TIMx->OR, (Remap >> TIMx_OR_RMP_SHIFT), (Remap & TIMx_OR_RMP_MASK)); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_OCREF_Clear OCREF_Clear_Management + * @{ + */ + /** + * @brief Set the OCREF clear input source + * @note The OCxREF signal of a given channel can be cleared when a high level is + * applied on the OCREF_CLR_INPUT + * @note This function can only be used in Output compare and PWM modes. + * @rmtoll SMCR OCCS LL_TIM_SetOCRefClearInputSource + * @param TIMx Timer instance + * @param OCRefClearInputSource This parameter can be one of the following values: + * @arg @ref LL_TIM_OCREF_CLR_INT_OCREF_CLR + * @arg @ref LL_TIM_OCREF_CLR_INT_ETR + * @retval None + */ + __STATIC_INLINE void LL_TIM_SetOCRefClearInputSource(TIM_TypeDef *TIMx, + uint32_t OCRefClearInputSource) + { + MODIFY_REG(TIMx->SMCR, TIM_SMCR_OCCS, OCRefClearInputSource); + } + /** + * @} + */ + + /** @defgroup TIM_LL_EF_FLAG_Management FLAG-Management + * @{ + */ + /** + * @brief Clear the update interrupt flag (UIF). + * @rmtoll SR UIF LL_TIM_ClearFlag_UPDATE + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_UPDATE(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_UIF)); + } + + /** + * @brief Indicate whether update interrupt flag (UIF) is set (update interrupt is + * pending). + * @rmtoll SR UIF LL_TIM_IsActiveFlag_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_UPDATE(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_UIF) == (TIM_SR_UIF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the Capture/Compare 1 interrupt flag (CC1F). + * @rmtoll SR CC1IF LL_TIM_ClearFlag_CC1 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_CC1(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_CC1IF)); + } + + /** + * @brief Indicate whether Capture/Compare 1 interrupt flag (CC1F) is set + * (Capture/Compare 1 interrupt is pending). + * @rmtoll SR CC1IF LL_TIM_IsActiveFlag_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_CC1IF) == (TIM_SR_CC1IF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the Capture/Compare 2 interrupt flag (CC2F). + * @rmtoll SR CC2IF LL_TIM_ClearFlag_CC2 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_CC2(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_CC2IF)); + } + + /** + * @brief Indicate whether Capture/Compare 2 interrupt flag (CC2F) is set + * (Capture/Compare 2 interrupt is pending). + * @rmtoll SR CC2IF LL_TIM_IsActiveFlag_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_CC2IF) == (TIM_SR_CC2IF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the Capture/Compare 3 interrupt flag (CC3F). + * @rmtoll SR CC3IF LL_TIM_ClearFlag_CC3 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_CC3(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_CC3IF)); + } + + /** + * @brief Indicate whether Capture/Compare 3 interrupt flag (CC3F) is set + * (Capture/Compare 3 interrupt is pending). + * @rmtoll SR CC3IF LL_TIM_IsActiveFlag_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_CC3IF) == (TIM_SR_CC3IF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the Capture/Compare 4 interrupt flag (CC4F). + * @rmtoll SR CC4IF LL_TIM_ClearFlag_CC4 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_CC4(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_CC4IF)); + } + + /** + * @brief Indicate whether Capture/Compare 4 interrupt flag (CC4F) is set + * (Capture/Compare 4 interrupt is pending). + * @rmtoll SR CC4IF LL_TIM_IsActiveFlag_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_CC4IF) == (TIM_SR_CC4IF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the commutation interrupt flag (COMIF). + * @rmtoll SR COMIF LL_TIM_ClearFlag_COM + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_COM(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_COMIF)); + } + + /** + * @brief Indicate whether commutation interrupt flag (COMIF) is set (commutation + * interrupt is pending). + * @rmtoll SR COMIF LL_TIM_IsActiveFlag_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_COM(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_COMIF) == (TIM_SR_COMIF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the trigger interrupt flag (TIF). + * @rmtoll SR TIF LL_TIM_ClearFlag_TRIG + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_TRIG(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_TIF)); + } + + /** + * @brief Indicate whether trigger interrupt flag (TIF) is set (trigger interrupt is + * pending). + * @rmtoll SR TIF LL_TIM_IsActiveFlag_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_TRIG(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_TIF) == (TIM_SR_TIF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the break interrupt flag (BIF). + * @rmtoll SR BIF LL_TIM_ClearFlag_BRK + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_BRK(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_BIF)); + } + + /** + * @brief Indicate whether break interrupt flag (BIF) is set (break interrupt is + * pending). + * @rmtoll SR BIF LL_TIM_IsActiveFlag_BRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_BRK(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_BIF) == (TIM_SR_BIF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the Capture/Compare 1 over-capture interrupt flag (CC1OF). + * @rmtoll SR CC1OF LL_TIM_ClearFlag_CC1OVR + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_CC1OVR(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_CC1OF)); + } + + /** + * @brief Indicate whether Capture/Compare 1 over-capture interrupt flag (CC1OF) is + * set (Capture/Compare 1 interrupt is pending). + * @rmtoll SR CC1OF LL_TIM_IsActiveFlag_CC1OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1OVR(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_CC1OF) == (TIM_SR_CC1OF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the Capture/Compare 2 over-capture interrupt flag (CC2OF). + * @rmtoll SR CC2OF LL_TIM_ClearFlag_CC2OVR + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_CC2OVR(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_CC2OF)); + } + + /** + * @brief Indicate whether Capture/Compare 2 over-capture interrupt flag (CC2OF) is + * set (Capture/Compare 2 over-capture interrupt is pending). + * @rmtoll SR CC2OF LL_TIM_IsActiveFlag_CC2OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2OVR(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_CC2OF) == (TIM_SR_CC2OF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the Capture/Compare 3 over-capture interrupt flag (CC3OF). + * @rmtoll SR CC3OF LL_TIM_ClearFlag_CC3OVR + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_CC3OVR(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_CC3OF)); + } + + /** + * @brief Indicate whether Capture/Compare 3 over-capture interrupt flag (CC3OF) is + * set (Capture/Compare 3 over-capture interrupt is pending). + * @rmtoll SR CC3OF LL_TIM_IsActiveFlag_CC3OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3OVR(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_CC3OF) == (TIM_SR_CC3OF)) ? 1UL : 0UL); + } + + /** + * @brief Clear the Capture/Compare 4 over-capture interrupt flag (CC4OF). + * @rmtoll SR CC4OF LL_TIM_ClearFlag_CC4OVR + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_ClearFlag_CC4OVR(TIM_TypeDef *TIMx) + { + WRITE_REG(TIMx->SR, ~(TIM_SR_CC4OF)); + } + + /** + * @brief Indicate whether Capture/Compare 4 over-capture interrupt flag (CC4OF) is + * set (Capture/Compare 4 over-capture interrupt is pending). + * @rmtoll SR CC4OF LL_TIM_IsActiveFlag_CC4OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4OVR(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->SR, TIM_SR_CC4OF) == (TIM_SR_CC4OF)) ? 1UL : 0UL); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_IT_Management IT-Management + * @{ + */ + /** + * @brief Enable update interrupt (UIE). + * @rmtoll DIER UIE LL_TIM_EnableIT_UPDATE + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableIT_UPDATE(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_UIE); + } + + /** + * @brief Disable update interrupt (UIE). + * @rmtoll DIER UIE LL_TIM_DisableIT_UPDATE + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableIT_UPDATE(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_UIE); + } + + /** + * @brief Indicates whether the update interrupt (UIE) is enabled. + * @rmtoll DIER UIE LL_TIM_IsEnabledIT_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_UPDATE(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_UIE) == (TIM_DIER_UIE)) ? 1UL : 0UL); + } + + /** + * @brief Enable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_TIM_EnableIT_CC1 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableIT_CC1(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_CC1IE); + } + + /** + * @brief Disable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_TIM_DisableIT_CC1 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableIT_CC1(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1IE); + } + + /** + * @brief Indicates whether the capture/compare 1 interrupt (CC1IE) is enabled. + * @rmtoll DIER CC1IE LL_TIM_IsEnabledIT_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC1(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC1IE) == (TIM_DIER_CC1IE)) ? 1UL : 0UL); + } + + /** + * @brief Enable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_TIM_EnableIT_CC2 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableIT_CC2(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_CC2IE); + } + + /** + * @brief Disable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_TIM_DisableIT_CC2 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableIT_CC2(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2IE); + } + + /** + * @brief Indicates whether the capture/compare 2 interrupt (CC2IE) is enabled. + * @rmtoll DIER CC2IE LL_TIM_IsEnabledIT_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC2(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC2IE) == (TIM_DIER_CC2IE)) ? 1UL : 0UL); + } + + /** + * @brief Enable capture/compare 3 interrupt (CC3IE). + * @rmtoll DIER CC3IE LL_TIM_EnableIT_CC3 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableIT_CC3(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_CC3IE); + } + + /** + * @brief Disable capture/compare 3 interrupt (CC3IE). + * @rmtoll DIER CC3IE LL_TIM_DisableIT_CC3 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableIT_CC3(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3IE); + } + + /** + * @brief Indicates whether the capture/compare 3 interrupt (CC3IE) is enabled. + * @rmtoll DIER CC3IE LL_TIM_IsEnabledIT_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC3(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC3IE) == (TIM_DIER_CC3IE)) ? 1UL : 0UL); + } + + /** + * @brief Enable capture/compare 4 interrupt (CC4IE). + * @rmtoll DIER CC4IE LL_TIM_EnableIT_CC4 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableIT_CC4(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_CC4IE); + } + + /** + * @brief Disable capture/compare 4 interrupt (CC4IE). + * @rmtoll DIER CC4IE LL_TIM_DisableIT_CC4 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableIT_CC4(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4IE); + } + + /** + * @brief Indicates whether the capture/compare 4 interrupt (CC4IE) is enabled. + * @rmtoll DIER CC4IE LL_TIM_IsEnabledIT_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC4(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4IE) == (TIM_DIER_CC4IE)) ? 1UL : 0UL); + } + + /** + * @brief Enable commutation interrupt (COMIE). + * @rmtoll DIER COMIE LL_TIM_EnableIT_COM + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableIT_COM(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_COMIE); + } + + /** + * @brief Disable commutation interrupt (COMIE). + * @rmtoll DIER COMIE LL_TIM_DisableIT_COM + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableIT_COM(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_COMIE); + } + + /** + * @brief Indicates whether the commutation interrupt (COMIE) is enabled. + * @rmtoll DIER COMIE LL_TIM_IsEnabledIT_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_COM(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_COMIE) == (TIM_DIER_COMIE)) ? 1UL : 0UL); + } + + /** + * @brief Enable trigger interrupt (TIE). + * @rmtoll DIER TIE LL_TIM_EnableIT_TRIG + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableIT_TRIG(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_TIE); + } + + /** + * @brief Disable trigger interrupt (TIE). + * @rmtoll DIER TIE LL_TIM_DisableIT_TRIG + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableIT_TRIG(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_TIE); + } + + /** + * @brief Indicates whether the trigger interrupt (TIE) is enabled. + * @rmtoll DIER TIE LL_TIM_IsEnabledIT_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_TRIG(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_TIE) == (TIM_DIER_TIE)) ? 1UL : 0UL); + } + + /** + * @brief Enable break interrupt (BIE). + * @rmtoll DIER BIE LL_TIM_EnableIT_BRK + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableIT_BRK(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_BIE); + } + + /** + * @brief Disable break interrupt (BIE). + * @rmtoll DIER BIE LL_TIM_DisableIT_BRK + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableIT_BRK(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_BIE); + } + + /** + * @brief Indicates whether the break interrupt (BIE) is enabled. + * @rmtoll DIER BIE LL_TIM_IsEnabledIT_BRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_BRK(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_BIE) == (TIM_DIER_BIE)) ? 1UL : 0UL); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_DMA_Management DMA Management + * @{ + */ + /** + * @brief Enable update DMA request (UDE). + * @rmtoll DIER UDE LL_TIM_EnableDMAReq_UPDATE + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableDMAReq_UPDATE(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_UDE); + } + + /** + * @brief Disable update DMA request (UDE). + * @rmtoll DIER UDE LL_TIM_DisableDMAReq_UPDATE + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableDMAReq_UPDATE(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_UDE); + } + + /** + * @brief Indicates whether the update DMA request (UDE) is enabled. + * @rmtoll DIER UDE LL_TIM_IsEnabledDMAReq_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_UPDATE(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_UDE) == (TIM_DIER_UDE)) ? 1UL : 0UL); + } + + /** + * @brief Enable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_TIM_EnableDMAReq_CC1 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableDMAReq_CC1(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_CC1DE); + } + + /** + * @brief Disable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_TIM_DisableDMAReq_CC1 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableDMAReq_CC1(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1DE); + } + + /** + * @brief Indicates whether the capture/compare 1 DMA request (CC1DE) is enabled. + * @rmtoll DIER CC1DE LL_TIM_IsEnabledDMAReq_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC1(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC1DE) == (TIM_DIER_CC1DE)) ? 1UL : 0UL); + } + + /** + * @brief Enable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_TIM_EnableDMAReq_CC2 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableDMAReq_CC2(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_CC2DE); + } + + /** + * @brief Disable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_TIM_DisableDMAReq_CC2 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableDMAReq_CC2(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2DE); + } + + /** + * @brief Indicates whether the capture/compare 2 DMA request (CC2DE) is enabled. + * @rmtoll DIER CC2DE LL_TIM_IsEnabledDMAReq_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC2(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC2DE) == (TIM_DIER_CC2DE)) ? 1UL : 0UL); + } + + /** + * @brief Enable capture/compare 3 DMA request (CC3DE). + * @rmtoll DIER CC3DE LL_TIM_EnableDMAReq_CC3 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableDMAReq_CC3(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_CC3DE); + } + + /** + * @brief Disable capture/compare 3 DMA request (CC3DE). + * @rmtoll DIER CC3DE LL_TIM_DisableDMAReq_CC3 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableDMAReq_CC3(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3DE); + } + + /** + * @brief Indicates whether the capture/compare 3 DMA request (CC3DE) is enabled. + * @rmtoll DIER CC3DE LL_TIM_IsEnabledDMAReq_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC3(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC3DE) == (TIM_DIER_CC3DE)) ? 1UL : 0UL); + } + + /** + * @brief Enable capture/compare 4 DMA request (CC4DE). + * @rmtoll DIER CC4DE LL_TIM_EnableDMAReq_CC4 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableDMAReq_CC4(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_CC4DE); + } + + /** + * @brief Disable capture/compare 4 DMA request (CC4DE). + * @rmtoll DIER CC4DE LL_TIM_DisableDMAReq_CC4 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableDMAReq_CC4(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4DE); + } + + /** + * @brief Indicates whether the capture/compare 4 DMA request (CC4DE) is enabled. + * @rmtoll DIER CC4DE LL_TIM_IsEnabledDMAReq_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC4(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4DE) == (TIM_DIER_CC4DE)) ? 1UL : 0UL); + } + + /** + * @brief Enable commutation DMA request (COMDE). + * @rmtoll DIER COMDE LL_TIM_EnableDMAReq_COM + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableDMAReq_COM(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_COMDE); + } + + /** + * @brief Disable commutation DMA request (COMDE). + * @rmtoll DIER COMDE LL_TIM_DisableDMAReq_COM + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableDMAReq_COM(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_COMDE); + } + + /** + * @brief Indicates whether the commutation DMA request (COMDE) is enabled. + * @rmtoll DIER COMDE LL_TIM_IsEnabledDMAReq_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_COM(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_COMDE) == (TIM_DIER_COMDE)) ? 1UL : 0UL); + } + + /** + * @brief Enable trigger interrupt (TDE). + * @rmtoll DIER TDE LL_TIM_EnableDMAReq_TRIG + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_EnableDMAReq_TRIG(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->DIER, TIM_DIER_TDE); + } + + /** + * @brief Disable trigger interrupt (TDE). + * @rmtoll DIER TDE LL_TIM_DisableDMAReq_TRIG + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_DisableDMAReq_TRIG(TIM_TypeDef *TIMx) + { + CLEAR_BIT(TIMx->DIER, TIM_DIER_TDE); + } + + /** + * @brief Indicates whether the trigger interrupt (TDE) is enabled. + * @rmtoll DIER TDE LL_TIM_IsEnabledDMAReq_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_TRIG(const TIM_TypeDef *TIMx) + { + return ((READ_BIT(TIMx->DIER, TIM_DIER_TDE) == (TIM_DIER_TDE)) ? 1UL : 0UL); + } + + /** + * @} + */ + + /** @defgroup TIM_LL_EF_EVENT_Management EVENT-Management + * @{ + */ + /** + * @brief Generate an update event. + * @rmtoll EGR UG LL_TIM_GenerateEvent_UPDATE + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_GenerateEvent_UPDATE(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->EGR, TIM_EGR_UG); + } + + /** + * @brief Generate Capture/Compare 1 event. + * @rmtoll EGR CC1G LL_TIM_GenerateEvent_CC1 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_GenerateEvent_CC1(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->EGR, TIM_EGR_CC1G); + } + + /** + * @brief Generate Capture/Compare 2 event. + * @rmtoll EGR CC2G LL_TIM_GenerateEvent_CC2 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_GenerateEvent_CC2(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->EGR, TIM_EGR_CC2G); + } + + /** + * @brief Generate Capture/Compare 3 event. + * @rmtoll EGR CC3G LL_TIM_GenerateEvent_CC3 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_GenerateEvent_CC3(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->EGR, TIM_EGR_CC3G); + } + + /** + * @brief Generate Capture/Compare 4 event. + * @rmtoll EGR CC4G LL_TIM_GenerateEvent_CC4 + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_GenerateEvent_CC4(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->EGR, TIM_EGR_CC4G); + } + + /** + * @brief Generate commutation event. + * @rmtoll EGR COMG LL_TIM_GenerateEvent_COM + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_GenerateEvent_COM(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->EGR, TIM_EGR_COMG); + } + + /** + * @brief Generate trigger event. + * @rmtoll EGR TG LL_TIM_GenerateEvent_TRIG + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_GenerateEvent_TRIG(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->EGR, TIM_EGR_TG); + } + + /** + * @brief Generate break event. + * @rmtoll EGR BG LL_TIM_GenerateEvent_BRK + * @param TIMx Timer instance + * @retval None + */ + __STATIC_INLINE void LL_TIM_GenerateEvent_BRK(TIM_TypeDef *TIMx) + { + SET_BIT(TIMx->EGR, TIM_EGR_BG); + } + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup TIM_LL_EF_Init Initialisation and deinitialisation functions + * @{ + */ + + ErrorStatus LL_TIM_DeInit(const TIM_TypeDef *TIMx); + void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct); + ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, const LL_TIM_InitTypeDef *TIM_InitStruct); + void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); + ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, + const LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); + void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); + ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, + const LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct); + void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); + ErrorStatus LL_TIM_ENCODER_Init( + TIM_TypeDef *TIMx, const LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); + void LL_TIM_HALLSENSOR_StructInit( + LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct); + ErrorStatus LL_TIM_HALLSENSOR_Init( + TIM_TypeDef *TIMx, const LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct); + void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct); + ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, + const LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* TIM1 || TIM2 || TIM3 || TIM14 || TIM15 || TIM16 || TIM17 || TIM6 || TIM7 */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_TIM_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_usart.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_usart.h new file mode 100644 index 0000000000..03e5ba1fc5 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_usart.h @@ -0,0 +1,4041 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_usart.h + * @author MCD Application Team + * @brief Header file of USART LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_LL_USART_H +#define STM32F0xx_LL_USART_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + + /** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +#if defined(USART1) || defined(USART2) || defined(USART3) || defined(UART4) || \ + defined(UART5) || defined(USART6) || defined(USART7) || defined(USART8) + +/** @defgroup USART_LL USART + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup USART_LL_Private_Constants USART Private Constants + * @{ + */ +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup USART_LL_Private_Macros USART Private Macros + * @{ + */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup USART_LL_ES_INIT USART Exported Init structures + * @{ + */ + + /** + * @brief LL USART Init Structure definition + */ + typedef struct + { + uint32_t BaudRate; /*!< This field defines expected Usart communication baud rate. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetBaudRate().*/ + + uint32_t DataWidth; /*!< Specifies the number of data bits transmitted or received + in a frame. This parameter can be a value of @ref + USART_LL_EC_DATAWIDTH. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetDataWidth().*/ + + uint32_t + StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref USART_LL_EC_STOPBITS. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetStopBitsLength().*/ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref USART_LL_EC_PARITY. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetParity().*/ + + uint32_t + TransferDirection; /*!< Specifies whether the Receive and/or Transmit mode is + enabled or disabled. This parameter can be a value of + @ref USART_LL_EC_DIRECTION. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetTransferDirection().*/ + + uint32_t HardwareFlowControl; /*!< Specifies whether the hardware flow control + mode is enabled or disabled. This parameter can + be a value of @ref USART_LL_EC_HWCONTROL. + + This feature can be modified afterwards using + unitary function @ref LL_USART_SetHWFlowCtrl().*/ + + uint32_t OverSampling; /*!< Specifies whether USART oversampling mode is 16 or 8. + This parameter can be a value of @ref + USART_LL_EC_OVERSAMPLING. + + This feature can be modified afterwards using unitary + function @ref LL_USART_SetOverSampling().*/ + + } LL_USART_InitTypeDef; + + /** + * @brief LL USART Clock Init Structure definition + */ + typedef struct + { + uint32_t + ClockOutput; /*!< Specifies whether the USART clock is enabled or disabled. + This parameter can be a value of @ref USART_LL_EC_CLOCK. + + USART HW configuration can be modified afterwards using + unitary functions + @ref LL_USART_EnableSCLKOutput() or @ref + LL_USART_DisableSCLKOutput(). For more details, refer to + description of this function. */ + + uint32_t ClockPolarity; /*!< Specifies the steady state of the serial clock. + This parameter can be a value of @ref + USART_LL_EC_POLARITY. + + USART HW configuration can be modified afterwards + using unitary functions @ref + LL_USART_SetClockPolarity(). For more details, refer to + description of this function. */ + + uint32_t + ClockPhase; /*!< Specifies the clock transition on which the bit capture is + made. This parameter can be a value of @ref USART_LL_EC_PHASE. + + USART HW configuration can be modified afterwards using + unitary functions @ref LL_USART_SetClockPhase(). For more + details, refer to description of this function. */ + + uint32_t + LastBitClockPulse; /*!< Specifies whether the clock pulse corresponding to the + last transmitted data bit (MSB) has to be output on the + SCLK pin in synchronous mode. This parameter can be a + value of @ref USART_LL_EC_LASTCLKPULSE. + + USART HW configuration can be modified afterwards + using unitary functions @ref + LL_USART_SetLastClkPulseOutput(). For more details, + refer to description of this function. */ + + } LL_USART_ClockInitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup USART_LL_Exported_Constants USART Exported Constants + * @{ + */ + +/** @defgroup USART_LL_EC_CLEAR_FLAG Clear Flags Defines + * @brief Flags defines which can be used with LL_USART_WriteReg function + * @{ + */ +#define LL_USART_ICR_PECF USART_ICR_PECF /*!< Parity error clear flag */ +#define LL_USART_ICR_FECF USART_ICR_FECF /*!< Framing error clear flag */ +#define LL_USART_ICR_NCF USART_ICR_NCF /*!< Noise error detected clear flag */ +#define LL_USART_ICR_ORECF USART_ICR_ORECF /*!< Overrun error clear flag */ +#define LL_USART_ICR_IDLECF USART_ICR_IDLECF /*!< Idle line detected clear flag */ +#define LL_USART_ICR_TCCF USART_ICR_TCCF /*!< Transmission complete clear flag */ +#if defined USART_LIN_SUPPORT +#define LL_USART_ICR_LBDCF USART_ICR_LBDCF /*!< LIN break detection clear flag */ +#endif /* USART_LIN_SUPPORT */ +#define LL_USART_ICR_CTSCF USART_ICR_CTSCF /*!< CTS clear flag */ +#define LL_USART_ICR_RTOCF USART_ICR_RTOCF /*!< Receiver timeout clear flag */ +#if defined USART_SMARTCARD_SUPPORT +#define LL_USART_ICR_EOBCF USART_ICR_EOBCF /*!< End of block clear flag */ +#endif /* USART_SMARTCARD_SUPPORT */ +#define LL_USART_ICR_CMCF USART_ICR_CMCF /*!< Character match clear flag */ +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUFIE) +#define LL_USART_ICR_WUCF USART_ICR_WUCF /*!< Wakeup from Stop mode clear flag */ +#endif /* USART_CR3_WUFIE */ +#endif /* USART_CR1_UESM */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_USART_ReadReg function + * @{ + */ +#define LL_USART_ISR_PE USART_ISR_PE /*!< Parity error flag */ +#define LL_USART_ISR_FE USART_ISR_FE /*!< Framing error flag */ +#define LL_USART_ISR_NE USART_ISR_NE /*!< Noise detected flag */ +#define LL_USART_ISR_ORE USART_ISR_ORE /*!< Overrun error flag */ +#define LL_USART_ISR_IDLE USART_ISR_IDLE /*!< Idle line detected flag */ +#define LL_USART_ISR_RXNE USART_ISR_RXNE /*!< Read data register not empty flag */ +#define LL_USART_ISR_TC USART_ISR_TC /*!< Transmission complete flag */ +#define LL_USART_ISR_TXE USART_ISR_TXE /*!< Transmit data register empty flag */ +#if defined USART_LIN_SUPPORT +#define LL_USART_ISR_LBDF USART_ISR_LBDF /*!< LIN break detection flag */ +#endif /* USART_LIN_SUPPORT */ +#define LL_USART_ISR_CTSIF USART_ISR_CTSIF /*!< CTS interrupt flag */ +#define LL_USART_ISR_CTS USART_ISR_CTS /*!< CTS flag */ +#define LL_USART_ISR_RTOF USART_ISR_RTOF /*!< Receiver timeout flag */ +#if defined USART_SMARTCARD_SUPPORT +#define LL_USART_ISR_EOBF USART_ISR_EOBF /*!< End of block flag */ +#endif /* USART_SMARTCARD_SUPPORT */ +#define LL_USART_ISR_ABRE USART_ISR_ABRE /*!< Auto baud rate error flag */ +#define LL_USART_ISR_ABRF USART_ISR_ABRF /*!< Auto baud rate flag */ +#define LL_USART_ISR_BUSY USART_ISR_BUSY /*!< Busy flag */ +#define LL_USART_ISR_CMF USART_ISR_CMF /*!< Character match flag */ +#define LL_USART_ISR_SBKF USART_ISR_SBKF /*!< Send break flag */ +#define LL_USART_ISR_RWU USART_ISR_RWU /*!< Receiver wakeup from Mute mode flag */ +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUFIE) +#define LL_USART_ISR_WUF USART_ISR_WUF /*!< Wakeup from Stop mode flag */ +#endif /* USART_CR3_WUFIE */ +#endif /* USART_CR1_UESM */ +#define LL_USART_ISR_TEACK USART_ISR_TEACK /*!< Transmit enable acknowledge flag */ +#define LL_USART_ISR_REACK USART_ISR_REACK /*!< Receive enable acknowledge flag */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_USART_ReadReg and LL_USART_WriteReg + * functions + * @{ + */ +#define LL_USART_CR1_IDLEIE USART_CR1_IDLEIE /*!< IDLE interrupt enable */ +#define LL_USART_CR1_RXNEIE \ + USART_CR1_RXNEIE /*!< Read data register not empty interrupt enable */ +#define LL_USART_CR1_TCIE USART_CR1_TCIE /*!< Transmission complete interrupt enable */ +#define LL_USART_CR1_TXEIE \ + USART_CR1_TXEIE /*!< Transmit data register empty interrupt enable */ +#define LL_USART_CR1_PEIE USART_CR1_PEIE /*!< Parity error */ +#define LL_USART_CR1_CMIE USART_CR1_CMIE /*!< Character match interrupt enable */ +#define LL_USART_CR1_RTOIE USART_CR1_RTOIE /*!< Receiver timeout interrupt enable */ +#if defined(USART_SMARTCARD_SUPPORT) +#define LL_USART_CR1_EOBIE USART_CR1_EOBIE /*!< End of Block interrupt enable */ +#endif /* USART_SMARTCARD_SUPPORT */ +#if defined(USART_LIN_SUPPORT) +#define LL_USART_CR2_LBDIE USART_CR2_LBDIE /*!< LIN break detection interrupt enable */ +#endif /* USART_LIN_SUPPORT */ +#define LL_USART_CR3_EIE USART_CR3_EIE /*!< Error interrupt enable */ +#define LL_USART_CR3_CTSIE USART_CR3_CTSIE /*!< CTS interrupt enable */ +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUFIE) +#define LL_USART_CR3_WUFIE \ + USART_CR3_WUFIE /*!< Wakeup from Stop mode interrupt enable \ + */ +#endif /* USART_CR3_WUFIE */ +#endif /* USART_CR1_UESM */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_DIRECTION Communication Direction + * @{ + */ +#define LL_USART_DIRECTION_NONE \ + 0x00000000U /*!< Transmitter and Receiver are disabled \ + */ +#define LL_USART_DIRECTION_RX \ + USART_CR1_RE /*!< Transmitter is disabled and Receiver is enabled */ +#define LL_USART_DIRECTION_TX \ + USART_CR1_TE /*!< Transmitter is enabled and Receiver is disabled */ +#define LL_USART_DIRECTION_TX_RX \ + (USART_CR1_TE | USART_CR1_RE) /*!< Transmitter and Receiver are enabled */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_PARITY Parity Control + * @{ + */ +#define LL_USART_PARITY_NONE 0x00000000U /*!< Parity control disabled */ +#define LL_USART_PARITY_EVEN \ + USART_CR1_PCE /*!< Parity control enabled and Even Parity is selected */ +#define LL_USART_PARITY_ODD \ + (USART_CR1_PCE | \ + USART_CR1_PS) /*!< Parity control enabled and Odd Parity is selected */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_WAKEUP Wakeup + * @{ + */ +#define LL_USART_WAKEUP_IDLELINE \ + 0x00000000U /*!< USART wake up from Mute mode on Idle Line */ +#define LL_USART_WAKEUP_ADDRESSMARK \ + USART_CR1_WAKE /*!< USART wake up from Mute mode on Address Mark */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_DATAWIDTH Datawidth + * @{ + */ +#if defined(USART_7BITS_SUPPORT) +#define LL_USART_DATAWIDTH_7B \ + USART_CR1_M1 /*!< 7 bits word length : Start bit, 7 data bits, n stop bits */ +#define LL_USART_DATAWIDTH_8B \ + 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */ +#define LL_USART_DATAWIDTH_9B \ + USART_CR1_M0 /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */ +#else +#define LL_USART_DATAWIDTH_8B \ + 0x00000000U /*!< 8 bits word length : Start bit, 8 data bits, n stop bits */ +#define LL_USART_DATAWIDTH_9B \ + USART_CR1_M /*!< 9 bits word length : Start bit, 9 data bits, n stop bits */ +#endif /* USART_7BITS_SUPPORT */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_OVERSAMPLING Oversampling + * @{ + */ +#define LL_USART_OVERSAMPLING_16 0x00000000U /*!< Oversampling by 16 */ +#define LL_USART_OVERSAMPLING_8 USART_CR1_OVER8 /*!< Oversampling by 8 */ + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup USART_LL_EC_CLOCK Clock Signal + * @{ + */ + +#define LL_USART_CLOCK_DISABLE 0x00000000U /*!< Clock signal not provided */ +#define LL_USART_CLOCK_ENABLE USART_CR2_CLKEN /*!< Clock signal provided */ +/** + * @} + */ +#endif /*USE_FULL_LL_DRIVER*/ + +/** @defgroup USART_LL_EC_LASTCLKPULSE Last Clock Pulse + * @{ + */ +#define LL_USART_LASTCLKPULSE_NO_OUTPUT \ + 0x00000000U /*!< The clock pulse of the last data bit is not output to the SCLK pin \ + */ +#define LL_USART_LASTCLKPULSE_OUTPUT \ + USART_CR2_LBCL /*!< The clock pulse of the last data bit is output to the SCLK pin \ + */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_PHASE Clock Phase + * @{ + */ +#define LL_USART_PHASE_1EDGE \ + 0x00000000U /*!< The first clock transition is the first data capture edge */ +#define LL_USART_PHASE_2EDGE \ + USART_CR2_CPHA /*!< The second clock transition is the first data capture edge */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_POLARITY Clock Polarity + * @{ + */ +#define LL_USART_POLARITY_LOW \ + 0x00000000U /*!< Steady low value on SCLK pin outside transmission window*/ +#define LL_USART_POLARITY_HIGH \ + USART_CR2_CPOL /*!< Steady high value on SCLK pin outside transmission window */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_STOPBITS Stop Bits + * @{ + */ +#if defined(USART_SMARTCARD_SUPPORT) +#define LL_USART_STOPBITS_0_5 USART_CR2_STOP_0 /*!< 0.5 stop bit */ +#endif /* USART_SMARTCARD_SUPPORT */ +#define LL_USART_STOPBITS_1 0x00000000U /*!< 1 stop bit */ +#if defined(USART_SMARTCARD_SUPPORT) +#define LL_USART_STOPBITS_1_5 \ + (USART_CR2_STOP_0 | USART_CR2_STOP_1) /*!< 1.5 stop bits \ + */ +#endif /* USART_SMARTCARD_SUPPORT */ +#define LL_USART_STOPBITS_2 USART_CR2_STOP_1 /*!< 2 stop bits */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_TXRX TX RX Pins Swap + * @{ + */ +#define LL_USART_TXRX_STANDARD \ + 0x00000000U /*!< TX/RX pins are used as defined in standard pinout */ +#define LL_USART_TXRX_SWAPPED \ + (USART_CR2_SWAP) /*!< TX and RX pins functions are swapped. */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_RXPIN_LEVEL RX Pin Active Level Inversion + * @{ + */ +#define LL_USART_RXPIN_LEVEL_STANDARD \ + 0x00000000U /*!< RX pin signal works using the standard logic levels */ +#define LL_USART_RXPIN_LEVEL_INVERTED \ + (USART_CR2_RXINV) /*!< RX pin signal values are inverted. */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_TXPIN_LEVEL TX Pin Active Level Inversion + * @{ + */ +#define LL_USART_TXPIN_LEVEL_STANDARD \ + 0x00000000U /*!< TX pin signal works using the standard logic levels */ +#define LL_USART_TXPIN_LEVEL_INVERTED \ + (USART_CR2_TXINV) /*!< TX pin signal values are inverted. */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_BINARY_LOGIC Binary Data Inversion + * @{ + */ +#define LL_USART_BINARY_LOGIC_POSITIVE \ + 0x00000000U /*!< Logical data from the data register are send/received in \ + positive/direct logic. (1=H, 0=L) */ +#define LL_USART_BINARY_LOGIC_NEGATIVE \ + USART_CR2_DATAINV /*!< Logical data from the data register are send/received in \ + negative/inverse logic. (1=L, 0=H). The parity bit is also \ + inverted. */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_BITORDER Bit Order + * @{ + */ +#define LL_USART_BITORDER_LSBFIRST \ + 0x00000000U /*!< data is transmitted/received with data bit 0 first, following the \ + start bit */ +#define LL_USART_BITORDER_MSBFIRST \ + USART_CR2_MSBFIRST /*!< data is transmitted/received with the MSB first, following \ + the start bit */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_AUTOBAUD_DETECT_ON Autobaud Detection + * @{ + */ +#define LL_USART_AUTOBAUD_DETECT_ON_STARTBIT \ + 0x00000000U /*!< Measurement of the start bit is used to detect the baud rate */ +#define LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE \ + USART_CR2_ABRMODE_0 /*!< Falling edge to falling edge measurement. Received frame \ + must start with a single bit = 1 -> Frame = Start10xxxxxx */ +#if defined(USART_FABR_SUPPORT) +#define LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME \ + USART_CR2_ABRMODE_1 /*!< 0x7F frame detection */ +#define LL_USART_AUTOBAUD_DETECT_ON_55_FRAME \ + (USART_CR2_ABRMODE_1 | USART_CR2_ABRMODE_0) /*!< 0x55 frame detection */ +#endif /* USART_FABR_SUPPORT */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_ADDRESS_DETECT Address Length Detection + * @{ + */ +#define LL_USART_ADDRESS_DETECT_4B \ + 0x00000000U /*!< 4-bit address detection method selected */ +#define LL_USART_ADDRESS_DETECT_7B \ + USART_CR2_ADDM7 /*!< 7-bit address detection (in 8-bit data mode) method selected */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_HWCONTROL Hardware Control + * @{ + */ +#define LL_USART_HWCONTROL_NONE \ + 0x00000000U /*!< CTS and RTS hardware flow control disabled */ +#define LL_USART_HWCONTROL_RTS \ + USART_CR3_RTSE /*!< RTS output enabled, data is only requested when there is space \ + in the receive buffer */ +#define LL_USART_HWCONTROL_CTS \ + USART_CR3_CTSE /*!< CTS mode enabled, data is only transmitted when the nCTS input \ + is asserted (tied to 0) */ +#define LL_USART_HWCONTROL_RTS_CTS \ + (USART_CR3_RTSE | USART_CR3_CTSE) /*!< CTS and RTS hardware flow control enabled */ + /** + * @} + */ + +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUS) +/** @defgroup USART_LL_EC_WAKEUP_ON Wakeup Activation + * @{ + */ +#define LL_USART_WAKEUP_ON_ADDRESS 0x00000000U /*!< Wake up active on address match */ +#define LL_USART_WAKEUP_ON_STARTBIT \ + USART_CR3_WUS_1 /*!< Wake up active on Start bit detection */ +#define LL_USART_WAKEUP_ON_RXNE \ + (USART_CR3_WUS_0 | USART_CR3_WUS_1) /*!< Wake up active on RXNE */ + /** + * @} + */ + +#endif /* USART_CR3_WUS */ +#endif /* USART_CR1_UESM */ +#if defined(USART_IRDA_SUPPORT) +/** @defgroup USART_LL_EC_IRDA_POWER IrDA Power + * @{ + */ +#define LL_USART_IRDA_POWER_NORMAL 0x00000000U /*!< IrDA normal power mode */ +#define LL_USART_IRDA_POWER_LOW USART_CR3_IRLP /*!< IrDA low power mode */ +/** + * @} + */ +#endif /* USART_IRDA_SUPPORT */ + +#if defined(USART_LIN_SUPPORT) +/** @defgroup USART_LL_EC_LINBREAK_DETECT LIN Break Detection Length + * @{ + */ +#define LL_USART_LINBREAK_DETECT_10B \ + 0x00000000U /*!< 10-bit break detection method selected */ +#define LL_USART_LINBREAK_DETECT_11B \ + USART_CR2_LBDL /*!< 11-bit break detection method selected */ +/** + * @} + */ +#endif /* USART_LIN_SUPPORT */ + +/** @defgroup USART_LL_EC_DE_POLARITY Driver Enable Polarity + * @{ + */ +#define LL_USART_DE_POLARITY_HIGH 0x00000000U /*!< DE signal is active high */ +#define LL_USART_DE_POLARITY_LOW USART_CR3_DEP /*!< DE signal is active low */ +/** + * @} + */ + +/** @defgroup USART_LL_EC_DMA_REG_DATA DMA Register Data + * @{ + */ +#define LL_USART_DMA_REG_DATA_TRANSMIT \ + 0x00000000U /*!< Get address of data register used for transmission */ +#define LL_USART_DMA_REG_DATA_RECEIVE \ + 0x00000001U /*!< Get address of data register used for reception */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup USART_LL_Exported_Macros USART Exported Macros + * @{ + */ + +/** @defgroup USART_LL_EM_WRITE_READ Common Write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in USART register + * @param __INSTANCE__ USART Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_USART_WriteReg(__INSTANCE__, __REG__, __VALUE__) \ + WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in USART register + * @param __INSTANCE__ USART Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_USART_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup USART_LL_EM_Exported_Macros_Helper Exported_Macros_Helper + * @{ + */ + +/** + * @brief Compute USARTDIV value according to Peripheral Clock and + * expected Baud Rate in 8 bits sampling mode (32 bits value of USARTDIV is + * returned) + * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance + * @param __BAUDRATE__ Baud rate value to achieve + * @retval USARTDIV value to be used for BRR register filling in OverSampling_8 case + */ +#define __LL_USART_DIV_SAMPLING8(__PERIPHCLK__, __BAUDRATE__) \ + ((((__PERIPHCLK__)*2U) + ((__BAUDRATE__) / 2U)) / (__BAUDRATE__)) + +/** + * @brief Compute USARTDIV value according to Peripheral Clock and + * expected Baud Rate in 16 bits sampling mode (32 bits value of USARTDIV is + * returned) + * @param __PERIPHCLK__ Peripheral Clock frequency used for USART instance + * @param __BAUDRATE__ Baud rate value to achieve + * @retval USARTDIV value to be used for BRR register filling in OverSampling_16 case + */ +#define __LL_USART_DIV_SAMPLING16(__PERIPHCLK__, __BAUDRATE__) \ + (((__PERIPHCLK__) + ((__BAUDRATE__) / 2U)) / (__BAUDRATE__)) + + /** + * @} + */ + + /** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ + + /** @defgroup USART_LL_Exported_Functions USART Exported Functions + * @{ + */ + + /** @defgroup USART_LL_EF_Configuration Configuration functions + * @{ + */ + + /** + * @brief USART Enable + * @rmtoll CR1 UE LL_USART_Enable + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR1, USART_CR1_UE); + } + + /** + * @brief USART Disable (all USART prescalers and outputs are disabled) + * @note When USART is disabled, USART prescalers and outputs are stopped + * immediately, and current operations are discarded. The configuration of the USART + * is kept, but all the status flags, in the USARTx_ISR are set to their default + * values. + * @rmtoll CR1 UE LL_USART_Disable + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_Disable(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR1, USART_CR1_UE); + } + + /** + * @brief Indicate if USART is enabled + * @rmtoll CR1 UE LL_USART_IsEnabled + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabled(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_UE) == (USART_CR1_UE)) ? 1UL : 0UL); + } + +#if defined(USART_CR1_UESM) + /** + * @brief USART enabled in STOP Mode. + * @note When this function is enabled, USART is able to wake up the MCU from Stop + * mode, provided that USART clock selection is HSI or LSE in RCC. + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR1 UESM LL_USART_EnableInStopMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableInStopMode(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_UESM); + } + + /** + * @brief USART disabled in STOP Mode. + * @note When this function is disabled, USART is not able to wake up the MCU from + * Stop mode + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR1 UESM LL_USART_DisableInStopMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableInStopMode(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_UESM); + } + + /** + * @brief Indicate if USART is enabled in STOP Mode (able to wake up MCU from Stop + * mode or not) + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR1 UESM LL_USART_IsEnabledInStopMode + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledInStopMode(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_UESM) == (USART_CR1_UESM)) ? 1UL : 0UL); + } + +#endif /* USART_CR1_UESM*/ + /** + * @brief Receiver Enable (Receiver is enabled and begins searching for a start bit) + * @rmtoll CR1 RE LL_USART_EnableDirectionRx + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableDirectionRx(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RE); + } + + /** + * @brief Receiver Disable + * @rmtoll CR1 RE LL_USART_DisableDirectionRx + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableDirectionRx(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RE); + } + + /** + * @brief Transmitter Enable + * @rmtoll CR1 TE LL_USART_EnableDirectionTx + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableDirectionTx(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TE); + } + + /** + * @brief Transmitter Disable + * @rmtoll CR1 TE LL_USART_DisableDirectionTx + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableDirectionTx(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TE); + } + + /** + * @brief Configure simultaneously enabled/disabled states + * of Transmitter and Receiver + * @rmtoll CR1 RE LL_USART_SetTransferDirection\n + * CR1 TE LL_USART_SetTransferDirection + * @param USARTx USART Instance + * @param TransferDirection This parameter can be one of the following values: + * @arg @ref LL_USART_DIRECTION_NONE + * @arg @ref LL_USART_DIRECTION_RX + * @arg @ref LL_USART_DIRECTION_TX + * @arg @ref LL_USART_DIRECTION_TX_RX + * @retval None + */ + __STATIC_INLINE void LL_USART_SetTransferDirection(USART_TypeDef *USARTx, + uint32_t TransferDirection) + { + ATOMIC_MODIFY_REG(USARTx->CR1, USART_CR1_RE | USART_CR1_TE, TransferDirection); + } + + /** + * @brief Return enabled/disabled states of Transmitter and Receiver + * @rmtoll CR1 RE LL_USART_GetTransferDirection\n + * CR1 TE LL_USART_GetTransferDirection + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_DIRECTION_NONE + * @arg @ref LL_USART_DIRECTION_RX + * @arg @ref LL_USART_DIRECTION_TX + * @arg @ref LL_USART_DIRECTION_TX_RX + */ + __STATIC_INLINE uint32_t LL_USART_GetTransferDirection(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_RE | USART_CR1_TE)); + } + + /** + * @brief Configure Parity (enabled/disabled and parity mode if enabled). + * @note This function selects if hardware parity control (generation and detection) + * is enabled or disabled. When the parity control is enabled (Odd or Even), computed + * parity bit is inserted at the MSB position (9th or 8th bit depending on data width) + * and parity is checked on the received data. + * @rmtoll CR1 PS LL_USART_SetParity\n + * CR1 PCE LL_USART_SetParity + * @param USARTx USART Instance + * @param Parity This parameter can be one of the following values: + * @arg @ref LL_USART_PARITY_NONE + * @arg @ref LL_USART_PARITY_EVEN + * @arg @ref LL_USART_PARITY_ODD + * @retval None + */ + __STATIC_INLINE void LL_USART_SetParity(USART_TypeDef *USARTx, uint32_t Parity) + { + MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE, Parity); + } + + /** + * @brief Return Parity configuration (enabled/disabled and parity mode if enabled) + * @rmtoll CR1 PS LL_USART_GetParity\n + * CR1 PCE LL_USART_GetParity + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_PARITY_NONE + * @arg @ref LL_USART_PARITY_EVEN + * @arg @ref LL_USART_PARITY_ODD + */ + __STATIC_INLINE uint32_t LL_USART_GetParity(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE)); + } + + /** + * @brief Set Receiver Wake Up method from Mute mode. + * @rmtoll CR1 WAKE LL_USART_SetWakeUpMethod + * @param USARTx USART Instance + * @param Method This parameter can be one of the following values: + * @arg @ref LL_USART_WAKEUP_IDLELINE + * @arg @ref LL_USART_WAKEUP_ADDRESSMARK + * @retval None + */ + __STATIC_INLINE void LL_USART_SetWakeUpMethod(USART_TypeDef *USARTx, uint32_t Method) + { + MODIFY_REG(USARTx->CR1, USART_CR1_WAKE, Method); + } + + /** + * @brief Return Receiver Wake Up method from Mute mode + * @rmtoll CR1 WAKE LL_USART_GetWakeUpMethod + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_WAKEUP_IDLELINE + * @arg @ref LL_USART_WAKEUP_ADDRESSMARK + */ + __STATIC_INLINE uint32_t LL_USART_GetWakeUpMethod(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_WAKE)); + } + + /** + * @brief Set Word length (i.e. nb of data bits, excluding start and stop bits) + * @rmtoll CR1 M0 LL_USART_SetDataWidth\n + * CR1 M1 LL_USART_SetDataWidth + * @param USARTx USART Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref LL_USART_DATAWIDTH_7B (*) + * @arg @ref LL_USART_DATAWIDTH_8B + * @arg @ref LL_USART_DATAWIDTH_9B + * + * (*) Values not available on all devices + * @retval None + */ + __STATIC_INLINE void LL_USART_SetDataWidth(USART_TypeDef *USARTx, uint32_t DataWidth) + { + MODIFY_REG(USARTx->CR1, USART_CR1_M, DataWidth); + } + + /** + * @brief Return Word length (i.e. nb of data bits, excluding start and stop bits) + * @rmtoll CR1 M0 LL_USART_GetDataWidth\n + * CR1 M1 LL_USART_GetDataWidth + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_DATAWIDTH_7B (*) + * @arg @ref LL_USART_DATAWIDTH_8B + * @arg @ref LL_USART_DATAWIDTH_9B + * + * (*) Values not available on all devices + */ + __STATIC_INLINE uint32_t LL_USART_GetDataWidth(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_M)); + } + + /** + * @brief Allow switch between Mute Mode and Active mode + * @rmtoll CR1 MME LL_USART_EnableMuteMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableMuteMode(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_MME); + } + + /** + * @brief Prevent Mute Mode use. Set Receiver in active mode permanently. + * @rmtoll CR1 MME LL_USART_DisableMuteMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableMuteMode(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_MME); + } + + /** + * @brief Indicate if switch between Mute Mode and Active mode is allowed + * @rmtoll CR1 MME LL_USART_IsEnabledMuteMode + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledMuteMode(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_MME) == (USART_CR1_MME)) ? 1UL : 0UL); + } + + /** + * @brief Set Oversampling to 8-bit or 16-bit mode + * @rmtoll CR1 OVER8 LL_USART_SetOverSampling + * @param USARTx USART Instance + * @param OverSampling This parameter can be one of the following values: + * @arg @ref LL_USART_OVERSAMPLING_16 + * @arg @ref LL_USART_OVERSAMPLING_8 + * @retval None + */ + __STATIC_INLINE void LL_USART_SetOverSampling(USART_TypeDef *USARTx, + uint32_t OverSampling) + { + MODIFY_REG(USARTx->CR1, USART_CR1_OVER8, OverSampling); + } + + /** + * @brief Return Oversampling mode + * @rmtoll CR1 OVER8 LL_USART_GetOverSampling + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_OVERSAMPLING_16 + * @arg @ref LL_USART_OVERSAMPLING_8 + */ + __STATIC_INLINE uint32_t LL_USART_GetOverSampling(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_OVER8)); + } + + /** + * @brief Configure if Clock pulse of the last data bit is output to the SCLK pin or + * not + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 LBCL LL_USART_SetLastClkPulseOutput + * @param USARTx USART Instance + * @param LastBitClockPulse This parameter can be one of the following values: + * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT + * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT + * @retval None + */ + __STATIC_INLINE void LL_USART_SetLastClkPulseOutput(USART_TypeDef *USARTx, + uint32_t LastBitClockPulse) + { + MODIFY_REG(USARTx->CR2, USART_CR2_LBCL, LastBitClockPulse); + } + + /** + * @brief Retrieve Clock pulse of the last data bit output configuration + * (Last bit Clock pulse output to the SCLK pin or not) + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 LBCL LL_USART_GetLastClkPulseOutput + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT + * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT + */ + __STATIC_INLINE uint32_t LL_USART_GetLastClkPulseOutput(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBCL)); + } + + /** + * @brief Select the phase of the clock output on the SCLK pin in synchronous mode + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CPHA LL_USART_SetClockPhase + * @param USARTx USART Instance + * @param ClockPhase This parameter can be one of the following values: + * @arg @ref LL_USART_PHASE_1EDGE + * @arg @ref LL_USART_PHASE_2EDGE + * @retval None + */ + __STATIC_INLINE void LL_USART_SetClockPhase(USART_TypeDef *USARTx, + uint32_t ClockPhase) + { + MODIFY_REG(USARTx->CR2, USART_CR2_CPHA, ClockPhase); + } + + /** + * @brief Return phase of the clock output on the SCLK pin in synchronous mode + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CPHA LL_USART_GetClockPhase + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_PHASE_1EDGE + * @arg @ref LL_USART_PHASE_2EDGE + */ + __STATIC_INLINE uint32_t LL_USART_GetClockPhase(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPHA)); + } + + /** + * @brief Select the polarity of the clock output on the SCLK pin in synchronous mode + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CPOL LL_USART_SetClockPolarity + * @param USARTx USART Instance + * @param ClockPolarity This parameter can be one of the following values: + * @arg @ref LL_USART_POLARITY_LOW + * @arg @ref LL_USART_POLARITY_HIGH + * @retval None + */ + __STATIC_INLINE void LL_USART_SetClockPolarity(USART_TypeDef *USARTx, + uint32_t ClockPolarity) + { + MODIFY_REG(USARTx->CR2, USART_CR2_CPOL, ClockPolarity); + } + + /** + * @brief Return polarity of the clock output on the SCLK pin in synchronous mode + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CPOL LL_USART_GetClockPolarity + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_POLARITY_LOW + * @arg @ref LL_USART_POLARITY_HIGH + */ + __STATIC_INLINE uint32_t LL_USART_GetClockPolarity(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_CPOL)); + } + + /** + * @brief Configure Clock signal format (Phase Polarity and choice about output of + * last bit clock pulse) + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clock Phase configuration using @ref LL_USART_SetClockPhase() function + * - Clock Polarity configuration using @ref LL_USART_SetClockPolarity() + * function + * - Output of Last bit Clock pulse configuration using @ref + * LL_USART_SetLastClkPulseOutput() function + * @rmtoll CR2 CPHA LL_USART_ConfigClock\n + * CR2 CPOL LL_USART_ConfigClock\n + * CR2 LBCL LL_USART_ConfigClock + * @param USARTx USART Instance + * @param Phase This parameter can be one of the following values: + * @arg @ref LL_USART_PHASE_1EDGE + * @arg @ref LL_USART_PHASE_2EDGE + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_USART_POLARITY_LOW + * @arg @ref LL_USART_POLARITY_HIGH + * @param LBCPOutput This parameter can be one of the following values: + * @arg @ref LL_USART_LASTCLKPULSE_NO_OUTPUT + * @arg @ref LL_USART_LASTCLKPULSE_OUTPUT + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigClock(USART_TypeDef *USARTx, uint32_t Phase, + uint32_t Polarity, uint32_t LBCPOutput) + { + MODIFY_REG(USARTx->CR2, USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL, + Phase | Polarity | LBCPOutput); + } + + /** + * @brief Enable Clock output on SCLK pin + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CLKEN LL_USART_EnableSCLKOutput + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableSCLKOutput(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR2, USART_CR2_CLKEN); + } + + /** + * @brief Disable Clock output on SCLK pin + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CLKEN LL_USART_DisableSCLKOutput + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableSCLKOutput(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN); + } + + /** + * @brief Indicate if Clock output on SCLK pin is enabled + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @rmtoll CR2 CLKEN LL_USART_IsEnabledSCLKOutput + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledSCLKOutput(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR2, USART_CR2_CLKEN) == (USART_CR2_CLKEN)) ? 1UL + : 0UL); + } + + /** + * @brief Set the length of the stop bits + * @rmtoll CR2 STOP LL_USART_SetStopBitsLength + * @param USARTx USART Instance + * @param StopBits This parameter can be one of the following values: + * @arg @ref LL_USART_STOPBITS_0_5 (*) + * @arg @ref LL_USART_STOPBITS_1 + * @arg @ref LL_USART_STOPBITS_1_5 (*) + * @arg @ref LL_USART_STOPBITS_2 + * + * (*) Values not available on all devices + * @retval None + */ + __STATIC_INLINE void LL_USART_SetStopBitsLength(USART_TypeDef *USARTx, + uint32_t StopBits) + { + MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits); + } + + /** + * @brief Retrieve the length of the stop bits + * @rmtoll CR2 STOP LL_USART_GetStopBitsLength + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_STOPBITS_0_5 (*) + * @arg @ref LL_USART_STOPBITS_1 + * @arg @ref LL_USART_STOPBITS_1_5 (*) + * @arg @ref LL_USART_STOPBITS_2 + * + * (*) Values not available on all devices + */ + __STATIC_INLINE uint32_t LL_USART_GetStopBitsLength(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_STOP)); + } + + /** + * @brief Configure Character frame format (Datawidth, Parity control, Stop Bits) + * @note Call of this function is equivalent to following function call sequence : + * - Data Width configuration using @ref LL_USART_SetDataWidth() function + * - Parity Control and mode configuration using @ref LL_USART_SetParity() + * function + * - Stop bits configuration using @ref LL_USART_SetStopBitsLength() function + * @rmtoll CR1 PS LL_USART_ConfigCharacter\n + * CR1 PCE LL_USART_ConfigCharacter\n + * CR1 M0 LL_USART_ConfigCharacter\n + * CR1 M1 LL_USART_ConfigCharacter\n + * CR2 STOP LL_USART_ConfigCharacter + * @param USARTx USART Instance + * @param DataWidth This parameter can be one of the following values: + * @arg @ref LL_USART_DATAWIDTH_7B (*) + * @arg @ref LL_USART_DATAWIDTH_8B + * @arg @ref LL_USART_DATAWIDTH_9B + * @param Parity This parameter can be one of the following values: + * @arg @ref LL_USART_PARITY_NONE + * @arg @ref LL_USART_PARITY_EVEN + * @arg @ref LL_USART_PARITY_ODD + * @param StopBits This parameter can be one of the following values: + * @arg @ref LL_USART_STOPBITS_0_5 (*) + * @arg @ref LL_USART_STOPBITS_1 + * @arg @ref LL_USART_STOPBITS_1_5 (*) + * @arg @ref LL_USART_STOPBITS_2 + * + * (*) Values not available on all devices + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigCharacter(USART_TypeDef *USARTx, + uint32_t DataWidth, uint32_t Parity, + uint32_t StopBits) + { + MODIFY_REG(USARTx->CR1, USART_CR1_PS | USART_CR1_PCE | USART_CR1_M, + Parity | DataWidth); + MODIFY_REG(USARTx->CR2, USART_CR2_STOP, StopBits); + } + + /** + * @brief Configure TX/RX pins swapping setting. + * @rmtoll CR2 SWAP LL_USART_SetTXRXSwap + * @param USARTx USART Instance + * @param SwapConfig This parameter can be one of the following values: + * @arg @ref LL_USART_TXRX_STANDARD + * @arg @ref LL_USART_TXRX_SWAPPED + * @retval None + */ + __STATIC_INLINE void LL_USART_SetTXRXSwap(USART_TypeDef *USARTx, uint32_t SwapConfig) + { + MODIFY_REG(USARTx->CR2, USART_CR2_SWAP, SwapConfig); + } + + /** + * @brief Retrieve TX/RX pins swapping configuration. + * @rmtoll CR2 SWAP LL_USART_GetTXRXSwap + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_TXRX_STANDARD + * @arg @ref LL_USART_TXRX_SWAPPED + */ + __STATIC_INLINE uint32_t LL_USART_GetTXRXSwap(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_SWAP)); + } + + /** + * @brief Configure RX pin active level logic + * @rmtoll CR2 RXINV LL_USART_SetRXPinLevel + * @param USARTx USART Instance + * @param PinInvMethod This parameter can be one of the following values: + * @arg @ref LL_USART_RXPIN_LEVEL_STANDARD + * @arg @ref LL_USART_RXPIN_LEVEL_INVERTED + * @retval None + */ + __STATIC_INLINE void LL_USART_SetRXPinLevel(USART_TypeDef *USARTx, + uint32_t PinInvMethod) + { + MODIFY_REG(USARTx->CR2, USART_CR2_RXINV, PinInvMethod); + } + + /** + * @brief Retrieve RX pin active level logic configuration + * @rmtoll CR2 RXINV LL_USART_GetRXPinLevel + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_RXPIN_LEVEL_STANDARD + * @arg @ref LL_USART_RXPIN_LEVEL_INVERTED + */ + __STATIC_INLINE uint32_t LL_USART_GetRXPinLevel(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_RXINV)); + } + + /** + * @brief Configure TX pin active level logic + * @rmtoll CR2 TXINV LL_USART_SetTXPinLevel + * @param USARTx USART Instance + * @param PinInvMethod This parameter can be one of the following values: + * @arg @ref LL_USART_TXPIN_LEVEL_STANDARD + * @arg @ref LL_USART_TXPIN_LEVEL_INVERTED + * @retval None + */ + __STATIC_INLINE void LL_USART_SetTXPinLevel(USART_TypeDef *USARTx, + uint32_t PinInvMethod) + { + MODIFY_REG(USARTx->CR2, USART_CR2_TXINV, PinInvMethod); + } + + /** + * @brief Retrieve TX pin active level logic configuration + * @rmtoll CR2 TXINV LL_USART_GetTXPinLevel + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_TXPIN_LEVEL_STANDARD + * @arg @ref LL_USART_TXPIN_LEVEL_INVERTED + */ + __STATIC_INLINE uint32_t LL_USART_GetTXPinLevel(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_TXINV)); + } + + /** + * @brief Configure Binary data logic. + * @note Allow to define how Logical data from the data register are send/received : + * either in positive/direct logic (1=H, 0=L) or in negative/inverse logic + * (1=L, 0=H) + * @rmtoll CR2 DATAINV LL_USART_SetBinaryDataLogic + * @param USARTx USART Instance + * @param DataLogic This parameter can be one of the following values: + * @arg @ref LL_USART_BINARY_LOGIC_POSITIVE + * @arg @ref LL_USART_BINARY_LOGIC_NEGATIVE + * @retval None + */ + __STATIC_INLINE void LL_USART_SetBinaryDataLogic(USART_TypeDef *USARTx, + uint32_t DataLogic) + { + MODIFY_REG(USARTx->CR2, USART_CR2_DATAINV, DataLogic); + } + + /** + * @brief Retrieve Binary data configuration + * @rmtoll CR2 DATAINV LL_USART_GetBinaryDataLogic + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_BINARY_LOGIC_POSITIVE + * @arg @ref LL_USART_BINARY_LOGIC_NEGATIVE + */ + __STATIC_INLINE uint32_t LL_USART_GetBinaryDataLogic(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_DATAINV)); + } + + /** + * @brief Configure transfer bit order (either Less or Most Significant Bit First) + * @note MSB First means data is transmitted/received with the MSB first, following + * the start bit. LSB First means data is transmitted/received with data bit 0 first, + * following the start bit. + * @rmtoll CR2 MSBFIRST LL_USART_SetTransferBitOrder + * @param USARTx USART Instance + * @param BitOrder This parameter can be one of the following values: + * @arg @ref LL_USART_BITORDER_LSBFIRST + * @arg @ref LL_USART_BITORDER_MSBFIRST + * @retval None + */ + __STATIC_INLINE void LL_USART_SetTransferBitOrder(USART_TypeDef *USARTx, + uint32_t BitOrder) + { + MODIFY_REG(USARTx->CR2, USART_CR2_MSBFIRST, BitOrder); + } + + /** + * @brief Return transfer bit order (either Less or Most Significant Bit First) + * @note MSB First means data is transmitted/received with the MSB first, following + * the start bit. LSB First means data is transmitted/received with data bit 0 first, + * following the start bit. + * @rmtoll CR2 MSBFIRST LL_USART_GetTransferBitOrder + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_BITORDER_LSBFIRST + * @arg @ref LL_USART_BITORDER_MSBFIRST + */ + __STATIC_INLINE uint32_t LL_USART_GetTransferBitOrder(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_MSBFIRST)); + } + + /** + * @brief Enable Auto Baud-Rate Detection + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check + * whether or not Auto Baud Rate detection feature is supported by the USARTx + * instance. + * @rmtoll CR2 ABREN LL_USART_EnableAutoBaudRate + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableAutoBaudRate(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR2, USART_CR2_ABREN); + } + + /** + * @brief Disable Auto Baud-Rate Detection + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check + * whether or not Auto Baud Rate detection feature is supported by the USARTx + * instance. + * @rmtoll CR2 ABREN LL_USART_DisableAutoBaudRate + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableAutoBaudRate(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR2, USART_CR2_ABREN); + } + + /** + * @brief Indicate if Auto Baud-Rate Detection mechanism is enabled + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check + * whether or not Auto Baud Rate detection feature is supported by the USARTx + * instance. + * @rmtoll CR2 ABREN LL_USART_IsEnabledAutoBaud + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledAutoBaud(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR2, USART_CR2_ABREN) == (USART_CR2_ABREN)) ? 1UL + : 0UL); + } + + /** + * @brief Set Auto Baud-Rate mode bits + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check + * whether or not Auto Baud Rate detection feature is supported by the USARTx + * instance. + * @rmtoll CR2 ABRMODE LL_USART_SetAutoBaudRateMode + * @param USARTx USART Instance + * @param AutoBaudRateMode This parameter can be one of the following values: + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_STARTBIT + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME (*) + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_55_FRAME (*) + * + * (*) Values not available on all devices + * @retval None + */ + __STATIC_INLINE void LL_USART_SetAutoBaudRateMode(USART_TypeDef *USARTx, + uint32_t AutoBaudRateMode) + { + MODIFY_REG(USARTx->CR2, USART_CR2_ABRMODE, AutoBaudRateMode); + } + + /** + * @brief Return Auto Baud-Rate mode + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check + * whether or not Auto Baud Rate detection feature is supported by the USARTx + * instance. + * @rmtoll CR2 ABRMODE LL_USART_GetAutoBaudRateMode + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_STARTBIT + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_FALLINGEDGE + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_7F_FRAME (*) + * @arg @ref LL_USART_AUTOBAUD_DETECT_ON_55_FRAME (*) + * + * (*) Values not available on all devices + */ + __STATIC_INLINE uint32_t LL_USART_GetAutoBaudRateMode(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ABRMODE)); + } + + /** + * @brief Enable Receiver Timeout + * @rmtoll CR2 RTOEN LL_USART_EnableRxTimeout + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableRxTimeout(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR2, USART_CR2_RTOEN); + } + + /** + * @brief Disable Receiver Timeout + * @rmtoll CR2 RTOEN LL_USART_DisableRxTimeout + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableRxTimeout(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR2, USART_CR2_RTOEN); + } + + /** + * @brief Indicate if Receiver Timeout feature is enabled + * @rmtoll CR2 RTOEN LL_USART_IsEnabledRxTimeout + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledRxTimeout(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR2, USART_CR2_RTOEN) == (USART_CR2_RTOEN)) ? 1UL + : 0UL); + } + + /** + * @brief Set Address of the USART node. + * @note This is used in multiprocessor communication during Mute mode or Stop mode, + * for wake up with address mark detection. + * @note 4bits address node is used when 4-bit Address Detection is selected in + * ADDM7. (b7-b4 should be set to 0) 8bits address node is used when 7-bit Address + * Detection is selected in ADDM7. (This is used in multiprocessor communication + * during Mute mode or Stop mode, for wake up with 7-bit address mark detection. The + * MSB of the character sent by the transmitter should be equal to 1. It may also be + * used for character detection during normal reception, Mute mode inactive (for + * example, end of block detection in ModBus protocol). In this case, the whole + * received character (8-bit) is compared to the ADD[7:0] value and CMF flag is set on + * match) + * @rmtoll CR2 ADD LL_USART_ConfigNodeAddress\n + * CR2 ADDM7 LL_USART_ConfigNodeAddress + * @param USARTx USART Instance + * @param AddressLen This parameter can be one of the following values: + * @arg @ref LL_USART_ADDRESS_DETECT_4B + * @arg @ref LL_USART_ADDRESS_DETECT_7B + * @param NodeAddress 4 or 7 bit Address of the USART node. + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigNodeAddress(USART_TypeDef *USARTx, + uint32_t AddressLen, + uint32_t NodeAddress) + { + MODIFY_REG(USARTx->CR2, USART_CR2_ADD | USART_CR2_ADDM7, + (uint32_t)(AddressLen | (NodeAddress << USART_CR2_ADD_Pos))); + } + + /** + * @brief Return 8 bit Address of the USART node as set in ADD field of CR2. + * @note If 4-bit Address Detection is selected in ADDM7, + * only 4bits (b3-b0) of returned value are relevant (b31-b4 are not relevant) + * If 7-bit Address Detection is selected in ADDM7, + * only 8bits (b7-b0) of returned value are relevant (b31-b8 are not relevant) + * @rmtoll CR2 ADD LL_USART_GetNodeAddress + * @param USARTx USART Instance + * @retval Address of the USART node (Value between Min_Data=0 and Max_Data=255) + */ + __STATIC_INLINE uint32_t LL_USART_GetNodeAddress(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADD) >> USART_CR2_ADD_Pos); + } + + /** + * @brief Return Length of Node Address used in Address Detection mode (7-bit or + * 4-bit) + * @rmtoll CR2 ADDM7 LL_USART_GetNodeAddressLen + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_ADDRESS_DETECT_4B + * @arg @ref LL_USART_ADDRESS_DETECT_7B + */ + __STATIC_INLINE uint32_t LL_USART_GetNodeAddressLen(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_ADDM7)); + } + + /** + * @brief Enable RTS HW Flow Control + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 RTSE LL_USART_EnableRTSHWFlowCtrl + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableRTSHWFlowCtrl(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_RTSE); + } + + /** + * @brief Disable RTS HW Flow Control + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 RTSE LL_USART_DisableRTSHWFlowCtrl + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableRTSHWFlowCtrl(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_RTSE); + } + + /** + * @brief Enable CTS HW Flow Control + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSE LL_USART_EnableCTSHWFlowCtrl + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableCTSHWFlowCtrl(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_CTSE); + } + + /** + * @brief Disable CTS HW Flow Control + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSE LL_USART_DisableCTSHWFlowCtrl + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableCTSHWFlowCtrl(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_CTSE); + } + + /** + * @brief Configure HW Flow Control mode (both CTS and RTS) + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 RTSE LL_USART_SetHWFlowCtrl\n + * CR3 CTSE LL_USART_SetHWFlowCtrl + * @param USARTx USART Instance + * @param HardwareFlowControl This parameter can be one of the following values: + * @arg @ref LL_USART_HWCONTROL_NONE + * @arg @ref LL_USART_HWCONTROL_RTS + * @arg @ref LL_USART_HWCONTROL_CTS + * @arg @ref LL_USART_HWCONTROL_RTS_CTS + * @retval None + */ + __STATIC_INLINE void LL_USART_SetHWFlowCtrl(USART_TypeDef *USARTx, + uint32_t HardwareFlowControl) + { + MODIFY_REG(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE, HardwareFlowControl); + } + + /** + * @brief Return HW Flow Control configuration (both CTS and RTS) + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 RTSE LL_USART_GetHWFlowCtrl\n + * CR3 CTSE LL_USART_GetHWFlowCtrl + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_HWCONTROL_NONE + * @arg @ref LL_USART_HWCONTROL_RTS + * @arg @ref LL_USART_HWCONTROL_CTS + * @arg @ref LL_USART_HWCONTROL_RTS_CTS + */ + __STATIC_INLINE uint32_t LL_USART_GetHWFlowCtrl(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_RTSE | USART_CR3_CTSE)); + } + + /** + * @brief Enable One bit sampling method + * @rmtoll CR3 ONEBIT LL_USART_EnableOneBitSamp + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableOneBitSamp(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_ONEBIT); + } + + /** + * @brief Disable One bit sampling method + * @rmtoll CR3 ONEBIT LL_USART_DisableOneBitSamp + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableOneBitSamp(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_ONEBIT); + } + + /** + * @brief Indicate if One bit sampling method is enabled + * @rmtoll CR3 ONEBIT LL_USART_IsEnabledOneBitSamp + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledOneBitSamp(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_ONEBIT) == (USART_CR3_ONEBIT)) ? 1UL + : 0UL); + } + + /** + * @brief Enable Overrun detection + * @rmtoll CR3 OVRDIS LL_USART_EnableOverrunDetect + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableOverrunDetect(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_OVRDIS); + } + + /** + * @brief Disable Overrun detection + * @rmtoll CR3 OVRDIS LL_USART_DisableOverrunDetect + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableOverrunDetect(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_OVRDIS); + } + + /** + * @brief Indicate if Overrun detection is enabled + * @rmtoll CR3 OVRDIS LL_USART_IsEnabledOverrunDetect + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledOverrunDetect(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_OVRDIS) != USART_CR3_OVRDIS) ? 1UL + : 0UL); + } + +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUS) + /** + * @brief Select event type for Wake UP Interrupt Flag (WUS[1:0] bits) + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUS LL_USART_SetWKUPType + * @param USARTx USART Instance + * @param Type This parameter can be one of the following values: + * @arg @ref LL_USART_WAKEUP_ON_ADDRESS + * @arg @ref LL_USART_WAKEUP_ON_STARTBIT + * @arg @ref LL_USART_WAKEUP_ON_RXNE + * @retval None + */ + __STATIC_INLINE void LL_USART_SetWKUPType(USART_TypeDef *USARTx, uint32_t Type) + { + MODIFY_REG(USARTx->CR3, USART_CR3_WUS, Type); + } + + /** + * @brief Return event type for Wake UP Interrupt Flag (WUS[1:0] bits) + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUS LL_USART_GetWKUPType + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_WAKEUP_ON_ADDRESS + * @arg @ref LL_USART_WAKEUP_ON_STARTBIT + * @arg @ref LL_USART_WAKEUP_ON_RXNE + */ + __STATIC_INLINE uint32_t LL_USART_GetWKUPType(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_WUS)); + } + +#endif /* USART_CR3_WUS */ +#endif /* USART_CR1_UESM */ + /** + * @brief Configure USART BRR register for achieving expected Baud Rate value. + * @note Compute and set USARTDIV value in BRR Register (full BRR content) + * according to used Peripheral Clock, Oversampling mode, and expected Baud + * Rate values + * @note Peripheral clock and Baud rate values provided as function parameters + * should be valid (Baud rate value != 0) + * @note In case of oversampling by 16 and 8, BRR content must be greater than or + * equal to 16d. + * @rmtoll BRR BRR LL_USART_SetBaudRate + * @param USARTx USART Instance + * @param PeriphClk Peripheral Clock + * @param OverSampling This parameter can be one of the following values: + * @arg @ref LL_USART_OVERSAMPLING_16 + * @arg @ref LL_USART_OVERSAMPLING_8 + * @param BaudRate Baud Rate + * @retval None + */ + __STATIC_INLINE void LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, + uint32_t OverSampling, uint32_t BaudRate) + { + uint32_t usartdiv; + uint32_t brrtemp; + + if (OverSampling == LL_USART_OVERSAMPLING_8) + { + usartdiv = (uint16_t)(__LL_USART_DIV_SAMPLING8(PeriphClk, BaudRate)); + brrtemp = usartdiv & 0xFFF0U; + brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); + USARTx->BRR = brrtemp; + } + else + { + USARTx->BRR = (uint16_t)(__LL_USART_DIV_SAMPLING16(PeriphClk, BaudRate)); + } + } + + /** + * @brief Return current Baud Rate value, according to USARTDIV present in BRR + * register (full BRR content), and to used Peripheral Clock and Oversampling mode + * values + * @note In case of non-initialized or invalid value stored in BRR register, value 0 + * will be returned. + * @note In case of oversampling by 16 and 8, BRR content must be greater than or + * equal to 16d. + * @rmtoll BRR BRR LL_USART_GetBaudRate + * @param USARTx USART Instance + * @param PeriphClk Peripheral Clock + * @param OverSampling This parameter can be one of the following values: + * @arg @ref LL_USART_OVERSAMPLING_16 + * @arg @ref LL_USART_OVERSAMPLING_8 + * @retval Baud Rate + */ + __STATIC_INLINE uint32_t LL_USART_GetBaudRate(const USART_TypeDef *USARTx, + uint32_t PeriphClk, + uint32_t OverSampling) + { + uint32_t usartdiv; + uint32_t brrresult = 0x0U; + + usartdiv = USARTx->BRR; + + if (usartdiv == 0U) + { + /* Do not perform a division by 0 */ + } + else if (OverSampling == LL_USART_OVERSAMPLING_8) + { + usartdiv = (uint16_t)((usartdiv & 0xFFF0U) | ((usartdiv & 0x0007U) << 1U)); + if (usartdiv != 0U) + { + brrresult = (PeriphClk * 2U) / usartdiv; + } + } + else + { + if ((usartdiv & 0xFFFFU) != 0U) + { + brrresult = PeriphClk / usartdiv; + } + } + return (brrresult); + } + + /** + * @brief Set Receiver Time Out Value (expressed in nb of bits duration) + * @rmtoll RTOR RTO LL_USART_SetRxTimeout + * @param USARTx USART Instance + * @param Timeout Value between Min_Data=0x00 and Max_Data=0x00FFFFFF + * @retval None + */ + __STATIC_INLINE void LL_USART_SetRxTimeout(USART_TypeDef *USARTx, uint32_t Timeout) + { + MODIFY_REG(USARTx->RTOR, USART_RTOR_RTO, Timeout); + } + + /** + * @brief Get Receiver Time Out Value (expressed in nb of bits duration) + * @rmtoll RTOR RTO LL_USART_GetRxTimeout + * @param USARTx USART Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x00FFFFFF + */ + __STATIC_INLINE uint32_t LL_USART_GetRxTimeout(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->RTOR, USART_RTOR_RTO)); + } + +#if defined(USART_SMARTCARD_SUPPORT) + /** + * @brief Set Block Length value in reception + * @rmtoll RTOR BLEN LL_USART_SetBlockLength + * @param USARTx USART Instance + * @param BlockLength Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ + __STATIC_INLINE void LL_USART_SetBlockLength(USART_TypeDef *USARTx, + uint32_t BlockLength) + { + MODIFY_REG(USARTx->RTOR, USART_RTOR_BLEN, BlockLength << USART_RTOR_BLEN_Pos); + } + + /** + * @brief Get Block Length value in reception + * @rmtoll RTOR BLEN LL_USART_GetBlockLength + * @param USARTx USART Instance + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ + __STATIC_INLINE uint32_t LL_USART_GetBlockLength(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->RTOR, USART_RTOR_BLEN) >> USART_RTOR_BLEN_Pos); + } +#endif /* USART_SMARTCARD_SUPPORT */ + + /** + * @} + */ + +#if defined(USART_IRDA_SUPPORT) + /** @defgroup USART_LL_EF_Configuration_IRDA Configuration functions related to Irda + * feature + * @{ + */ + + /** + * @brief Enable IrDA mode + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IREN LL_USART_EnableIrda + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIrda(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_IREN); + } + + /** + * @brief Disable IrDA mode + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IREN LL_USART_DisableIrda + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIrda(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_IREN); + } + + /** + * @brief Indicate if IrDA mode is enabled + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IREN LL_USART_IsEnabledIrda + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIrda(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_IREN) == (USART_CR3_IREN)) ? 1UL : 0UL); + } + + /** + * @brief Configure IrDA Power Mode (Normal or Low Power) + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IRLP LL_USART_SetIrdaPowerMode + * @param USARTx USART Instance + * @param PowerMode This parameter can be one of the following values: + * @arg @ref LL_USART_IRDA_POWER_NORMAL + * @arg @ref LL_USART_IRDA_POWER_LOW + * @retval None + */ + __STATIC_INLINE void LL_USART_SetIrdaPowerMode(USART_TypeDef *USARTx, + uint32_t PowerMode) + { + MODIFY_REG(USARTx->CR3, USART_CR3_IRLP, PowerMode); + } + + /** + * @brief Retrieve IrDA Power Mode configuration (Normal or Low Power) + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll CR3 IRLP LL_USART_GetIrdaPowerMode + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_IRDA_POWER_NORMAL + * @arg @ref LL_USART_PHASE_2EDGE + */ + __STATIC_INLINE uint32_t LL_USART_GetIrdaPowerMode(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_IRLP)); + } + + /** + * @brief Set Irda prescaler value, used for dividing the USART clock source + * to achieve the Irda Low Power frequency (8 bits value) + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll GTPR PSC LL_USART_SetIrdaPrescaler + * @param USARTx USART Instance + * @param PrescalerValue Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ + __STATIC_INLINE void LL_USART_SetIrdaPrescaler(USART_TypeDef *USARTx, + uint32_t PrescalerValue) + { + MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, (uint16_t)PrescalerValue); + } + + /** + * @brief Return Irda prescaler value, used for dividing the USART clock source + * to achieve the Irda Low Power frequency (8 bits value) + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @rmtoll GTPR PSC LL_USART_GetIrdaPrescaler + * @param USARTx USART Instance + * @retval Irda prescaler value (Value between Min_Data=0x00 and Max_Data=0xFF) + */ + __STATIC_INLINE uint32_t LL_USART_GetIrdaPrescaler(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC)); + } + +/** + * @} + */ +#endif /* USART_IRDA_SUPPORT */ + +#if defined(USART_SMARTCARD_SUPPORT) + /** @defgroup USART_LL_EF_Configuration_Smartcard Configuration functions related to + * Smartcard feature + * @{ + */ + + /** + * @brief Enable Smartcard NACK transmission + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 NACK LL_USART_EnableSmartcardNACK + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableSmartcardNACK(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_NACK); + } + + /** + * @brief Disable Smartcard NACK transmission + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 NACK LL_USART_DisableSmartcardNACK + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableSmartcardNACK(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_NACK); + } + + /** + * @brief Indicate if Smartcard NACK transmission is enabled + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 NACK LL_USART_IsEnabledSmartcardNACK + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcardNACK(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_NACK) == (USART_CR3_NACK)) ? 1UL : 0UL); + } + + /** + * @brief Enable Smartcard mode + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 SCEN LL_USART_EnableSmartcard + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableSmartcard(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_SCEN); + } + + /** + * @brief Disable Smartcard mode + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 SCEN LL_USART_DisableSmartcard + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableSmartcard(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_SCEN); + } + + /** + * @brief Indicate if Smartcard mode is enabled + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 SCEN LL_USART_IsEnabledSmartcard + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledSmartcard(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_SCEN) == (USART_CR3_SCEN)) ? 1UL : 0UL); + } + + /** + * @brief Set Smartcard Auto-Retry Count value (SCARCNT[2:0] bits) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @note This bit-field specifies the number of retries in transmit and receive, in + * Smartcard mode. In transmission mode, it specifies the number of automatic + * retransmission retries, before generating a transmission error (FE bit set). In + * reception mode, it specifies the number or erroneous reception trials, before + * generating a reception error (RXNE and PE bits set) + * @rmtoll CR3 SCARCNT LL_USART_SetSmartcardAutoRetryCount + * @param USARTx USART Instance + * @param AutoRetryCount Value between Min_Data=0 and Max_Data=7 + * @retval None + */ + __STATIC_INLINE void LL_USART_SetSmartcardAutoRetryCount(USART_TypeDef *USARTx, + uint32_t AutoRetryCount) + { + MODIFY_REG(USARTx->CR3, USART_CR3_SCARCNT, + AutoRetryCount << USART_CR3_SCARCNT_Pos); + } + + /** + * @brief Return Smartcard Auto-Retry Count value (SCARCNT[2:0] bits) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR3 SCARCNT LL_USART_GetSmartcardAutoRetryCount + * @param USARTx USART Instance + * @retval Smartcard Auto-Retry Count value (Value between Min_Data=0 and Max_Data=7) + */ + __STATIC_INLINE uint32_t + LL_USART_GetSmartcardAutoRetryCount(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_SCARCNT) >> + USART_CR3_SCARCNT_Pos); + } + + /** + * @brief Set Smartcard prescaler value, used for dividing the USART clock + * source to provide the SMARTCARD Clock (5 bits value) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll GTPR PSC LL_USART_SetSmartcardPrescaler + * @param USARTx USART Instance + * @param PrescalerValue Value between Min_Data=0 and Max_Data=31 + * @retval None + */ + __STATIC_INLINE void LL_USART_SetSmartcardPrescaler(USART_TypeDef *USARTx, + uint32_t PrescalerValue) + { + MODIFY_REG(USARTx->GTPR, USART_GTPR_PSC, (uint16_t)PrescalerValue); + } + + /** + * @brief Return Smartcard prescaler value, used for dividing the USART clock + * source to provide the SMARTCARD Clock (5 bits value) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll GTPR PSC LL_USART_GetSmartcardPrescaler + * @param USARTx USART Instance + * @retval Smartcard prescaler value (Value between Min_Data=0 and Max_Data=31) + */ + __STATIC_INLINE uint32_t LL_USART_GetSmartcardPrescaler(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_PSC)); + } + + /** + * @brief Set Smartcard Guard time value, expressed in nb of baud clocks periods + * (GT[7:0] bits : Guard time value) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll GTPR GT LL_USART_SetSmartcardGuardTime + * @param USARTx USART Instance + * @param GuardTime Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ + __STATIC_INLINE void LL_USART_SetSmartcardGuardTime(USART_TypeDef *USARTx, + uint32_t GuardTime) + { + MODIFY_REG(USARTx->GTPR, USART_GTPR_GT, + (uint16_t)(GuardTime << USART_GTPR_GT_Pos)); + } + + /** + * @brief Return Smartcard Guard time value, expressed in nb of baud clocks periods + * (GT[7:0] bits : Guard time value) + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll GTPR GT LL_USART_GetSmartcardGuardTime + * @param USARTx USART Instance + * @retval Smartcard Guard time value (Value between Min_Data=0x00 and Max_Data=0xFF) + */ + __STATIC_INLINE uint32_t LL_USART_GetSmartcardGuardTime(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->GTPR, USART_GTPR_GT) >> USART_GTPR_GT_Pos); + } + +/** + * @} + */ +#endif /* USART_SMARTCARD_SUPPORT */ + + /** @defgroup USART_LL_EF_Configuration_HalfDuplex Configuration functions related to + * Half Duplex feature + * @{ + */ + + /** + * @brief Enable Single Wire Half-Duplex mode + * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or + * not Half-Duplex mode is supported by the USARTx instance. + * @rmtoll CR3 HDSEL LL_USART_EnableHalfDuplex + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableHalfDuplex(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_HDSEL); + } + + /** + * @brief Disable Single Wire Half-Duplex mode + * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or + * not Half-Duplex mode is supported by the USARTx instance. + * @rmtoll CR3 HDSEL LL_USART_DisableHalfDuplex + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableHalfDuplex(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL); + } + + /** + * @brief Indicate if Single Wire Half-Duplex mode is enabled + * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or + * not Half-Duplex mode is supported by the USARTx instance. + * @rmtoll CR3 HDSEL LL_USART_IsEnabledHalfDuplex + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledHalfDuplex(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_HDSEL) == (USART_CR3_HDSEL)) ? 1UL + : 0UL); + } + + /** + * @} + */ + +#if defined(USART_LIN_SUPPORT) + /** @defgroup USART_LL_EF_Configuration_LIN Configuration functions related to LIN + * feature + * @{ + */ + + /** + * @brief Set LIN Break Detection Length + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDL LL_USART_SetLINBrkDetectionLen + * @param USARTx USART Instance + * @param LINBDLength This parameter can be one of the following values: + * @arg @ref LL_USART_LINBREAK_DETECT_10B + * @arg @ref LL_USART_LINBREAK_DETECT_11B + * @retval None + */ + __STATIC_INLINE void LL_USART_SetLINBrkDetectionLen(USART_TypeDef *USARTx, + uint32_t LINBDLength) + { + MODIFY_REG(USARTx->CR2, USART_CR2_LBDL, LINBDLength); + } + + /** + * @brief Return LIN Break Detection Length + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDL LL_USART_GetLINBrkDetectionLen + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_LINBREAK_DETECT_10B + * @arg @ref LL_USART_LINBREAK_DETECT_11B + */ + __STATIC_INLINE uint32_t LL_USART_GetLINBrkDetectionLen(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR2, USART_CR2_LBDL)); + } + + /** + * @brief Enable LIN mode + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LINEN LL_USART_EnableLIN + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableLIN(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR2, USART_CR2_LINEN); + } + + /** + * @brief Disable LIN mode + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LINEN LL_USART_DisableLIN + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableLIN(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR2, USART_CR2_LINEN); + } + + /** + * @brief Indicate if LIN mode is enabled + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LINEN LL_USART_IsEnabledLIN + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledLIN(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR2, USART_CR2_LINEN) == (USART_CR2_LINEN)) ? 1UL + : 0UL); + } + +/** + * @} + */ +#endif /* USART_LIN_SUPPORT */ + + /** @defgroup USART_LL_EF_Configuration_DE Configuration functions related to Driver + * Enable feature + * @{ + */ + + /** + * @brief Set DEDT (Driver Enable De-Assertion Time), Time value expressed on 5 bits + * ([4:0] bits). + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR1 DEDT LL_USART_SetDEDeassertionTime + * @param USARTx USART Instance + * @param Time Value between Min_Data=0 and Max_Data=31 + * @retval None + */ + __STATIC_INLINE void LL_USART_SetDEDeassertionTime(USART_TypeDef *USARTx, + uint32_t Time) + { + MODIFY_REG(USARTx->CR1, USART_CR1_DEDT, Time << USART_CR1_DEDT_Pos); + } + + /** + * @brief Return DEDT (Driver Enable De-Assertion Time) + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR1 DEDT LL_USART_GetDEDeassertionTime + * @param USARTx USART Instance + * @retval Time value expressed on 5 bits ([4:0] bits) : Value between Min_Data=0 and + * Max_Data=31 + */ + __STATIC_INLINE uint32_t LL_USART_GetDEDeassertionTime(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_DEDT) >> USART_CR1_DEDT_Pos); + } + + /** + * @brief Set DEAT (Driver Enable Assertion Time), Time value expressed on 5 bits + * ([4:0] bits). + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR1 DEAT LL_USART_SetDEAssertionTime + * @param USARTx USART Instance + * @param Time Value between Min_Data=0 and Max_Data=31 + * @retval None + */ + __STATIC_INLINE void LL_USART_SetDEAssertionTime(USART_TypeDef *USARTx, uint32_t Time) + { + MODIFY_REG(USARTx->CR1, USART_CR1_DEAT, Time << USART_CR1_DEAT_Pos); + } + + /** + * @brief Return DEAT (Driver Enable Assertion Time) + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR1 DEAT LL_USART_GetDEAssertionTime + * @param USARTx USART Instance + * @retval Time value expressed on 5 bits ([4:0] bits) : Value between Min_Data=0 and + * Max_Data=31 + */ + __STATIC_INLINE uint32_t LL_USART_GetDEAssertionTime(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR1, USART_CR1_DEAT) >> USART_CR1_DEAT_Pos); + } + + /** + * @brief Enable Driver Enable (DE) Mode + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEM LL_USART_EnableDEMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableDEMode(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_DEM); + } + + /** + * @brief Disable Driver Enable (DE) Mode + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEM LL_USART_DisableDEMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableDEMode(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_DEM); + } + + /** + * @brief Indicate if Driver Enable (DE) Mode is enabled + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEM LL_USART_IsEnabledDEMode + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledDEMode(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_DEM) == (USART_CR3_DEM)) ? 1UL : 0UL); + } + + /** + * @brief Select Driver Enable Polarity + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEP LL_USART_SetDESignalPolarity + * @param USARTx USART Instance + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_USART_DE_POLARITY_HIGH + * @arg @ref LL_USART_DE_POLARITY_LOW + * @retval None + */ + __STATIC_INLINE void LL_USART_SetDESignalPolarity(USART_TypeDef *USARTx, + uint32_t Polarity) + { + MODIFY_REG(USARTx->CR3, USART_CR3_DEP, Polarity); + } + + /** + * @brief Return Driver Enable Polarity + * @note Macro IS_UART_DRIVER_ENABLE_INSTANCE(USARTx) can be used to check whether + * or not Driver Enable feature is supported by the USARTx instance. + * @rmtoll CR3 DEP LL_USART_GetDESignalPolarity + * @param USARTx USART Instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_USART_DE_POLARITY_HIGH + * @arg @ref LL_USART_DE_POLARITY_LOW + */ + __STATIC_INLINE uint32_t LL_USART_GetDESignalPolarity(const USART_TypeDef *USARTx) + { + return (uint32_t)(READ_BIT(USARTx->CR3, USART_CR3_DEP)); + } + + /** + * @} + */ + + /** @defgroup USART_LL_EF_AdvancedConfiguration Advanced Configurations services + * @{ + */ + + /** + * @brief Perform basic configuration of USART for enabling use in Asynchronous Mode + * (UART) + * @note In UART mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register (if LIN feature is supported), + * - CLKEN bit in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register (if Smartcard feature is supported), + * - IREN bit in the USART_CR3 register (if Irda feature is supported), + * - HDSEL bit in the USART_CR3 register. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function (if LIN + * feature is supported) + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function (if + * Smartcard feature is supported) + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function (if Irda + * feature is supported) + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * @note Other remaining configurations items related to Asynchronous Mode + * (as Baud Rate, Word length, Parity, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigAsyncMode\n + * CR2 CLKEN LL_USART_ConfigAsyncMode\n + * CR3 SCEN LL_USART_ConfigAsyncMode\n + * CR3 IREN LL_USART_ConfigAsyncMode\n + * CR3 HDSEL LL_USART_ConfigAsyncMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigAsyncMode(USART_TypeDef *USARTx) + { + /* In Asynchronous mode, the following bits must be kept cleared: + - LINEN (if LIN feature is supported), CLKEN bits in the USART_CR2 register, + - SCEN (if Smartcard feature is supported), IREN (if Irda feature is supported) + and HDSEL bits in the USART_CR3 register. + */ +#if defined(USART_LIN_SUPPORT) + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); +#else + CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN); +#endif /* USART_LIN_SUPPORT */ +#if defined(USART_SMARTCARD_SUPPORT) +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL)); +#else + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); +#endif /* USART_IRDA_SUPPORT */ +#else +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL)); +#else + CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL); +#endif /* USART_IRDA_SUPPORT */ +#endif /* USART_SMARTCARD_SUPPORT */ + } + + /** + * @brief Perform basic configuration of USART for enabling use in Synchronous Mode + * @note In Synchronous mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register (if LIN feature is supported), + * - SCEN bit in the USART_CR3 register (if Smartcard feature is supported), + * - IREN bit in the USART_CR3 register (if Irda feature is supported), + * - HDSEL bit in the USART_CR3 register. + * This function also sets the USART in Synchronous mode. + * @note Macro IS_USART_INSTANCE(USARTx) can be used to check whether or not + * Synchronous mode is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function (if LIN + * feature is supported) + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function (if Irda + * feature is supported) + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function (if + * Smartcard feature is supported) + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function + * @note Other remaining configurations items related to Synchronous Mode + * (as Baud Rate, Word length, Parity, Clock Polarity, ...) should be set + * using dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigSyncMode\n + * CR2 CLKEN LL_USART_ConfigSyncMode\n + * CR3 SCEN LL_USART_ConfigSyncMode\n + * CR3 IREN LL_USART_ConfigSyncMode\n + * CR3 HDSEL LL_USART_ConfigSyncMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigSyncMode(USART_TypeDef *USARTx) + { + /* In Synchronous mode, the following bits must be kept cleared: + - LINEN (if LIN feature is supported) bit in the USART_CR2 register, + - SCEN (if Smartcard feature is supported), IREN (if Irda feature is supported) + and HDSEL bits in the USART_CR3 register. + */ +#if defined(USART_LIN_SUPPORT) + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN)); +#endif /* USART_LIN_SUPPORT */ +#if defined(USART_SMARTCARD_SUPPORT) +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN | USART_CR3_HDSEL)); +#else + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); +#endif /* USART_IRDA_SUPPORT */ +#else +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL)); +#else + CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL); +#endif /* USART_IRDA_SUPPORT */ +#endif /* USART_SMARTCARD_SUPPORT */ + /* set the UART/USART in Synchronous mode */ + SET_BIT(USARTx->CR2, USART_CR2_CLKEN); + } + +#if defined(USART_LIN_SUPPORT) + /** + * @brief Perform basic configuration of USART for enabling use in LIN Mode + * @note In LIN mode, the following bits must be kept cleared: + * - STOP and CLKEN bits in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register (if Smartcard feature is supported), + * - IREN bit in the USART_CR3 register (if Irda feature is supported), + * - HDSEL bit in the USART_CR3 register. + * This function also set the UART/USART in LIN mode. + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear STOP in CR2 using @ref LL_USART_SetStopBitsLength() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function (if + * Smartcard feature is supported) + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function (if Irda + * feature is supported) + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * - Set LINEN in CR2 using @ref LL_USART_EnableLIN() function + * @note Other remaining configurations items related to LIN Mode + * (as Baud Rate, Word length, LIN Break Detection Length, ...) should be set + * using dedicated functions + * @rmtoll CR2 CLKEN LL_USART_ConfigLINMode\n + * CR2 STOP LL_USART_ConfigLINMode\n + * CR2 LINEN LL_USART_ConfigLINMode\n + * CR3 IREN LL_USART_ConfigLINMode\n + * CR3 SCEN LL_USART_ConfigLINMode\n + * CR3 HDSEL LL_USART_ConfigLINMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigLINMode(USART_TypeDef *USARTx) + { + /* In LIN mode, the following bits must be kept cleared: + - STOP and CLKEN bits in the USART_CR2 register, + - IREN (if Irda feature is supported) , SCEN (if Smartcard feature is supported) + and HDSEL bits in the USART_CR3 register. + */ + CLEAR_BIT(USARTx->CR2, (USART_CR2_CLKEN | USART_CR2_STOP)); +#if defined(USART_SMARTCARD_SUPPORT) +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL)); +#else + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); +#endif /* USART_IRDA_SUPPORT */ +#else +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL)); +#else + CLEAR_BIT(USARTx->CR3, USART_CR3_HDSEL); +#endif /* USART_IRDA_SUPPORT */ +#endif /* USART_SMARTCARD_SUPPORT */ + /* Set the UART/USART in LIN mode */ + SET_BIT(USARTx->CR2, USART_CR2_LINEN); + } +#endif /* USART_LIN_SUPPORT */ + + /** + * @brief Perform basic configuration of USART for enabling use in Half Duplex Mode + * @note In Half Duplex mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register (if LIN feature is supported), + * - CLKEN bit in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register (if Smartcard feature is supported), + * - IREN bit in the USART_CR3 register (if Irda feature is supported), + * This function also sets the UART/USART in Half Duplex mode. + * @note Macro IS_UART_HALFDUPLEX_INSTANCE(USARTx) can be used to check whether or + * not Half-Duplex mode is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function (if LIN + * feature is supported) + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function (if + * Smartcard feature is supported) + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function (if Irda + * feature is supported) + * - Set HDSEL in CR3 using @ref LL_USART_EnableHalfDuplex() function + * @note Other remaining configurations items related to Half Duplex Mode + * (as Baud Rate, Word length, Parity, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigHalfDuplexMode\n + * CR2 CLKEN LL_USART_ConfigHalfDuplexMode\n + * CR3 HDSEL LL_USART_ConfigHalfDuplexMode\n + * CR3 SCEN LL_USART_ConfigHalfDuplexMode\n + * CR3 IREN LL_USART_ConfigHalfDuplexMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigHalfDuplexMode(USART_TypeDef *USARTx) + { + /* In Half Duplex mode, the following bits must be kept cleared: + - LINEN (if LIN feature is supported) and CLKEN bits in the USART_CR2 register, + - SCEN (if Smartcard feature is supported) and IREN (if Irda feature is supported) + bits in the USART_CR3 register. + */ +#if defined(USART_LIN_SUPPORT) + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); +#else + CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN); +#endif /* USART_LIN_SUPPORT */ +#if defined(USART_SMARTCARD_SUPPORT) +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_IREN)); +#else + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN)); +#endif /* USART_IRDA_SUPPORT */ +#else +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN)); +#endif /* USART_IRDA_SUPPORT */ +#endif /* USART_SMARTCARD_SUPPORT */ + /* set the UART/USART in Half Duplex mode */ + SET_BIT(USARTx->CR3, USART_CR3_HDSEL); + } + +#if defined(USART_SMARTCARD_SUPPORT) + /** + * @brief Perform basic configuration of USART for enabling use in Smartcard Mode + * @note In Smartcard mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register (if LIN feature is supported), + * - IREN bit in the USART_CR3 register (if Irda feature is supported), + * - HDSEL bit in the USART_CR3 register. + * This function also configures Stop bits to 1.5 bits and + * sets the USART in Smartcard mode (SCEN bit). + * Clock Output is also enabled (CLKEN). + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function (if LIN + * feature is supported) + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function (if Irda + * feature is supported) + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function + * - Set CLKEN in CR2 using @ref LL_USART_EnableSCLKOutput() function + * - Set SCEN in CR3 using @ref LL_USART_EnableSmartcard() function + * @note Other remaining configurations items related to Smartcard Mode + * (as Baud Rate, Word length, Parity, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigSmartcardMode\n + * CR2 STOP LL_USART_ConfigSmartcardMode\n + * CR2 CLKEN LL_USART_ConfigSmartcardMode\n + * CR3 HDSEL LL_USART_ConfigSmartcardMode\n + * CR3 SCEN LL_USART_ConfigSmartcardMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigSmartcardMode(USART_TypeDef *USARTx) + { + /* In Smartcard mode, the following bits must be kept cleared: + - LINEN (if LIN feature is supported) bit in the USART_CR2 register, + - IREN (if Irda feature is supported) and HDSEL bits in the USART_CR3 register. + */ +#if defined(USART_LIN_SUPPORT) + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN)); +#endif /* USART_LIN_SUPPORT */ +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_IREN | USART_CR3_HDSEL)); +#else + CLEAR_BIT(USARTx->CR3, (USART_CR3_HDSEL)); +#endif /* USART_IRDA_SUPPORT */ + /* Configure Stop bits to 1.5 bits */ + /* Synchronous mode is activated by default */ + SET_BIT(USARTx->CR2, (USART_CR2_STOP_0 | USART_CR2_STOP_1 | USART_CR2_CLKEN)); + /* set the UART/USART in Smartcard mode */ + SET_BIT(USARTx->CR3, USART_CR3_SCEN); + } +#endif /* USART_SMARTCARD_SUPPORT */ + +#if defined(USART_IRDA_SUPPORT) + /** + * @brief Perform basic configuration of USART for enabling use in Irda Mode + * @note In IRDA mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register (if LIN feature is supported), + * - STOP and CLKEN bits in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register (if Smartcard feature is supported), + * - HDSEL bit in the USART_CR3 register. + * This function also sets the UART/USART in IRDA mode (IREN bit). + * @note Macro IS_IRDA_INSTANCE(USARTx) can be used to check whether or not + * IrDA feature is supported by the USARTx instance. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function (if LIN + * feature is supported) + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function (if + * Smartcard feature is supported) + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * - Configure STOP in CR2 using @ref LL_USART_SetStopBitsLength() function + * - Set IREN in CR3 using @ref LL_USART_EnableIrda() function + * @note Other remaining configurations items related to Irda Mode + * (as Baud Rate, Word length, Power mode, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigIrdaMode\n + * CR2 CLKEN LL_USART_ConfigIrdaMode\n + * CR2 STOP LL_USART_ConfigIrdaMode\n + * CR3 SCEN LL_USART_ConfigIrdaMode\n + * CR3 HDSEL LL_USART_ConfigIrdaMode\n + * CR3 IREN LL_USART_ConfigIrdaMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigIrdaMode(USART_TypeDef *USARTx) + { + /* In IRDA mode, the following bits must be kept cleared: + - LINEN (if LIN feature is supported), STOP and CLKEN bits in the USART_CR2 + register, + - SCEN (if Smartcard feature is supported) and HDSEL bits in the USART_CR3 + register. + */ +#if defined(USART_LIN_SUPPORT) + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN | USART_CR2_STOP)); +#else + CLEAR_BIT(USARTx->CR2, (USART_CR2_CLKEN | USART_CR2_STOP)); +#endif /* USART_LIN_SUPPORT */ +#if defined(USART_SMARTCARD_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); +#else + CLEAR_BIT(USARTx->CR3, (USART_CR3_HDSEL)); +#endif /* USART_SMARTCARD_SUPPORT */ + /* set the UART/USART in IRDA mode */ + SET_BIT(USARTx->CR3, USART_CR3_IREN); + } +#endif /* USART_IRDA_SUPPORT */ + + /** + * @brief Perform basic configuration of USART for enabling use in Multi processor + * Mode (several USARTs connected in a network, one of the USARTs can be the master, + * its TX output connected to the RX inputs of the other slaves USARTs). + * @note In MultiProcessor mode, the following bits must be kept cleared: + * - LINEN bit in the USART_CR2 register (if LIN feature is supported), + * - CLKEN bit in the USART_CR2 register, + * - SCEN bit in the USART_CR3 register (if Smartcard feature is supported), + * - IREN bit in the USART_CR3 register (if Irda feature is supported), + * - HDSEL bit in the USART_CR3 register. + * @note Call of this function is equivalent to following function call sequence : + * - Clear LINEN in CR2 using @ref LL_USART_DisableLIN() function (if LIN + * feature is supported) + * - Clear CLKEN in CR2 using @ref LL_USART_DisableSCLKOutput() function + * - Clear SCEN in CR3 using @ref LL_USART_DisableSmartcard() function (if + * Smartcard feature is supported) + * - Clear IREN in CR3 using @ref LL_USART_DisableIrda() function (if Irda + * feature is supported) + * - Clear HDSEL in CR3 using @ref LL_USART_DisableHalfDuplex() function + * @note Other remaining configurations items related to Multi processor Mode + * (as Baud Rate, Wake Up Method, Node address, ...) should be set using + * dedicated functions + * @rmtoll CR2 LINEN LL_USART_ConfigMultiProcessMode\n + * CR2 CLKEN LL_USART_ConfigMultiProcessMode\n + * CR3 SCEN LL_USART_ConfigMultiProcessMode\n + * CR3 HDSEL LL_USART_ConfigMultiProcessMode\n + * CR3 IREN LL_USART_ConfigMultiProcessMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ConfigMultiProcessMode(USART_TypeDef *USARTx) + { + /* In Multi Processor mode, the following bits must be kept cleared: + - LINEN (if LIN feature is supported) and CLKEN bits in the USART_CR2 register, + - IREN (if Irda feature is supported), SCEN (if Smartcard feature is supported) + and HDSEL bits in the USART_CR3 register. + */ +#if defined(USART_LIN_SUPPORT) + CLEAR_BIT(USARTx->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); +#else + CLEAR_BIT(USARTx->CR2, USART_CR2_CLKEN); +#endif /* USART_LIN_SUPPORT */ +#if defined(USART_SMARTCARD_SUPPORT) +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); +#else + CLEAR_BIT(USARTx->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL)); +#endif /* USART_IRDA_SUPPORT */ +#else +#if defined(USART_IRDA_SUPPORT) + CLEAR_BIT(USARTx->CR3, (USART_CR3_HDSEL | USART_CR3_IREN)); +#else + CLEAR_BIT(USARTx->CR3, (USART_CR3_HDSEL)); +#endif /* USART_IRDA_SUPPORT */ +#endif /* USART_SMARTCARD_SUPPORT*/ + } + + /** + * @} + */ + + /** @defgroup USART_LL_EF_FLAG_Management FLAG_Management + * @{ + */ + + /** + * @brief Check if the USART Parity Error Flag is set or not + * @rmtoll ISR PE LL_USART_IsActiveFlag_PE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_PE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_PE) == (USART_ISR_PE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Framing Error Flag is set or not + * @rmtoll ISR FE LL_USART_IsActiveFlag_FE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_FE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_FE) == (USART_ISR_FE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Noise error detected Flag is set or not + * @rmtoll ISR NE LL_USART_IsActiveFlag_NE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_NE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_NE) == (USART_ISR_NE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART OverRun Error Flag is set or not + * @rmtoll ISR ORE LL_USART_IsActiveFlag_ORE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ORE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_ORE) == (USART_ISR_ORE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART IDLE line detected Flag is set or not + * @rmtoll ISR IDLE LL_USART_IsActiveFlag_IDLE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_IDLE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_IDLE) == (USART_ISR_IDLE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Read Data Register Not Empty Flag is set or not + * @rmtoll ISR RXNE LL_USART_IsActiveFlag_RXNE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_RXNE) == (USART_ISR_RXNE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Transmission Complete Flag is set or not + * @rmtoll ISR TC LL_USART_IsActiveFlag_TC + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TC(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_TC) == (USART_ISR_TC)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Transmit Data Register Empty Flag is set or not + * @rmtoll ISR TXE LL_USART_IsActiveFlag_TXE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_TXE) == (USART_ISR_TXE)) ? 1UL : 0UL); + } + +#if defined(USART_LIN_SUPPORT) + /** + * @brief Check if the USART LIN Break Detection Flag is set or not + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll ISR LBDF LL_USART_IsActiveFlag_LBD + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_LBD(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_LBDF) == (USART_ISR_LBDF)) ? 1UL : 0UL); + } +#endif /* USART_LIN_SUPPORT */ + + /** + * @brief Check if the USART CTS interrupt Flag is set or not + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll ISR CTSIF LL_USART_IsActiveFlag_nCTS + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_nCTS(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_CTSIF) == (USART_ISR_CTSIF)) ? 1UL + : 0UL); + } + + /** + * @brief Check if the USART CTS Flag is set or not + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll ISR CTS LL_USART_IsActiveFlag_CTS + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_CTS(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_CTS) == (USART_ISR_CTS)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Receiver Time Out Flag is set or not + * @rmtoll ISR RTOF LL_USART_IsActiveFlag_RTO + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RTO(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_RTOF) == (USART_ISR_RTOF)) ? 1UL : 0UL); + } + +#if defined(USART_SMARTCARD_SUPPORT) + /** + * @brief Check if the USART End Of Block Flag is set or not + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll ISR EOBF LL_USART_IsActiveFlag_EOB + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_EOB(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_EOBF) == (USART_ISR_EOBF)) ? 1UL : 0UL); + } +#endif /* USART_SMARTCARD_SUPPORT */ + + /** + * @brief Check if the USART Auto-Baud Rate Error Flag is set or not + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check + * whether or not Auto Baud Rate detection feature is supported by the USARTx + * instance. + * @rmtoll ISR ABRE LL_USART_IsActiveFlag_ABRE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ABRE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_ABRE) == (USART_ISR_ABRE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Auto-Baud Rate Flag is set or not + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check + * whether or not Auto Baud Rate detection feature is supported by the USARTx + * instance. + * @rmtoll ISR ABRF LL_USART_IsActiveFlag_ABR + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ABR(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_ABRF) == (USART_ISR_ABRF)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Busy Flag is set or not + * @rmtoll ISR BUSY LL_USART_IsActiveFlag_BUSY + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_BUSY(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_BUSY) == (USART_ISR_BUSY)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Character Match Flag is set or not + * @rmtoll ISR CMF LL_USART_IsActiveFlag_CM + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_CM(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_CMF) == (USART_ISR_CMF)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Send Break Flag is set or not + * @rmtoll ISR SBKF LL_USART_IsActiveFlag_SBK + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_SBK(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_SBKF) == (USART_ISR_SBKF)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Receive Wake Up from mute mode Flag is set or not + * @rmtoll ISR RWU LL_USART_IsActiveFlag_RWU + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RWU(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_RWU) == (USART_ISR_RWU)) ? 1UL : 0UL); + } + +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUFIE) + /** + * @brief Check if the USART Wake Up from stop mode Flag is set or not + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll ISR WUF LL_USART_IsActiveFlag_WKUP + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_WKUP(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_WUF) == (USART_ISR_WUF)) ? 1UL : 0UL); + } + +#endif /* USART_CR3_WUFIE */ +#endif /* USART_CR1_UESM */ + /** + * @brief Check if the USART Transmit Enable Acknowledge Flag is set or not + * @rmtoll ISR TEACK LL_USART_IsActiveFlag_TEACK + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TEACK(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_TEACK) == (USART_ISR_TEACK)) ? 1UL + : 0UL); + } + + /** + * @brief Check if the USART Receive Enable Acknowledge Flag is set or not + * @rmtoll ISR REACK LL_USART_IsActiveFlag_REACK + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsActiveFlag_REACK(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->ISR, USART_ISR_REACK) == (USART_ISR_REACK)) ? 1UL + : 0UL); + } + + /** + * @brief Clear Parity Error Flag + * @rmtoll ICR PECF LL_USART_ClearFlag_PE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_PE(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_PECF); + } + + /** + * @brief Clear Framing Error Flag + * @rmtoll ICR FECF LL_USART_ClearFlag_FE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_FE(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_FECF); + } + + /** + * @brief Clear Noise Error detected Flag + * @rmtoll ICR NCF LL_USART_ClearFlag_NE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_NE(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_NCF); + } + + /** + * @brief Clear OverRun Error Flag + * @rmtoll ICR ORECF LL_USART_ClearFlag_ORE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_ORECF); + } + + /** + * @brief Clear IDLE line detected Flag + * @rmtoll ICR IDLECF LL_USART_ClearFlag_IDLE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_IDLECF); + } + + /** + * @brief Clear Transmission Complete Flag + * @rmtoll ICR TCCF LL_USART_ClearFlag_TC + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_TC(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_TCCF); + } + + +#if defined(USART_LIN_SUPPORT) + /** + * @brief Clear LIN Break Detection Flag + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll ICR LBDCF LL_USART_ClearFlag_LBD + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_LBD(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_LBDCF); + } +#endif /* USART_LIN_SUPPORT */ + + /** + * @brief Clear CTS Interrupt Flag + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll ICR CTSCF LL_USART_ClearFlag_nCTS + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_nCTS(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_CTSCF); + } + + /** + * @brief Clear Receiver Time Out Flag + * @rmtoll ICR RTOCF LL_USART_ClearFlag_RTO + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_RTO(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_RTOCF); + } + +#if defined(USART_SMARTCARD_SUPPORT) + /** + * @brief Clear End Of Block Flag + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll ICR EOBCF LL_USART_ClearFlag_EOB + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_EOB(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_EOBCF); + } +#endif /* USART_SMARTCARD_SUPPORT */ + + /** + * @brief Clear Character Match Flag + * @rmtoll ICR CMCF LL_USART_ClearFlag_CM + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_CM(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_CMCF); + } + +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUFIE) + /** + * @brief Clear Wake Up from stop mode Flag + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll ICR WUCF LL_USART_ClearFlag_WKUP + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_ClearFlag_WKUP(USART_TypeDef *USARTx) + { + WRITE_REG(USARTx->ICR, USART_ICR_WUCF); + } + +#endif /* USART_CR3_WUFIE */ +#endif /* USART_CR1_UESM */ + /** + * @} + */ + + /** @defgroup USART_LL_EF_IT_Management IT_Management + * @{ + */ + + /** + * @brief Enable IDLE Interrupt + * @rmtoll CR1 IDLEIE LL_USART_EnableIT_IDLE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_IDLEIE); + } + + /** + * @brief Enable RX Not Empty Interrupt + * @rmtoll CR1 RXNEIE LL_USART_EnableIT_RXNE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_RXNE(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RXNEIE); + } + + /** + * @brief Enable Transmission Complete Interrupt + * @rmtoll CR1 TCIE LL_USART_EnableIT_TC + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_TC(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TCIE); + } + + /** + * @brief Enable TX Empty Interrupt + * @rmtoll CR1 TXEIE LL_USART_EnableIT_TXE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_TXE(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_TXEIE); + } + + /** + * @brief Enable Parity Error Interrupt + * @rmtoll CR1 PEIE LL_USART_EnableIT_PE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_PE(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_PEIE); + } + + /** + * @brief Enable Character Match Interrupt + * @rmtoll CR1 CMIE LL_USART_EnableIT_CM + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_CM(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_CMIE); + } + + /** + * @brief Enable Receiver Timeout Interrupt + * @rmtoll CR1 RTOIE LL_USART_EnableIT_RTO + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_RTO(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_RTOIE); + } + +#if defined(USART_SMARTCARD_SUPPORT) + /** + * @brief Enable End Of Block Interrupt + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR1 EOBIE LL_USART_EnableIT_EOB + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_EOB(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR1, USART_CR1_EOBIE); + } +#endif /* USART_SMARTCARD_SUPPORT */ + +#if defined(USART_LIN_SUPPORT) + /** + * @brief Enable LIN Break Detection Interrupt + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDIE LL_USART_EnableIT_LBD + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_LBD(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR2, USART_CR2_LBDIE); + } + +#endif /* USART_LIN_SUPPORT */ + /** + * @brief Enable Error Interrupt + * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in + * case of a framing error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the + * USARTx_ISR register). 0: Interrupt is inhibited 1: An interrupt is generated when + * FE=1 or ORE=1 or NF=1 in the USARTx_ISR register. + * @rmtoll CR3 EIE LL_USART_EnableIT_ERROR + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_ERROR(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_EIE); + } + + /** + * @brief Enable CTS Interrupt + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSIE LL_USART_EnableIT_CTS + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_CTS(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_CTSIE); + } + +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUFIE) + /** + * @brief Enable Wake Up from Stop Mode Interrupt + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUFIE LL_USART_EnableIT_WKUP + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableIT_WKUP(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_WUFIE); + } + +#endif /* USART_CR3_WUFIE */ +#endif /* USART_CR1_UESM */ + + /** + * @brief Disable IDLE Interrupt + * @rmtoll CR1 IDLEIE LL_USART_DisableIT_IDLE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_IDLE(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_IDLEIE); + } + + /** + * @brief Disable RX Not Empty Interrupt + * @rmtoll CR1 RXNEIE LL_USART_DisableIT_RXNE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_RXNE(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RXNEIE); + } + + /** + * @brief Disable Transmission Complete Interrupt + * @rmtoll CR1 TCIE LL_USART_DisableIT_TC + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_TC(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TCIE); + } + + /** + * @brief Disable TX Empty Interrupt + * @rmtoll CR1 TXEIE LL_USART_DisableIT_TXE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_TXE(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_TXEIE); + } + + /** + * @brief Disable Parity Error Interrupt + * @rmtoll CR1 PEIE LL_USART_DisableIT_PE + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_PE(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_PEIE); + } + + /** + * @brief Disable Character Match Interrupt + * @rmtoll CR1 CMIE LL_USART_DisableIT_CM + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_CM(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_CMIE); + } + + /** + * @brief Disable Receiver Timeout Interrupt + * @rmtoll CR1 RTOIE LL_USART_DisableIT_RTO + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_RTO(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_RTOIE); + } + +#if defined(USART_SMARTCARD_SUPPORT) + /** + * @brief Disable End Of Block Interrupt + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR1 EOBIE LL_USART_DisableIT_EOB + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_EOB(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR1, USART_CR1_EOBIE); + } +#endif /* USART_SMARTCARD_SUPPORT */ + +#if defined(USART_LIN_SUPPORT) + /** + * @brief Disable LIN Break Detection Interrupt + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDIE LL_USART_DisableIT_LBD + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_LBD(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR2, USART_CR2_LBDIE); + } +#endif /* USART_LIN_SUPPORT */ + + /** + * @brief Disable Error Interrupt + * @note When set, Error Interrupt Enable Bit is enabling interrupt generation in + * case of a framing error, overrun error or noise flag (FE=1 or ORE=1 or NF=1 in the + * USARTx_ISR register). 0: Interrupt is inhibited 1: An interrupt is generated when + * FE=1 or ORE=1 or NF=1 in the USARTx_ISR register. + * @rmtoll CR3 EIE LL_USART_DisableIT_ERROR + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_ERROR(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_EIE); + } + + /** + * @brief Disable CTS Interrupt + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSIE LL_USART_DisableIT_CTS + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_CTS(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_CTSIE); + } + +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUFIE) + /** + * @brief Disable Wake Up from Stop Mode Interrupt + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUFIE LL_USART_DisableIT_WKUP + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableIT_WKUP(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_WUFIE); + } + +#endif /* USART_CR3_WUFIE */ +#endif /* USART_CR1_UESM */ + + /** + * @brief Check if the USART IDLE Interrupt source is enabled or disabled. + * @rmtoll CR1 IDLEIE LL_USART_IsEnabledIT_IDLE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_IDLE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_IDLEIE) == (USART_CR1_IDLEIE)) ? 1UL + : 0UL); + } + + /** + * @brief Check if the USART RX Not Empty Interrupt is enabled or disabled. + * @rmtoll CR1 RXNEIE LL_USART_IsEnabledIT_RXNE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RXNE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_RXNEIE) == (USART_CR1_RXNEIE)) ? 1U + : 0U); + } + + /** + * @brief Check if the USART Transmission Complete Interrupt is enabled or disabled. + * @rmtoll CR1 TCIE LL_USART_IsEnabledIT_TC + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TC(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_TCIE) == (USART_CR1_TCIE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART TX Empty Interrupt is enabled or disabled. + * @rmtoll CR1 TXEIE LL_USART_IsEnabledIT_TXE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_TXE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_TXEIE) == (USART_CR1_TXEIE)) ? 1U : 0U); + } + + /** + * @brief Check if the USART Parity Error Interrupt is enabled or disabled. + * @rmtoll CR1 PEIE LL_USART_IsEnabledIT_PE + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_PE(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_PEIE) == (USART_CR1_PEIE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Character Match Interrupt is enabled or disabled. + * @rmtoll CR1 CMIE LL_USART_IsEnabledIT_CM + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CM(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_CMIE) == (USART_CR1_CMIE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART Receiver Timeout Interrupt is enabled or disabled. + * @rmtoll CR1 RTOIE LL_USART_IsEnabledIT_RTO + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_RTO(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_RTOIE) == (USART_CR1_RTOIE)) ? 1UL + : 0UL); + } + +#if defined(USART_SMARTCARD_SUPPORT) + /** + * @brief Check if the USART End Of Block Interrupt is enabled or disabled. + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll CR1 EOBIE LL_USART_IsEnabledIT_EOB + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_EOB(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR1, USART_CR1_EOBIE) == (USART_CR1_EOBIE)) ? 1UL + : 0UL); + } + +#endif /* USART_SMARTCARD_SUPPORT */ +#if defined(USART_LIN_SUPPORT) + /** + * @brief Check if the USART LIN Break Detection Interrupt is enabled or disabled. + * @note Macro IS_UART_LIN_INSTANCE(USARTx) can be used to check whether or not + * LIN feature is supported by the USARTx instance. + * @rmtoll CR2 LBDIE LL_USART_IsEnabledIT_LBD + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_LBD(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR2, USART_CR2_LBDIE) == (USART_CR2_LBDIE)) ? 1UL + : 0UL); + } +#endif /* USART_LIN_SUPPORT */ + + /** + * @brief Check if the USART Error Interrupt is enabled or disabled. + * @rmtoll CR3 EIE LL_USART_IsEnabledIT_ERROR + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_ERROR(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_EIE) == (USART_CR3_EIE)) ? 1UL : 0UL); + } + + /** + * @brief Check if the USART CTS Interrupt is enabled or disabled. + * @note Macro IS_UART_HWFLOW_INSTANCE(USARTx) can be used to check whether or not + * Hardware Flow control feature is supported by the USARTx instance. + * @rmtoll CR3 CTSIE LL_USART_IsEnabledIT_CTS + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_CTS(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_CTSIE) == (USART_CR3_CTSIE)) ? 1UL + : 0UL); + } + +#if defined(USART_CR1_UESM) +#if defined(USART_CR3_WUFIE) + /** + * @brief Check if the USART Wake Up from Stop Mode Interrupt is enabled or disabled. + * @note Macro IS_UART_WAKEUP_FROMSTOP_INSTANCE(USARTx) can be used to check whether + * or not Wake-up from Stop mode feature is supported by the USARTx instance. + * @rmtoll CR3 WUFIE LL_USART_IsEnabledIT_WKUP + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledIT_WKUP(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_WUFIE) == (USART_CR3_WUFIE)) ? 1UL + : 0UL); + } + +#endif /* USART_CR3_WUFIE */ +#endif /* USART_CR1_UESM */ + + /** + * @} + */ + + /** @defgroup USART_LL_EF_DMA_Management DMA_Management + * @{ + */ + + /** + * @brief Enable DMA Mode for reception + * @rmtoll CR3 DMAR LL_USART_EnableDMAReq_RX + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAR); + } + + /** + * @brief Disable DMA Mode for reception + * @rmtoll CR3 DMAR LL_USART_DisableDMAReq_RX + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableDMAReq_RX(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAR); + } + + /** + * @brief Check if DMA Mode is enabled for reception + * @rmtoll CR3 DMAR LL_USART_IsEnabledDMAReq_RX + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_RX(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_DMAR) == (USART_CR3_DMAR)) ? 1UL : 0UL); + } + + /** + * @brief Enable DMA Mode for transmission + * @rmtoll CR3 DMAT LL_USART_EnableDMAReq_TX + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx) + { + ATOMIC_SET_BIT(USARTx->CR3, USART_CR3_DMAT); + } + + /** + * @brief Disable DMA Mode for transmission + * @rmtoll CR3 DMAT LL_USART_DisableDMAReq_TX + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableDMAReq_TX(USART_TypeDef *USARTx) + { + ATOMIC_CLEAR_BIT(USARTx->CR3, USART_CR3_DMAT); + } + + /** + * @brief Check if DMA Mode is enabled for transmission + * @rmtoll CR3 DMAT LL_USART_IsEnabledDMAReq_TX + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t LL_USART_IsEnabledDMAReq_TX(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_DMAT) == (USART_CR3_DMAT)) ? 1UL : 0UL); + } + + /** + * @brief Enable DMA Disabling on Reception Error + * @rmtoll CR3 DDRE LL_USART_EnableDMADeactOnRxErr + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_EnableDMADeactOnRxErr(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->CR3, USART_CR3_DDRE); + } + + /** + * @brief Disable DMA Disabling on Reception Error + * @rmtoll CR3 DDRE LL_USART_DisableDMADeactOnRxErr + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_DisableDMADeactOnRxErr(USART_TypeDef *USARTx) + { + CLEAR_BIT(USARTx->CR3, USART_CR3_DDRE); + } + + /** + * @brief Indicate if DMA Disabling on Reception Error is disabled + * @rmtoll CR3 DDRE LL_USART_IsEnabledDMADeactOnRxErr + * @param USARTx USART Instance + * @retval State of bit (1 or 0). + */ + __STATIC_INLINE uint32_t + LL_USART_IsEnabledDMADeactOnRxErr(const USART_TypeDef *USARTx) + { + return ((READ_BIT(USARTx->CR3, USART_CR3_DDRE) == (USART_CR3_DDRE)) ? 1UL : 0UL); + } + + /** + * @brief Get the data register address used for DMA transfer + * @rmtoll RDR RDR LL_USART_DMA_GetRegAddr\n + * @rmtoll TDR TDR LL_USART_DMA_GetRegAddr + * @param USARTx USART Instance + * @param Direction This parameter can be one of the following values: + * @arg @ref LL_USART_DMA_REG_DATA_TRANSMIT + * @arg @ref LL_USART_DMA_REG_DATA_RECEIVE + * @retval Address of data register + */ + __STATIC_INLINE uint32_t LL_USART_DMA_GetRegAddr(const USART_TypeDef *USARTx, + uint32_t Direction) + { + uint32_t data_reg_addr; + + if (Direction == LL_USART_DMA_REG_DATA_TRANSMIT) + { + /* return address of TDR register */ + data_reg_addr = (uint32_t) & (USARTx->TDR); + } + else + { + /* return address of RDR register */ + data_reg_addr = (uint32_t) & (USARTx->RDR); + } + + return data_reg_addr; + } + + /** + * @} + */ + + /** @defgroup USART_LL_EF_Data_Management Data_Management + * @{ + */ + + /** + * @brief Read Receiver Data register (Receive Data value, 8 bits) + * @rmtoll RDR RDR LL_USART_ReceiveData8 + * @param USARTx USART Instance + * @retval Value between Min_Data=0x00 and Max_Data=0xFF + */ + __STATIC_INLINE uint8_t LL_USART_ReceiveData8(const USART_TypeDef *USARTx) + { + return (uint8_t)(READ_BIT(USARTx->RDR, USART_RDR_RDR) & 0xFFU); + } + + /** + * @brief Read Receiver Data register (Receive Data value, 9 bits) + * @rmtoll RDR RDR LL_USART_ReceiveData9 + * @param USARTx USART Instance + * @retval Value between Min_Data=0x00 and Max_Data=0x1FF + */ + __STATIC_INLINE uint16_t LL_USART_ReceiveData9(const USART_TypeDef *USARTx) + { + return (uint16_t)(READ_BIT(USARTx->RDR, USART_RDR_RDR)); + } + + /** + * @brief Write in Transmitter Data Register (Transmit Data value, 8 bits) + * @rmtoll TDR TDR LL_USART_TransmitData8 + * @param USARTx USART Instance + * @param Value between Min_Data=0x00 and Max_Data=0xFF + * @retval None + */ + __STATIC_INLINE void LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value) + { + USARTx->TDR = Value; + } + + /** + * @brief Write in Transmitter Data Register (Transmit Data value, 9 bits) + * @rmtoll TDR TDR LL_USART_TransmitData9 + * @param USARTx USART Instance + * @param Value between Min_Data=0x00 and Max_Data=0x1FF + * @retval None + */ + __STATIC_INLINE void LL_USART_TransmitData9(USART_TypeDef *USARTx, uint16_t Value) + { + USARTx->TDR = (uint16_t)(Value & 0x1FFUL); + } + + /** + * @} + */ + + /** @defgroup USART_LL_EF_Execution Execution + * @{ + */ + + /** + * @brief Request an Automatic Baud Rate measurement on next received data frame + * @note Macro IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(USARTx) can be used to check + * whether or not Auto Baud Rate detection feature is supported by the USARTx + * instance. + * @rmtoll RQR ABRRQ LL_USART_RequestAutoBaudRate + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_RequestAutoBaudRate(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_ABRRQ); + } + + /** + * @brief Request Break sending + * @rmtoll RQR SBKRQ LL_USART_RequestBreakSending + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_RequestBreakSending(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_SBKRQ); + } + + /** + * @brief Put USART in mute mode and set the RWU flag + * @rmtoll RQR MMRQ LL_USART_RequestEnterMuteMode + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_RequestEnterMuteMode(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_MMRQ); + } + + /** + * @brief Request a Receive Data flush + * @note Allows to discard the received data without reading them, and avoid an + * overrun condition. + * @rmtoll RQR RXFRQ LL_USART_RequestRxDataFlush + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_RequestRxDataFlush(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_RXFRQ); + } + +#if defined(USART_SMARTCARD_SUPPORT) + /** + * @brief Request a Transmit data flush + * @note Macro IS_SMARTCARD_INSTANCE(USARTx) can be used to check whether or not + * Smartcard feature is supported by the USARTx instance. + * @rmtoll RQR TXFRQ LL_USART_RequestTxDataFlush + * @param USARTx USART Instance + * @retval None + */ + __STATIC_INLINE void LL_USART_RequestTxDataFlush(USART_TypeDef *USARTx) + { + SET_BIT(USARTx->RQR, (uint16_t)USART_RQR_TXFRQ); + } +#endif /*USART_SMARTCARD_SUPPORT*/ + + /** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) + /** @defgroup USART_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + ErrorStatus LL_USART_DeInit(const USART_TypeDef *USARTx); + ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, + const LL_USART_InitTypeDef *USART_InitStruct); + void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct); + ErrorStatus LL_USART_ClockInit( + USART_TypeDef *USARTx, const LL_USART_ClockInitTypeDef *USART_ClockInitStruct); + void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + + /** + * @} + */ + + /** + * @} + */ + +#endif /* USART1 || USART2 || USART3 || UART4 || UART5 || USART6 || USART7 || USART8 */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_LL_USART_H */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_utils.c b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_utils.c new file mode 100644 index 0000000000..ca8880fce8 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_utils.c @@ -0,0 +1,630 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_utils.c + * @author MCD Application Team + * @brief UTILS LL module driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_ll_utils.h" + +#include "stm32f0xx_ll_rcc.h" +#include "stm32f0xx_ll_system.h" +#ifdef USE_FULL_ASSERT +#include "stm32_assert.h" +#else +#define assert_param(expr) ((void)0U) +#endif + +/** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +/** @addtogroup UTILS_LL + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup UTILS_LL_Private_Constants + * @{ + */ + +/* Defines used for PLL range */ +#define UTILS_PLL_OUTPUT_MIN 16000000U /*!< Frequency min for PLL output, in Hz */ +#define UTILS_PLL_OUTPUT_MAX 48000000U /*!< Frequency max for PLL output, in Hz */ + +/* Defines used for HSE range */ +#define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */ +#define UTILS_HSE_FREQUENCY_MAX 32000000U /*!< Frequency max for HSE frequency, in Hz */ + +/* Defines used for FLASH latency according to SYSCLK Frequency */ +#define UTILS_LATENCY1_FREQ 24000000U /*!< SYSCLK frequency to set FLASH latency 1 */ +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup UTILS_LL_Private_Macros + * @{ + */ +#define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) \ + (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) || \ + ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) || \ + ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) || \ + ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) || \ + ((__VALUE__) == LL_RCC_SYSCLK_DIV_512)) + +#define IS_LL_UTILS_APB1_DIV(__VALUE__) \ + (((__VALUE__) == LL_RCC_APB1_DIV_1) || ((__VALUE__) == LL_RCC_APB1_DIV_2) || \ + ((__VALUE__) == LL_RCC_APB1_DIV_4) || ((__VALUE__) == LL_RCC_APB1_DIV_8) || \ + ((__VALUE__) == LL_RCC_APB1_DIV_16)) + +#define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) \ + (((__VALUE__) == LL_RCC_PLL_MUL_2) || ((__VALUE__) == LL_RCC_PLL_MUL_3) || \ + ((__VALUE__) == LL_RCC_PLL_MUL_4) || ((__VALUE__) == LL_RCC_PLL_MUL_5) || \ + ((__VALUE__) == LL_RCC_PLL_MUL_6) || ((__VALUE__) == LL_RCC_PLL_MUL_7) || \ + ((__VALUE__) == LL_RCC_PLL_MUL_8) || ((__VALUE__) == LL_RCC_PLL_MUL_9) || \ + ((__VALUE__) == LL_RCC_PLL_MUL_10) || ((__VALUE__) == LL_RCC_PLL_MUL_11) || \ + ((__VALUE__) == LL_RCC_PLL_MUL_12) || ((__VALUE__) == LL_RCC_PLL_MUL_13) || \ + ((__VALUE__) == LL_RCC_PLL_MUL_14) || ((__VALUE__) == LL_RCC_PLL_MUL_15) || \ + ((__VALUE__) == LL_RCC_PLL_MUL_16)) + +#define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) \ + (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2) || \ + ((__VALUE__) == LL_RCC_PREDIV_DIV_3) || ((__VALUE__) == LL_RCC_PREDIV_DIV_4) || \ + ((__VALUE__) == LL_RCC_PREDIV_DIV_5) || ((__VALUE__) == LL_RCC_PREDIV_DIV_6) || \ + ((__VALUE__) == LL_RCC_PREDIV_DIV_7) || ((__VALUE__) == LL_RCC_PREDIV_DIV_8) || \ + ((__VALUE__) == LL_RCC_PREDIV_DIV_9) || ((__VALUE__) == LL_RCC_PREDIV_DIV_10) || \ + ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12) || \ + ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14) || \ + ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16)) + +#define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) \ + ((UTILS_PLL_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX)) + + +#define IS_LL_UTILS_HSE_BYPASS(__STATE__) \ + (((__STATE__) == LL_UTILS_HSEBYPASS_ON) || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF)) + +#define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) \ + (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && \ + ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX)) +/** + * @} + */ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup UTILS_LL_Private_Functions UTILS Private functions + * @{ + */ +static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, + LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct); +static ErrorStatus UTILS_EnablePLLAndSwitchSystem( + uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); +static ErrorStatus UTILS_PLL_IsBusy(void); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup UTILS_LL_Exported_Functions + * @{ + */ + +/** @addtogroup UTILS_LL_EF_DELAY + * @{ + */ + +/** + * @brief This function configures the Cortex-M SysTick source to have 1ms time base. + * @note When a RTOS is used, it is recommended to avoid changing the Systick + * configuration by calling this function, for a delay use rather osDelay RTOS + * service. + * @param HCLKFrequency HCLK frequency in Hz + * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref + * LL_RCC_GetSystemClocksFreq + * @retval None + */ +void LL_Init1msTick(uint32_t HCLKFrequency) +{ + /* Use frequency provided in argument */ + LL_InitTick(HCLKFrequency, 1000U); +} + +/** + * @brief This function provides accurate delay (in milliseconds) based + * on SysTick counter flag + * @note When a RTOS is used, it is recommended to avoid using blocking delay + * and use rather osDelay service. + * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which + * will configure Systick to 1ms + * @param Delay specifies the delay time length, in milliseconds. + * @retval None + */ +void LL_mDelay(uint32_t Delay) +{ + __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */ + /* Add this code to indicate that local variable is not used */ + ((void)tmp); + + /* Add a period to guaranty minimum wait */ + if (Delay < LL_MAX_DELAY) + { + Delay++; + } + + while (Delay) + { + if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U) + { + Delay--; + } + } +} + +/** + * @} + */ + +/** @addtogroup UTILS_EF_SYSTEM + * @brief System Configuration functions + * + @verbatim + =============================================================================== + ##### System Configuration functions ##### + =============================================================================== + [..] + System, AHB and APB buses clocks configuration + + (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 48000000 Hz. + @endverbatim + @internal + Depending on the SYSCLK frequency, the flash latency should be adapted + accordingly: + (++) +-----------------------------------------------+ + (++) | Latency | SYSCLK clock frequency (MHz) | + (++) |---------------|-------------------------------| + (++) |0WS(1CPU cycle)| 0 < SYSCLK <= 24 | + (++) |---------------|-------------------------------| + (++) |1WS(2CPU cycle)| 24 < SYSCLK <= 48 | + (++) +-----------------------------------------------+ + @endinternal + * @{ + */ + +/** + * @brief This function sets directly SystemCoreClock CMSIS variable. + * @note Variable can be calculated also through SystemCoreClockUpdate function. + * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper + * macro) + * @retval None + */ +void LL_SetSystemCoreClock(uint32_t HCLKFrequency) +{ + /* HCLK clock frequency */ + SystemCoreClock = HCLKFrequency; +} + +/** + * @brief Update number of Flash wait states in line with new frequency and current + voltage range. + * @param Frequency SYSCLK frequency + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Latency has been modified + * - ERROR: Latency cannot be modified + */ +#if defined(FLASH_ACR_LATENCY) +ErrorStatus LL_SetFlashLatency(uint32_t Frequency) +{ + uint32_t timeout; + uint32_t getlatency; + uint32_t latency; + ErrorStatus status = SUCCESS; + + /* Frequency cannot be equal to 0 */ + if (Frequency == 0U) + { + status = ERROR; + } + else + { + if (Frequency > UTILS_LATENCY1_FREQ) + { + /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */ + latency = LL_FLASH_LATENCY_1; + } + else + { + /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */ + latency = LL_FLASH_LATENCY_0; + } + LL_FLASH_SetLatency(latency); + + /* Check that the new number of wait states is taken into account to access the + Flash memory by reading the FLASH_ACR register */ + timeout = 2; + do + { + /* Wait for Flash latency to be updated */ + getlatency = LL_FLASH_GetLatency(); + timeout--; + } while ((getlatency != latency) && (timeout > 0)); + + if (getlatency != latency) + { + status = ERROR; + } + else + { + /* No thing to do */ + } + } + + return status; +} +#endif /* FLASH_ACR_LATENCY */ + +/** + * @brief This function configures system clock with HSI as clock source of the PLL + * @note The application need to ensure that PLL is disabled. + * @note Function is based on the following formula: + * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL) + * - PREDIV: Set to 2 for few devices + * - PLLMUL: The application software must set correctly the PLL multiplication + * factor to be in the range 16-48MHz + * @note FLASH latency can be modified through this function. + * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that + * contains the configuration information for the PLL. + * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that + * contains the configuration information for the BUS prescalers. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Max frequency configuration done + * - ERROR: Max frequency configuration not done + */ +ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) +{ + ErrorStatus status = SUCCESS; + uint32_t pllfreq = 0U; + + /* Check if one of the PLL is enabled */ + if (UTILS_PLL_IsBusy() == SUCCESS) + { +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + /* Check PREDIV value */ + assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv)); +#else + /* Force PREDIV value to 2 */ + UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2; +#endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/ + /* Calculate the new PLL output frequency */ + pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct); + + /* Enable HSI if not enabled */ + if (LL_RCC_HSI_IsReady() != 1U) + { + LL_RCC_HSI_Enable(); + while (LL_RCC_HSI_IsReady() != 1U) + { + /* Wait for HSI ready */ + } + } + + /* Configure PLL */ +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, + UTILS_PLLInitStruct->PLLDiv); +#else + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, + UTILS_PLLInitStruct->PLLMul); +#endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/ + + /* Enable PLL and switch system clock to PLL */ + status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); + } + else + { + /* Current PLL configuration cannot be modified */ + status = ERROR; + } + + return status; +} + +#if defined(RCC_CFGR_SW_HSI48) +/** + * @brief This function configures system clock with HSI48 as clock source of the PLL + * @note The application need to ensure that PLL is disabled. + * @note Function is based on the following formula: + * - PLL output frequency = ((HSI48 frequency / PREDIV) * PLLMUL) + * - PLLMUL: The application software must set correctly the PLL multiplication + * factor to be in the range 16-48MHz + * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that + * contains the configuration information for the PLL. + * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that + * contains the configuration information for the BUS prescalers. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Max frequency configuration done + * - ERROR: Max frequency configuration not done + */ +ErrorStatus LL_PLL_ConfigSystemClock_HSI48(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) +{ + ErrorStatus status = SUCCESS; + uint32_t pllfreq = 0U; + + /* Check if one of the PLL is enabled */ + if (UTILS_PLL_IsBusy() == SUCCESS) + { + /* Check PREDIV value */ + assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv)); + + /* Calculate the new PLL output frequency */ + pllfreq = UTILS_GetPLLOutputFrequency(HSI48_VALUE, UTILS_PLLInitStruct); + + /* Enable HSI48 if not enabled */ + if (LL_RCC_HSI48_IsReady() != 1U) + { + LL_RCC_HSI48_Enable(); + while (LL_RCC_HSI48_IsReady() != 1U) + { + /* Wait for HSI48 ready */ + } + } + + /* Configure PLL */ + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI48, UTILS_PLLInitStruct->PLLMul, + UTILS_PLLInitStruct->PLLDiv); + + /* Enable PLL and switch system clock to PLL */ + status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); + } + else + { + /* Current PLL configuration cannot be modified */ + status = ERROR; + } + + return status; +} + +#endif /*RCC_CFGR_SW_HSI48*/ +/** + * @brief This function configures system clock with HSE as clock source of the PLL + * @note The application need to ensure that PLL is disabled. + * @note Function is based on the following formula: + * - PLL output frequency = ((HSE frequency / PREDIV) * PLLMUL) + * - PLLMUL: The application software must set correctly the PLL multiplication + * factor to be in the range 16-48MHz + * @note FLASH latency can be modified through this function. + * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 32000000 + * @param HSEBypass This parameter can be one of the following values: + * @arg @ref LL_UTILS_HSEBYPASS_ON + * @arg @ref LL_UTILS_HSEBYPASS_OFF + * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that + * contains the configuration information for the PLL. + * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that + * contains the configuration information for the BUS prescalers. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: Max frequency configuration done + * - ERROR: Max frequency configuration not done + */ +ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass, + LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) +{ + ErrorStatus status = SUCCESS; + uint32_t pllfreq = 0U; + + /* Check the parameters */ + assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency)); + assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass)); + + /* Check if one of the PLL is enabled */ + if (UTILS_PLL_IsBusy() == SUCCESS) + { + /* Check PREDIV value */ +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv)); +#else + assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv)); +#endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/ + + /* Calculate the new PLL output frequency */ + pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct); + + /* Enable HSE if not enabled */ + if (LL_RCC_HSE_IsReady() != 1U) + { + /* Check if need to enable HSE bypass feature or not */ + if (HSEBypass == LL_UTILS_HSEBYPASS_ON) + { + LL_RCC_HSE_EnableBypass(); + } + else + { + LL_RCC_HSE_DisableBypass(); + } + + /* Enable HSE */ + LL_RCC_HSE_Enable(); + while (LL_RCC_HSE_IsReady() != 1U) + { + /* Wait for HSE ready */ + } + } + + /* Configure PLL */ +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, + UTILS_PLLInitStruct->PLLDiv); +#else + LL_RCC_PLL_ConfigDomain_SYS( + (RCC_CFGR_PLLSRC_HSE_PREDIV | UTILS_PLLInitStruct->Prediv), + UTILS_PLLInitStruct->PLLMul); +#endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/ + + /* Enable PLL and switch system clock to PLL */ + status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); + } + else + { + /* Current PLL configuration cannot be modified */ + status = ERROR; + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup UTILS_LL_Private_Functions + * @{ + */ +/** + * @brief Function to check that PLL can be modified + * @param PLL_InputFrequency PLL input frequency (in Hz) + * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that + * contains the configuration information for the PLL. + * @retval PLL output frequency (in Hz) + */ +static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, + LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct) +{ + uint32_t pllfreq = 0U; + + /* Check the parameters */ + assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul)); + + /* Check different PLL parameters according to RM */ + /* The application software must set correctly the PLL multiplication factor to + be in the range 16-48MHz */ +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency, UTILS_PLLInitStruct->PLLMul, + UTILS_PLLInitStruct->PLLDiv); +#else + pllfreq = + __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), + UTILS_PLLInitStruct->PLLMul); +#endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/ + assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq)); + + return pllfreq; +} + +/** + * @brief Function to check that PLL can be modified + * @retval An ErrorStatus enumeration value: + * - SUCCESS: PLL modification can be done + * - ERROR: PLL is busy + */ +static ErrorStatus UTILS_PLL_IsBusy(void) +{ + ErrorStatus status = SUCCESS; + + /* Check if PLL is busy*/ + if (LL_RCC_PLL_IsReady() != 0U) + { + /* PLL configuration cannot be modified */ + status = ERROR; + } + + return status; +} + +/** + * @brief Function to enable PLL and switch system clock to PLL + * @param SYSCLK_Frequency SYSCLK frequency + * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that + * contains the configuration information for the BUS prescalers. + * @retval An ErrorStatus enumeration value: + * - SUCCESS: No problem to switch system to PLL + * - ERROR: Problem to switch system to PLL + */ +static ErrorStatus UTILS_EnablePLLAndSwitchSystem( + uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) +{ + ErrorStatus status = SUCCESS; + uint32_t sysclk_frequency_current = 0U; + + assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider)); + assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider)); + + /* Calculate current SYSCLK frequency */ + sysclk_frequency_current = + (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_POSITION_HPRE]); + + /* Increasing the number of wait states because of higher CPU frequency */ + if (sysclk_frequency_current < SYSCLK_Frequency) + { + /* Set FLASH latency to highest latency */ + status = LL_SetFlashLatency(SYSCLK_Frequency); + } + + /* Update system clock configuration */ + if (status == SUCCESS) + { + /* Enable PLL */ + LL_RCC_PLL_Enable(); + while (LL_RCC_PLL_IsReady() != 1U) + { + /* Wait for PLL ready */ + } + + /* Sysclk activation on the main PLL */ + LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider); + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) + { + /* Wait for system clock switch to PLL */ + } + + /* Set APB1 & APB2 prescaler*/ + LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider); + } + + /* Decreasing the number of wait states because of lower CPU frequency */ + if (sysclk_frequency_current > SYSCLK_Frequency) + { + /* Set FLASH latency to lowest latency */ + status = LL_SetFlashLatency(SYSCLK_Frequency); + } + + /* Update SystemCoreClock variable */ + if (status == SUCCESS) + { + LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ( + SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider)); + } + + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx/stm32f0xx_ll_utils.h b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_utils.h new file mode 100644 index 0000000000..d374505d3e --- /dev/null +++ b/src/firmware/motor/stm32f0xx/stm32f0xx_ll_utils.h @@ -0,0 +1,287 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_utils.h + * @author MCD Application Team + * @brief Header file of UTILS LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The LL UTILS driver contains a set of generic APIs that can be + used by user: + (+) Device electronic signature + (+) Timing functions + (+) PLL configuration functions + + @endverbatim + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_LL_UTILS_H +#define __STM32F0xx_LL_UTILS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" + +/** @addtogroup STM32F0xx_LL_Driver + * @{ + */ + +/** @defgroup UTILS_LL UTILS + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup UTILS_LL_Private_Constants UTILS Private Constants + * @{ + */ + +/* Max delay can be used in LL_mDelay */ +#define LL_MAX_DELAY 0xFFFFFFFFU + +/** + * @brief Unique device ID register base address + */ +#define UID_BASE_ADDRESS UID_BASE + +/** + * @brief Flash size data register base address + */ +#define FLASHSIZE_BASE_ADDRESS FLASHSIZE_BASE + + /** + * @} + */ + + /* Private macros ------------------------------------------------------------*/ + /** @defgroup UTILS_LL_Private_Macros UTILS Private Macros + * @{ + */ + /** + * @} + */ + /* Exported types ------------------------------------------------------------*/ + /** @defgroup UTILS_LL_ES_INIT UTILS Exported structures + * @{ + */ + /** + * @brief UTILS PLL structure definition + */ + typedef struct + { + uint32_t + PLLMul; /*!< Multiplication factor for PLL VCO input clock. + This parameter can be a value of @ref RCC_LL_EC_PLL_MUL + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL_ConfigDomain_SYS(). */ + +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + uint32_t + PLLDiv; /*!< Division factor for PLL VCO output clock. + This parameter can be a value of @ref RCC_LL_EC_PREDIV_DIV + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL_ConfigDomain_SYS(). */ +#else + uint32_t Prediv; /*!< Division factor for HSE used as PLL clock source. + This parameter can be a value of @ref RCC_LL_EC_PREDIV_DIV + + This feature can be modified afterwards using unitary function + @ref LL_RCC_PLL_ConfigDomain_SYS(). */ +#endif /* RCC_PLLSRC_PREDIV1_SUPPORT */ + } LL_UTILS_PLLInitTypeDef; + + /** + * @brief UTILS System, AHB and APB buses clock configuration structure definition + */ + typedef struct + { + uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived + from the system clock (SYSCLK). This parameter can be a + value of @ref RCC_LL_EC_SYSCLK_DIV + + This feature can be modified afterwards using unitary + function + @ref LL_RCC_SetAHBPrescaler(). */ + + uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is + derived from the AHB clock (HCLK). This parameter can + be a value of @ref RCC_LL_EC_APB1_DIV + + This feature can be modified afterwards using + unitary function + @ref LL_RCC_SetAPB1Prescaler(). */ + } LL_UTILS_ClkInitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UTILS_LL_Exported_Constants UTILS Exported Constants + * @{ + */ + +/** @defgroup UTILS_EC_HSE_BYPASS HSE Bypass activation + * @{ + */ +#define LL_UTILS_HSEBYPASS_OFF \ + 0x00000000U /*!< HSE Bypass is not enabled */ +#define LL_UTILS_HSEBYPASS_ON 0x00000001U /*!< HSE Bypass is enabled */ + /** + * @} + */ + + /** + * @} + */ + + /* Exported macro ------------------------------------------------------------*/ + + /* Exported functions --------------------------------------------------------*/ + /** @defgroup UTILS_LL_Exported_Functions UTILS Exported Functions + * @{ + */ + + /** @defgroup UTILS_EF_DEVICE_ELECTRONIC_SIGNATURE DEVICE ELECTRONIC SIGNATURE + * @{ + */ + + /** + * @brief Get Word0 of the unique device identifier (UID based on 96 bits) + * @retval UID[31:0]: X and Y coordinates on the wafer expressed in BCD format + */ + __STATIC_INLINE uint32_t LL_GetUID_Word0(void) + { + return (uint32_t)(READ_REG(*((uint32_t *)UID_BASE_ADDRESS))); + } + + /** + * @brief Get Word1 of the unique device identifier (UID based on 96 bits) + * @retval UID[63:32]: Wafer number (UID[39:32]) & LOT_NUM[23:0] (UID[63:40]) + */ + __STATIC_INLINE uint32_t LL_GetUID_Word1(void) + { + return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 4U)))); + } + + /** + * @brief Get Word2 of the unique device identifier (UID based on 96 bits) + * @retval UID[95:64]: Lot number (ASCII encoded) - LOT_NUM[55:24] + */ + __STATIC_INLINE uint32_t LL_GetUID_Word2(void) + { + return (uint32_t)(READ_REG(*((uint32_t *)(UID_BASE_ADDRESS + 8U)))); + } + + /** + * @brief Get Flash memory size + * @note This bitfield indicates the size of the device Flash memory expressed in + * Kbytes. As an example, 0x040 corresponds to 64 Kbytes. + * @retval FLASH_SIZE[15:0]: Flash memory size + */ + __STATIC_INLINE uint32_t LL_GetFlashSize(void) + { + return (uint16_t)(READ_REG(*((uint32_t *)FLASHSIZE_BASE_ADDRESS))); + } + + + /** + * @} + */ + + /** @defgroup UTILS_LL_EF_DELAY DELAY + * @{ + */ + + /** + * @brief This function configures the Cortex-M SysTick source of the time base. + * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper + * macro) + * @note When a RTOS is used, it is recommended to avoid changing the SysTick + * configuration by calling this function, for a delay use rather osDelay RTOS + * service. + * @param Ticks Frequency of Ticks (Hz) + * @retval None + */ + __STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks) + { + /* Configure the SysTick to have interrupt in 1ms time base */ + SysTick->LOAD = + (uint32_t)((HCLKFrequency / Ticks) - 1UL); /* set reload register */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */ + } + + void LL_Init1msTick(uint32_t HCLKFrequency); + void LL_mDelay(uint32_t Delay); + + /** + * @} + */ + + /** @defgroup UTILS_EF_SYSTEM SYSTEM + * @{ + */ + + void LL_SetSystemCoreClock(uint32_t HCLKFrequency); +#if defined(FLASH_ACR_LATENCY) + ErrorStatus LL_SetFlashLatency(uint32_t Frequency); +#endif /* FLASH_ACR_LATENCY */ + ErrorStatus LL_PLL_ConfigSystemClock_HSI( + LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); +#if defined(RCC_CFGR_SW_HSI48) + ErrorStatus LL_PLL_ConfigSystemClock_HSI48( + LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); +#endif /*RCC_CFGR_SW_HSI48*/ + ErrorStatus LL_PLL_ConfigSystemClock_HSE( + uint32_t HSEFrequency, uint32_t HSEBypass, + LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, + LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_LL_UTILS_H */ diff --git a/src/firmware/motor/stm32f0xx/system_stm32f0xx.c b/src/firmware/motor/stm32f0xx/system_stm32f0xx.c new file mode 100644 index 0000000000..5e0cc92169 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/system_stm32f0xx.c @@ -0,0 +1,260 @@ +/** + ****************************************************************************** + * @file system_stm32f0xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f0xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f0xx_system + * @{ + */ + +/** @addtogroup STM32F0xx_System_Private_Includes + * @{ + */ + +#include "firmware/motor/stm32f0xx/stm32f0xx.h" + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Defines + * @{ + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE \ + ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. \ + This value can be provided and adapted by the user \ + application. */ +#endif /* HSE_VALUE */ + +#if !defined(HSI_VALUE) +#define HSI_VALUE \ + ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz. \ + This value can be provided and adapted by the user \ + application. */ +#endif /* HSI_VALUE */ + +#if !defined(HSI48_VALUE) +#define HSI48_VALUE \ + ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz. \ + This value can be provided and adapted by the user \ + application. */ +#endif /* HSI48_VALUE */ +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Variables + * @{ + */ +/* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. +*/ +uint32_t SystemCoreClock = 8000000; + +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* NOTE :SystemInit(): This function is called at startup just after reset and + before branch to main program. This call is made inside + the "startup_stm32f0xx.s" file. + User can setups the default system clock (System clock source, + PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings). + */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * - If SYSCLK source is HSI48, SystemCoreClock will contain the + * HSI48_VALUE(***) + * + * (*) HSI_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value + * 8 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (its value + * depends on the application requirements), user has to ensure that + * HSE_VALUE is same as the real frequency of the crystal used. Otherwise, this function + * may have wrong result. + * + * (***) HSI48_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default + * value 48 MHz) but the real value may vary depending on the variations in voltage and + * temperature. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case RCC_CFGR_SWS_HSI: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + case RCC_CFGR_SWS_HSE: /* HSE used as system clock */ + SystemCoreClock = HSE_VALUE; + break; + case RCC_CFGR_SWS_PLL: /* PLL used as system clock */ + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmull = RCC->CFGR & RCC_CFGR_PLLMUL; + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + pllmull = (pllmull >> 18) + 2; + predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1; + + if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV) + { + /* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */ + SystemCoreClock = (HSE_VALUE / predivfactor) * pllmull; + } +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F071xB) || \ + defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || \ + defined(STM32F098xx) + else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV) + { + /* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * + * PLLMUL */ + SystemCoreClock = (HSI48_VALUE / predivfactor) * pllmull; + } +#endif /* STM32F042x6 || STM32F048xx || STM32F071xB || STM32F072xB || STM32F078xx || \ + STM32F091xC || STM32F098xx */ + else + { +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || \ + defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) || \ + defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || \ + defined(STM32F030xC) + /* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */ + SystemCoreClock = (HSI_VALUE / predivfactor) * pllmull; +#else + /* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */ + SystemCoreClock = (HSI_VALUE >> 1) * pllmull; +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || \ + STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || \ + STM32F091xC || STM32F098xx || STM32F030xC */ + } + break; + default: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK clock frequency ----------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx/system_stm32f0xx.h b/src/firmware/motor/stm32f0xx/system_stm32f0xx.h new file mode 100644 index 0000000000..e9ac564e26 --- /dev/null +++ b/src/firmware/motor/stm32f0xx/system_stm32f0xx.h @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * @file system_stm32f0xx.h + * @author MCD Application Team + * @brief CMSIS Cortex-M0 Device System Source File for STM32F0xx devices. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f0xx_system + * @{ + */ + +/** + * @brief Define to prevent recursive inclusion + */ +#ifndef __SYSTEM_STM32F0XX_H +#define __SYSTEM_STM32F0XX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** @addtogroup STM32F0xx_System_Includes + * @{ + */ + + /** + * @} + */ + + + /** @addtogroup STM32F0xx_System_Exported_types + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 3) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) by calling HAL API function HAL_RCC_ClockConfig() + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since + SystemCoreClock variable is updated automatically. + */ + extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ + extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ + + /** + * @} + */ + + /** @addtogroup STM32F0xx_System_Exported_Constants + * @{ + */ + + /** + * @} + */ + + /** @addtogroup STM32F0xx_System_Exported_Macros + * @{ + */ + + /** + * @} + */ + + /** @addtogroup STM32F0xx_System_Exported_Functions + * @{ + */ + + extern void SystemInit(void); + extern void SystemCoreClockUpdate(void); + /** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__SYSTEM_STM32F0XX_H */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/src/firmware/motor/stm32f0xx_hal_msp.c b/src/firmware/motor/stm32f0xx_hal_msp.c new file mode 100644 index 0000000000..f587e7ee64 --- /dev/null +++ b/src/firmware/motor/stm32f0xx_hal_msp.c @@ -0,0 +1,143 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/main.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_hal_spi.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/* USER CODE BEGIN 1 */ + +void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + if (hspi->Instance == SPI1) + { + __HAL_RCC_SPI1_CLK_ENABLE(); + + // clocks or something + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + /**SPI1 GPIO Configuration + PA15 ------> SPI1_NSS + PB3 ------> SPI1_SCK -> NEEDS TO BECOME MISO + PB4 ------> SPI1_MISO -> NEEDS TO BE MOSI + PB5 ------> SPI1_MOSI -> NEEDS TO BE CLK + */ + + GPIO_InitStruct.Pin = GPIO_PIN_15; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF0_SPI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF0_SPI1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } +} + +/** + * @brief SPI MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hspi: SPI handle pointer + * @retval None + */ +void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) +{ + if (hspi->Instance == SPI1) + { + // turn off clock + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PA15 ------> SPI1_NSS + PB3 ------> SPI1_SCK + PB4 ------> SPI1_MISO + PB5 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5); + } +} + +/* USER CODE END 1 */ diff --git a/src/firmware/motor/stm32f0xx_it.c b/src/firmware/motor/stm32f0xx_it.c new file mode 100644 index 0000000000..b6702ca44b --- /dev/null +++ b/src/firmware/motor/stm32f0xx_it.c @@ -0,0 +1,104 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/stm32f0xx_it.h" + +#include "firmware/motor/main.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M0 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) + { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32F0xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32f0xx.s). */ +/******************************************************************************/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/src/firmware/motor/stm32f0xx_it.h b/src/firmware/motor/stm32f0xx_it.h new file mode 100644 index 0000000000..db6e5ed3bb --- /dev/null +++ b/src/firmware/motor/stm32f0xx_it.h @@ -0,0 +1,60 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_IT_H +#define __STM32F0xx_IT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Private includes ----------------------------------------------------------*/ + /* USER CODE BEGIN Includes */ + + /* USER CODE END Includes */ + + /* Exported types ------------------------------------------------------------*/ + /* USER CODE BEGIN ET */ + + /* USER CODE END ET */ + + /* Exported constants --------------------------------------------------------*/ + /* USER CODE BEGIN EC */ + + /* USER CODE END EC */ + + /* Exported macro ------------------------------------------------------------*/ + /* USER CODE BEGIN EM */ + + /* USER CODE END EM */ + + /* Exported functions prototypes ---------------------------------------------*/ + void NMI_Handler(void); + void PendSV_Handler(void); + /* USER CODE BEGIN EFP */ + + /* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_IT_H */ diff --git a/src/firmware/motor/stm32f0xx_mc_it.c b/src/firmware/motor/stm32f0xx_mc_it.c new file mode 100644 index 0000000000..115e204f9b --- /dev/null +++ b/src/firmware/motor/stm32f0xx_mc_it.c @@ -0,0 +1,214 @@ + +/** + ****************************************************************************** + * @file stm32f0xx_mc_it.c + * @author Motor Control SDK Team, ST Microelectronics + * @brief Main Interrupt Service Routines. + * This file provides exceptions handler and peripherals interrupt + * service routine related to Motor Control for the STM32F0 Family. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2024 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + * @ingroup STM32F0xx_IRQ_Handlers + */ + +/* Includes ------------------------------------------------------------------*/ +#include "firmware/motor/mc_config.h" +#include "firmware/motor/mc_tasks.h" +#include "firmware/motor/mcsdk/mc_type.h" +#include "firmware/motor/motorcontrol.h" +#include "firmware/motor/parameters_conversion.h" +#include "firmware/motor/stm32f0xx/stm32f0xx.h" +#include "firmware/motor/stm32f0xx/stm32f0xx_hal.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/** @addtogroup MCSDK + * @{ + */ + +/** @addtogroup STM32F0xx_IRQ_Handlers STM32F0xx IRQ Handlers + * @{ + */ + +/* USER CODE BEGIN PRIVATE */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/* USER CODE END PRIVATE */ + +/* Public prototypes of IRQ handlers called from assembly code ---------------*/ +void CURRENT_REGULATION_IRQHandler(void); +void DMAx_R1_M1_IRQHandler(void); +void TIMx_UP_BRK_M1_IRQHandler(void); +void SPD_TIM_M1_IRQHandler(void); + +/** + * @brief This function handles current regulation interrupt request. + * @param None + */ +void CURRENT_REGULATION_IRQHandler(void) +{ + /* USER CODE BEGIN CURRENT_REGULATION_IRQn 0 */ + + /* USER CODE END CURRENT_REGULATION_IRQn 0 */ + + /* Clear Flags */ + DMA1->IFCR = (LL_DMA_ISR_GIF1 | LL_DMA_ISR_TCIF1 | LL_DMA_ISR_HTIF1); + + /* USER CODE BEGIN CURRENT_REGULATION_IRQn 1 */ + + /* USER CODE END CURRENT_REGULATION_IRQn 1 */ + TSK_HighFrequencyTask(); + + /* USER CODE BEGIN CURRENT_REGULATION_IRQn 2 */ + + /* USER CODE END CURRENT_REGULATION_IRQn 2 */ +} + +/** + * @brief This function handles first motor TIMx Update, Break-in interrupt request. + * @param None + */ +void TIMx_UP_BRK_M1_IRQHandler(void) +{ + /* USER CODE BEGIN TIMx_UP_BRK_M1_IRQn 0 */ + + /* USER CODE END TIMx_UP_BRK_M1_IRQn 0 */ + + if (LL_TIM_IsActiveFlag_UPDATE(TIM1) && LL_TIM_IsEnabledIT_UPDATE(TIM1)) + { + R1_TIM1_UP_IRQHandler(&PWM_Handle_M1); + LL_TIM_ClearFlag_UPDATE(TIM1); + + /* USER CODE BEGIN PWM_Update */ + + /* USER CODE END PWM_Update */ + } + else + { + /* Nothing to do */ + } + + if (LL_TIM_IsActiveFlag_BRK(TIM1) && LL_TIM_IsEnabledIT_BRK(TIM1)) + { + LL_TIM_ClearFlag_BRK(TIM1); + PWMC_OCP_Handler(&PWM_Handle_M1._Super); + + /* USER CODE BEGIN Break */ + + /* USER CODE END Break */ + } + else + { + /* No other interrupts are routed to this handler */ + } + + /* USER CODE BEGIN TIMx_UP_BRK_M1_IRQn 1 */ + + /* USER CODE END TIMx_UP_BRK_M1_IRQn 1 */ +} + +/** + * @brief This function handles first motor DMAx TC interrupt request. + * Required only for R1 with rep rate > 1 + * @param None + */ +void DMAx_R1_M1_IRQHandler(void) +{ + /* USER CODE BEGIN DMAx_R1_M1_IRQn 0 */ + + /* USER CODE END DMAx_R1_M1_IRQn 0 */ + + if (LL_DMA_IsActiveFlag_TC5(DMA1)) + { + LL_DMA_ClearFlag_TC5(DMA1); + R1_DMAx_TC_IRQHandler(&PWM_Handle_M1); + /* USER CODE BEGIN DMAx_R1_M1_TC5 */ + + /* USER CODE END DMAx_R1_M1_TC5 */ + } + else + { + /* Nothing to do */ + } + + /* USER CODE BEGIN DMAx_R1_M1_IRQn 1 */ + + /* USER CODE END DMAx_R1_M1_IRQn 1 */ +} + +/** + * @brief This function handles TIMx global interrupt request for M1 Speed Sensor. + * @param None + */ +void SPD_TIM_M1_IRQHandler(void) +{ + /* USER CODE BEGIN SPD_TIM_M1_IRQn 0 */ + + /* USER CODE END SPD_TIM_M1_IRQn 0 */ + + /* HALL Timer Update IT always enabled, no need to check enable UPDATE state */ + if (LL_TIM_IsActiveFlag_UPDATE(HALL_M1.TIMx) != 0) + { + LL_TIM_ClearFlag_UPDATE(HALL_M1.TIMx); + HALL_TIMx_UP_IRQHandler(&HALL_M1); + + /* USER CODE BEGIN HALL_Update */ + + /* USER CODE END HALL_Update */ + } + else + { + /* Nothing to do */ + } + + /* HALL Timer CC1 IT always enabled, no need to check enable CC1 state */ + if (LL_TIM_IsActiveFlag_CC1(HALL_M1.TIMx)) + { + LL_TIM_ClearFlag_CC1(HALL_M1.TIMx); + HALL_TIMx_CC_IRQHandler(&HALL_M1); + + /* USER CODE BEGIN HALL_CC1 */ + + /* USER CODE END HALL_CC1 */ + } + else + { + /* Nothing to do */ + } + + /* USER CODE BEGIN SPD_TIM_M1_IRQn 1 */ + + /* USER CODE END SPD_TIM_M1_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT 2024 STMicroelectronics *****END OF FILE****/ diff --git a/src/firmware/motor/types.h b/src/firmware/motor/types.h new file mode 100644 index 0000000000..b0216fd6a1 --- /dev/null +++ b/src/firmware/motor/types.h @@ -0,0 +1,57 @@ +#ifndef __COMMON_TYPES +#define __COMMON_TYPES + +#define OPCODE_VALUES \ + DEF_VALUE(SPI_NOOP, 0b00000000) \ + DEF_VALUE(MOV_AX, 0b10000010) \ + DEF_VALUE(GET_AX, 0b10000011) \ + DEF_VALUE(MOV_BX, 0b10000100) \ + DEF_VALUE(GET_BX, 0b10000101) \ + DEF_VALUE(SET_SPEEDRAMP, 0b00000010) \ + DEF_VALUE(GET_SPEED, 0b00000011) \ + DEF_VALUE(SET_ENCODER, 0b00000100) \ + DEF_VALUE(GET_ENCODER, 0b00000101) \ + DEF_VALUE(START_MOTOR, 0b00001000) \ + DEF_VALUE(STOP_MOTOR, 0b11111111) \ + DEF_VALUE(ACK_FAULTS, 0b00010000) \ + DEF_VALUE(GET_FAULT, 0b00010001) \ + DEF_VALUE(SET_CURRENT, 0b00100000) \ + DEF_VALUE(GET_CURRENT, 0b00100001) \ + DEF_VALUE(ACK, 0b11000000) \ + DEF_VALUE(NACK, 0b11000001) \ + DEF_VALUE(SPI_ERROR, 0b11100000) + +#define DEF_VALUE(a, b) a = b, +enum OPCODES +{ + OPCODE_VALUES +}; +#undef DEF_VALUE + +/** + * For documentation on fault codes, visit ST MC SDK v6.2.0 documentation page + * /group___m_c___type.html#fault_codes + */ +enum FAULT_CODES +{ + NO_FAULT = 0x0000, + DURATION = 0x0001, + OVER_VOLT = 0x0002, + UNDER_VOLT = 0x0004, + OVER_TEMP = 0x0008, + START_UP = 0x0010, + SPEED_FDBK = 0x0020, + OVER_CURR = 0x0040, + SW_ERROR = 0x0080, + SAMPLE_FAULT = 0x0100, + OVERCURR_SW = 0x0200, + DP_FAULT = 0x0400, +}; + +enum FRAME_PARTS +{ + FRAME_SOF = 0x73, + FRAME_EOF = 0x45, +}; + +#endif diff --git a/src/starlark/defs.bzl b/src/starlark/defs.bzl index afaca57dc5..55f4dd072a 100644 --- a/src/starlark/defs.bzl +++ b/src/starlark/defs.bzl @@ -1,3 +1,4 @@ +load("@bazel_embedded//tools/openocd:openocd_repository.bzl", "openocd_deps") load("@rules_pkg//pkg:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo", "PackageSymlinkInfo") # =================================================================== @@ -97,3 +98,10 @@ pkg_executable = rule( }, provides = [PackageFilegroupInfo], ) + +def _openocd_extension_impl(_ctx): + openocd_deps() + +openocd_extension = module_extension( + implementation = _openocd_extension_impl, +) diff --git a/src/toolchains/cc/BUILD b/src/toolchains/cc/BUILD index 6d8c51dc29..352c3ab88c 100644 --- a/src/toolchains/cc/BUILD +++ b/src/toolchains/cc/BUILD @@ -2,6 +2,7 @@ load( ":cc_toolchain_config.bzl", "cc_toolchain_config_fullsystem", "cc_toolchain_config_k8_jetson_nano_cross_compile", + "cc_toolchain_config_stm32", "make_builtin_include_directories", ) @@ -60,6 +61,14 @@ platform( ], ) +platform( + name = "motor_board", + constraint_values = [ + "@platforms//cpu:armv6-m", + "@platforms//os:none", + ], +) + # This represents a mapping of CPU -> Compiler To Use cc_toolchain_suite( name = "toolchain", @@ -115,6 +124,13 @@ filegroup( ], ) +filegroup( + name = "motor_board_gcc_all", + srcs = [ + "@motor_board_gcc//:includes", + ], +) + cc_toolchain_config_fullsystem( name = "linux_k8_gcc", builtin_include_directories = [ @@ -195,6 +211,39 @@ cc_toolchain( toolchain_identifier = "gcc-k8-jetson-nano-cross-compile", ) +cc_toolchain_config_stm32( + name = "gcc-arm-none-abi", + builtin_include_directories = [ + "/opt/tbotspython/arm-none-eabi-gcc/arm-none-eabi/include/", + "/opt/tbotspython/arm-none-eabi-gcc/lib/gcc/arm-none-eabi/14.3.1/include/", + ], + tool_paths = { + "ar": "/opt/tbotspython/arm-none-eabi-gcc/bin/arm-none-eabi-ar", + "gcc": "/opt/tbotspython/arm-none-eabi-gcc/bin/arm-none-eabi-gcc", + "cpp": "/opt/tbotspython/arm-none-eabi-gcc/bin/arm-none-eabi-cpp", + "ld": "/opt/tbotspython/arm-none-eabi-gcc/bin/arm-none-eabi-ld", + "nm": "/opt/tbotspython/arm-none-eabi-gcc/bin/arm-none-eabi-nm", + "objdump": "/opt/tbotspython/arm-none-eabi-gcc/bin/arm-none-eabi-objdump", + "strip": "/opt/tbotspython/arm-none-eabi-gcc/bin/arm-none-eabi-strip", + }, + toolchain_identifier = "gcc-stm32", +) + +cc_toolchain( + name = "cc_toolchain_stm32", + all_files = ":motor_board_gcc_all", + ar_files = ":motor_board_gcc_all", + as_files = ":motor_board_gcc_all", + compiler_files = ":motor_board_gcc_all", + dwp_files = ":motor_board_gcc_all", + linker_files = ":motor_board_gcc_all", + objcopy_files = ":motor_board_gcc_all", + strip_files = ":motor_board_gcc_all", + supports_param_files = True, + toolchain_config = ":gcc-arm-none-abi", + toolchain_identifier = "stm32_gcc", +) + cc_toolchain_config_k8_jetson_nano_cross_compile( name = "gcc_k8_jetson_nano_cross_compile", builtin_include_directories = [ @@ -256,3 +305,13 @@ toolchain( toolchain = ":cc_toolchain_linux_aarch64_gcc", toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) + +toolchain( + name = "cc_toolchain_for_stm32", + target_compatible_with = [ + "@platforms//cpu:armv6-m", + "@platforms//os:none", + ], + toolchain = ":cc_toolchain_stm32", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) diff --git a/src/toolchains/cc/cc_toolchain_config.bzl b/src/toolchains/cc/cc_toolchain_config.bzl index 3dc7536544..0dddadd8da 100644 --- a/src/toolchains/cc/cc_toolchain_config.bzl +++ b/src/toolchains/cc/cc_toolchain_config.bzl @@ -84,7 +84,6 @@ ALL_COMPILE_ACTIONS = [ ACTION_NAMES.preprocess_assemble, ACTION_NAMES.lto_indexing, ACTION_NAMES.lto_backend, - ACTION_NAMES.strip, ACTION_NAMES.clif_match, ] @@ -614,6 +613,183 @@ cc_toolchain_config_fullsystem = rule( executable = True, ) +def _stm32_gcc_impl(ctx): + cortex_feature = feature( + name = "cortex_cpu", + enabled = True, + flag_sets = [ + flag_set( + actions = ALL_COMPILE_ACTIONS + ALL_LINK_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + # Compile for the Cortex M0 + "-mcpu=cortex-m0", + ], + ), + ], + ), + ], + ) + + space_optimization_feature = feature( + name = "space_optimization", + # Optimize for space, otherwise we'll likely overflow RAM and/or stack + enabled = True, + flag_sets = [ + flag_set( + actions = ALL_COMPILE_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + # Optimize for size + "-Os", + # Places each function into its own section. If coupled with --gc-sections in the linker + # stage, this option strips out unused functions and reduces code size. + "-ffunction-sections", + ], + ), + ], + ), + flag_set( + actions = ALL_LINK_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + # Garbage collects unused sections of code. Used with the compiler's -ffunction-sections, + # this option will completely strip out unused functions out of the created binary. + "-Wl,--gc-sections", + ], + ), + ], + ), + ], + ) + + no_syscalls_feature = feature( + name = "no_syscalls", + enabled = True, + flag_sets = [ + flag_set( + actions = ALL_LINK_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + # No OS, so stub out the system calls + "--specs=nosys.specs", + ], + ), + ], + ), + ], + ) + + map_file_feature = feature( + name = "map_file", + flag_sets = [ + flag_set( + actions = ALL_LINK_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + # Generate a map file with the cross-reference table. This is very helpful to figure out + # what functions are taking the most space in RAM and flash and who calls them. + "-Wl,-Map=output.map,--cref", + ], + ), + ], + ), + ], + ) + + bare_metal_feature = feature( + name = "bare_metal", + enabled = True, + flag_sets = [ + flag_set( + actions = ALL_COMPILE_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + # Tells the compiler that the target platform may not have an operating system, which + # allows it to make some performance and size optimizations. + "-ffreestanding", + ], + ), + ], + ), + ], + ) + + memory_usage_feature = feature( + name = "memory_usage", + enabled = True, + flag_sets = [ + flag_set( + actions = ALL_LINK_ACTIONS, + flag_groups = [ + flag_group( + flags = [ + # Print remaining FLASH and RAM available. + "-Wl,--print-memory-usage", + ], + ), + ], + ), + ], + ) + + features = [ + cortex_feature, + map_file_feature, + no_syscalls_feature, + space_optimization_feature, + bare_metal_feature, + memory_usage_feature, + ] + + return [ + cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = [], + artifact_name_patterns = [], + cxx_builtin_include_directories = ctx.attr.builtin_include_directories, + toolchain_identifier = ctx.attr.toolchain_identifier, + host_system_name = ctx.attr.host_system_name, + target_system_name = ctx.attr.target_system_name, + target_cpu = ctx.attr.target_cpu, + target_libc = "libc", + compiler = "gcc", + abi_version = "unknown", + abi_libc_version = "unknown", + tool_paths = [ + tool_path(name = name, path = path) + for name, path in ctx.attr.tool_paths.items() + ], + make_variables = [], + builtin_sysroot = None, + cc_target_os = None, + ), + ] + +cc_toolchain_config_stm32 = rule( + implementation = _stm32_gcc_impl, + attrs = { + "builtin_include_directories": attr.string_list(), + "extra_features": attr.string_list(), + "extra_no_canonical_prefixes_flags": attr.string_list(), + "host_compiler_warnings": attr.string_list(), + "host_system_name": attr.string(), + "host_unfiltered_compile_flags": attr.string_list(), + "target_cpu": attr.string(), + "target_system_name": attr.string(), + "tool_paths": attr.string_dict(), + "toolchain_identifier": attr.string(), + }, + provides = [CcToolchainConfigInfo], +) + def _k8_jetson_nano_cross_compile_impl(ctx): host_system_name = "k8"