diff --git a/demos/AT32/RT-AT-START-F405/.cproject b/demos/AT32/RT-AT-START-F405/.cproject new file mode 100644 index 0000000000..eb00a4aec8 --- /dev/null +++ b/demos/AT32/RT-AT-START-F405/.cproject @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/AT32/RT-AT-START-F405/.project b/demos/AT32/RT-AT-START-F405/.project new file mode 100644 index 0000000000..1f4a7141bb --- /dev/null +++ b/demos/AT32/RT-AT-START-F405/.project @@ -0,0 +1,78 @@ + + + RT-AT-START-F405 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + mingw32-make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + false + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/demos/AT32/RT-AT-START-F405/Makefile b/demos/AT32/RT-AT-START-F405/Makefile new file mode 100644 index 0000000000..4bec71adea --- /dev/null +++ b/demos/AT32/RT-AT-START-F405/Makefile @@ -0,0 +1,197 @@ +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +# Compiler options here. +ifeq ($(USE_OPT),) + USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 +endif + +# C specific options here (added to USE_OPT). +ifeq ($(USE_COPT),) + USE_COPT = +endif + +# C++ specific options here (added to USE_OPT). +ifeq ($(USE_CPPOPT),) + USE_CPPOPT = -fno-rtti +endif + +# Enable this if you want the linker to remove unused code and data. +ifeq ($(USE_LINK_GC),) + USE_LINK_GC = yes +endif + +# Linker extra options here. +ifeq ($(USE_LDOPT),) + USE_LDOPT = +endif + +# Enable this if you want link time optimizations (LTO). +ifeq ($(USE_LTO),) + USE_LTO = yes +endif + +# Enable this if you want to see the full log while compiling. +ifeq ($(USE_VERBOSE_COMPILE),) + USE_VERBOSE_COMPILE = no +endif + +# If enabled, this option makes the build process faster by not compiling +# modules not used in the current configuration. +ifeq ($(USE_SMART_BUILD),) + USE_SMART_BUILD = yes +endif + +# Enable this if you want to use bitbang I2C. +ifeq ($(USE_HAL_I2C_FALLBACK),) + USE_HAL_I2C_FALLBACK = no +endif + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Stack size to be allocated to the Cortex-M process stack. This stack is +# the stack used by the main() thread. +ifeq ($(USE_PROCESS_STACKSIZE),) + USE_PROCESS_STACKSIZE = 0x400 +endif + +# Stack size to the allocated to the Cortex-M main/exceptions stack. This +# stack is used for processing interrupts and exceptions. +ifeq ($(USE_EXCEPTIONS_STACKSIZE),) + USE_EXCEPTIONS_STACKSIZE = 0x400 +endif + +# Enables the use of FPU (no, softfp, hard). +ifeq ($(USE_FPU),) + USE_FPU = no +endif + +# FPU-related options. +ifeq ($(USE_FPU_OPT),) + USE_FPU_OPT = -mfloat-abi=$(USE_FPU) -mfpu=fpv4-sp-d16 +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, target, sources and paths +# + +# Define project name here +PROJECT = ch + +# Target settings. +MCU = cortex-m4 + +# Imported source files and paths. +CHIBIOS := ../../../../ChibiOS +CHIBIOS_CONTRIB := ../../.. +CONFDIR := ./cfg +BUILDDIR := ./build +DEPDIR := ./.dep + +# Licensing files. +include $(CHIBIOS)/os/license/license.mk +# Startup files. +include $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f405xx.mk +# HAL-OSAL files (optional). +include $(CHIBIOS)/os/hal/hal.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/AT32F405xx/platform.mk +include $(CHIBIOS_CONTRIB)/os/hal/boards/AT_START_F405/board.mk +include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk +# RTOS files (optional). +include $(CHIBIOS)/os/rt/rt.mk +include $(CHIBIOS)/os/common/ports/ARMv7-M/compilers/GCC/mk/port.mk +# Auto-build files in ./source recursively. +include $(CHIBIOS)/tools/mk/autobuild.mk +# Other files (optional). +include $(CHIBIOS)/os/test/test.mk +include $(CHIBIOS)/test/rt/rt_test.mk +include $(CHIBIOS)/test/oslib/oslib_test.mk +include $(CHIBIOS)/os/hal/lib/streams/streams.mk +include $(CHIBIOS)/os/various/shell/shell.mk + +# Define linker script file here. +LDSCRIPT= $(STARTUPLD_CONTRIB)/AT32F405xC.ld + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CSRC = $(ALLCSRC) \ + $(TESTSRC) \ + main.c + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CPPSRC = $(ALLCPPSRC) + +# List ASM source files here. +ASMSRC = $(ALLASMSRC) + +# List ASM with preprocessor source files here. +ASMXSRC = $(ALLXASMSRC) + +# Inclusion directories. +INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC) + +# Define C warning options here. +CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes + +# Define C++ warning options here. +CPPWARN = -Wall -Wextra -Wundef + +# +# Project, target, sources and paths +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +UDEFS = + +# Define ASM defines here +UADEFS = + +# List all user directories here +UINCDIR = + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# +# End of user section +############################################################################## + +############################################################################## +# Common rules +# + +RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk +include $(RULESPATH)/arm-none-eabi.mk +include $(RULESPATH)/rules.mk + +# +# Common rules +############################################################################## + +############################################################################## +# Custom rules +# + +# +# Custom rules +############################################################################## diff --git a/demos/AT32/RT-AT-START-F405/cfg/chconf.h b/demos/AT32/RT-AT-START-F405/cfg/chconf.h new file mode 100644 index 0000000000..46b3f78b68 --- /dev/null +++ b/demos/AT32/RT-AT-START-F405/cfg/chconf.h @@ -0,0 +1,842 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file rt/templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_7_0_ + +/*===========================================================================*/ +/** + * @name System settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Handling of instances. + * @note If enabled then threads assigned to various instances can + * interact each other using the same synchronization objects. + * If disabled then each OS instance is a separate world, no + * direct interactions are handled by the OS. + */ +#if !defined(CH_CFG_SMP_MODE) +#define CH_CFG_SMP_MODE FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_ST_RESOLUTION) +#define CH_CFG_ST_RESOLUTION 32 +#endif + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#if !defined(CH_CFG_ST_FREQUENCY) +#define CH_CFG_ST_FREQUENCY 10000 +#endif + +/** + * @brief Time intervals data size. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_INTERVALS_SIZE) +#define CH_CFG_INTERVALS_SIZE 32 +#endif + +/** + * @brief Time types data size. + * @note Allowed values are 16 or 32 bits. + */ +#if !defined(CH_CFG_TIME_TYPES_SIZE) +#define CH_CFG_TIME_TYPES_SIZE 32 +#endif + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#if !defined(CH_CFG_ST_TIMEDELTA) +#define CH_CFG_ST_TIMEDELTA 2 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#if !defined(CH_CFG_TIME_QUANTUM) +#define CH_CFG_TIME_QUANTUM 0 +#endif + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#if !defined(CH_CFG_NO_IDLE_THREAD) +#define CH_CFG_NO_IDLE_THREAD FALSE +#endif + +/** + * @brief Kernel hardening level. + * @details This option is the level of functional-safety checks enabled + * in the kerkel. The meaning is: + * - 0: No checks, maximum performance. + * - 1: Reasonable checks. + * - 2: All checks. + * . + */ +#if !defined(CH_CFG_HARDENING_LEVEL) +#define CH_CFG_HARDENING_LEVEL 0 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_OPTIMIZE_SPEED) +#define CH_CFG_OPTIMIZE_SPEED TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TM) +#define CH_CFG_USE_TM TRUE +#endif + +/** + * @brief Time Stamps APIs. + * @details If enabled then the time stamps APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TIMESTAMP) +#define CH_CFG_USE_TIMESTAMP TRUE +#endif + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_REGISTRY) +#define CH_CFG_USE_REGISTRY TRUE +#endif + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_WAITEXIT) +#define CH_CFG_USE_WAITEXIT TRUE +#endif + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_SEMAPHORES) +#define CH_CFG_USE_SEMAPHORES TRUE +#endif + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#endif + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MUTEXES) +#define CH_CFG_USE_MUTEXES TRUE +#endif + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#endif + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_CONDVARS) +#define CH_CFG_USE_CONDVARS TRUE +#endif + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#endif + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_EVENTS) +#define CH_CFG_USE_EVENTS TRUE +#endif + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#if !defined(CH_CFG_USE_EVENTS_TIMEOUT) +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#endif + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MESSAGES) +#define CH_CFG_USE_MESSAGES TRUE +#endif + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#if !defined(CH_CFG_USE_MESSAGES_PRIORITY) +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#endif + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#if !defined(CH_CFG_USE_DYNAMIC) +#define CH_CFG_USE_DYNAMIC TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name OSLIB options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_MAILBOXES) +#define CH_CFG_USE_MAILBOXES TRUE +#endif + +/** + * @brief Memory checks APIs. + * @details If enabled then the memory checks APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCHECKS) +#define CH_CFG_USE_MEMCHECKS TRUE +#endif + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCORE) +#define CH_CFG_USE_MEMCORE TRUE +#endif + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#if !defined(CH_CFG_MEMCORE_SIZE) +#define CH_CFG_MEMCORE_SIZE 0 +#endif + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#if !defined(CH_CFG_USE_HEAP) +#define CH_CFG_USE_HEAP TRUE +#endif + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMPOOLS) +#define CH_CFG_USE_MEMPOOLS TRUE +#endif + +/** + * @brief Objects FIFOs APIs. + * @details If enabled then the objects FIFOs APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_FIFOS) +#define CH_CFG_USE_OBJ_FIFOS TRUE +#endif + +/** + * @brief Pipes APIs. + * @details If enabled then the pipes APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_PIPES) +#define CH_CFG_USE_PIPES TRUE +#endif + +/** + * @brief Objects Caches APIs. + * @details If enabled then the objects caches APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_CACHES) +#define CH_CFG_USE_OBJ_CACHES TRUE +#endif + +/** + * @brief Delegate threads APIs. + * @details If enabled then the delegate threads APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_DELEGATES) +#define CH_CFG_USE_DELEGATES TRUE +#endif + +/** + * @brief Jobs Queues APIs. + * @details If enabled then the jobs queues APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_JOBS) +#define CH_CFG_USE_JOBS TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Objects factory options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Objects Factory APIs. + * @details If enabled then the objects factory APIs are included in the + * kernel. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_CFG_USE_FACTORY) +#define CH_CFG_USE_FACTORY TRUE +#endif + +/** + * @brief Maximum length for object names. + * @details If the specified length is zero then the name is stored by + * pointer but this could have unintended side effects. + */ +#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#endif + +/** + * @brief Enables the registry of generic objects. + */ +#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#endif + +/** + * @brief Enables factory for generic buffers. + */ +#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#endif + +/** + * @brief Enables factory for semaphores. + */ +#if !defined(CH_CFG_FACTORY_SEMAPHORES) +#define CH_CFG_FACTORY_SEMAPHORES TRUE +#endif + +/** + * @brief Enables factory for mailboxes. + */ +#if !defined(CH_CFG_FACTORY_MAILBOXES) +#define CH_CFG_FACTORY_MAILBOXES TRUE +#endif + +/** + * @brief Enables factory for objects FIFOs. + */ +#if !defined(CH_CFG_FACTORY_OBJ_FIFOS) +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#endif + +/** + * @brief Enables factory for Pipes. + */ +#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_PIPES TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_STATISTICS) +#define CH_DBG_STATISTICS FALSE +#endif + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_SYSTEM_STATE_CHECK) +#define CH_DBG_SYSTEM_STATE_CHECK TRUE +#endif + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_CHECKS) +#define CH_DBG_ENABLE_CHECKS TRUE +#endif + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_ASSERTS) +#define CH_DBG_ENABLE_ASSERTS TRUE +#endif + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_MASK) +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_ALL +#endif + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_BUFFER_SIZE) +#define CH_DBG_TRACE_BUFFER_SIZE 128 +#endif + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#if !defined(CH_DBG_ENABLE_STACK_CHECK) +#define CH_DBG_ENABLE_STACK_CHECK TRUE +#endif + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_FILL_THREADS) +#define CH_DBG_FILL_THREADS TRUE +#endif + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#if !defined(CH_DBG_THREADS_PROFILING) +#define CH_DBG_THREADS_PROFILING FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System structure extension. + * @details User fields added to the end of the @p ch_system_t structure. + */ +#define CH_CFG_SYSTEM_EXTRA_FIELDS \ + /* Add system custom fields here.*/ + +/** + * @brief System initialization hook. + * @details User initialization code added to the @p chSysInit() function + * just before interrupts are enabled globally. + */ +#define CH_CFG_SYSTEM_INIT_HOOK() { \ + /* Add system initialization code here.*/ \ +} + +/** + * @brief OS instance structure extension. + * @details User fields added to the end of the @p os_instance_t structure. + */ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ + /* Add OS instance custom fields here.*/ + +/** + * @brief OS instance initialization hook. + * + * @param[in] oip pointer to the @p os_instance_t structure + */ +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ + /* Add OS instance initialization code here.*/ \ +} + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p _thread_init() function. + * + * @note It is invoked from within @p _thread_init() and implicitly from all + * the threads creation APIs. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + * + * @param[in] ntp thread being switched in + * @param[in] otp thread being switched out + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** + * @brief Runtime Faults Collection Unit hook. + * @details This hook is invoked each time new faults are collected and stored. + */ +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ + /* Faults handling code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/demos/AT32/RT-AT-START-F405/cfg/config.h b/demos/AT32/RT-AT-START-F405/cfg/config.h new file mode 100644 index 0000000000..4fbd7cc3df --- /dev/null +++ b/demos/AT32/RT-AT-START-F405/cfg/config.h @@ -0,0 +1,30 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * I2C fallback driver system settings. + */ +#define SW_I2C_USE_I2C1 FALSE +#define SW_I2C_USE_I2C2 FALSE +#define SW_I2C_USE_I2C3 FALSE +#define SW_I2C_USE_I2C4 FALSE + +/* + * Other settings. + */ +#define BOARD_OTG_VBUSIG diff --git a/demos/AT32/RT-AT-START-F405/cfg/halconf.h b/demos/AT32/RT-AT-START-F405/cfg/halconf.h new file mode 100644 index 0000000000..59fb7c11f3 --- /dev/null +++ b/demos/AT32/RT-AT-START-F405/cfg/halconf.h @@ -0,0 +1,556 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef HALCONF_H +#define HALCONF_H + +#define _CHIBIOS_HAL_CONF_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC TRUE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the cryptographic subsystem. + */ +#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__) +#define HAL_USE_CRY FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EFlash subsystem. + */ +#if !defined(HAL_USE_EFL) || defined(__DOXYGEN__) +#define HAL_USE_EFL FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C TRUE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL TRUE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SIO subsystem. + */ +#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__) +#define HAL_USE_SIO FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI TRUE +#endif + +/** + * @brief Enables the TRNG subsystem. + */ +#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__) +#define HAL_USE_TRNG FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB TRUE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/** + * @brief Enables the WSPI subsystem. + */ +#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__) +#define HAL_USE_WSPI FALSE +#endif + +/*===========================================================================*/ +/* PAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__) +#define PAL_USE_CALLBACKS FALSE +#endif + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__) +#define PAL_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/** + * @brief Enforces the driver to use direct callbacks rather than OSAL events. + */ +#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__) +#define CAN_ENFORCE_USE_CALLBACKS FALSE +#endif + +/*===========================================================================*/ +/* CRY driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the SW fall-back of the cryptographic driver. + * @details When enabled, this option, activates a fall-back software + * implementation for algorithms not supported by the underlying + * hardware. + * @note Fall-back implementations may not be present for all algorithms. + */ +#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_USE_FALLBACK FALSE +#endif + +/** + * @brief Makes the driver forcibly use the fall-back implementations. + */ +#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_ENFORCE_FALLBACK FALSE +#endif + +/*===========================================================================*/ +/* DAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__) +#define DAC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define DAC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the zero-copy API. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Timeout before assuming a failure while waiting for card idle. + * @note Time is in milliseconds. + */ +#if !defined(MMC_IDLE_TIMEOUT_MS) || defined(__DOXYGEN__) +#define MMC_IDLE_TIMEOUT_MS 1000 +#endif + +/** + * @brief Mutual exclusion on the SPI bus. + */ +#if !defined(MMC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define MMC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/** + * @brief OCR initialization constant for V20 cards. + */ +#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__) +#define SDC_INIT_OCR_V20 0x50FF8000U +#endif + +/** + * @brief OCR initialization constant for non-V20 cards. + */ +#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__) +#define SDC_INIT_OCR 0x80100000U +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 16 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SIO driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SIO_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SIO_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Support for thread synchronization API. + */ +#if !defined(SIO_USE_SYNCHRONIZATION) || defined(__DOXYGEN__) +#define SIO_USE_SYNCHRONIZATION TRUE +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 256 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/** + * @brief Serial over USB number of buffers. + * @note The default is 2 buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_NUMBER 2 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Inserts an assertion on function errors before returning. + */ +#if !defined(SPI_USE_ASSERT_ON_ERROR) || defined(__DOXYGEN__) +#define SPI_USE_ASSERT_ON_ERROR TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/** + * @brief Handling method for SPI CS line. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__) +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD +#endif + +/*===========================================================================*/ +/* UART driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__) +#define UART_USE_WAIT FALSE +#endif + +/** + * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define UART_USE_MUTUAL_EXCLUSION FALSE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* WSPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__) +#define WSPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define WSPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +#endif /* HALCONF_H */ + +/** @} */ diff --git a/demos/AT32/RT-AT-START-F405/cfg/mcuconf.h b/demos/AT32/RT-AT-START-F405/cfg/mcuconf.h new file mode 100644 index 0000000000..a7eb2a1ad1 --- /dev/null +++ b/demos/AT32/RT-AT-START-F405/cfg/mcuconf.h @@ -0,0 +1,292 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef MCUCONF_H +#define MCUCONF_H + +/* + * AT32F405 drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#define AT32F405xx_MCUCONF + +/* + * General settings. + */ +#define AT32_NO_INIT FALSE + +/* + * HAL driver system settings. + */ +#define AT32_HICK_ENABLED TRUE +#define AT32_LICK_ENABLED TRUE +#define AT32_HEXT_ENABLED TRUE +#define AT32_LEXT_ENABLED FALSE +#define AT32_SCLKSEL AT32_SCLKSEL_PLL +#define AT32_PLLRCS AT32_PLLRCS_HEXT +#define AT32_PLLHEXTDIV AT32_PLLHEXTDIV_DIV1 +#define AT32_PLLCFGEN AT32_PLLCFGEN_SOLID +#define AT32_PLL_FP_VALUE 4 +#define AT32_PLL_FU_VALUE 18 +#define AT32_PLL_MS_VALUE 1 +#define AT32_PLL_NS_VALUE 72 +#define AT32_AHBDIV AT32_AHBDIV_DIV1 +#define AT32_APB1DIV AT32_APB1DIV_DIV2 +#define AT32_APB2DIV AT32_APB2DIV_DIV2 +#define AT32_ADCDIV AT32_ADCDIV_DIV4 +#define AT32_USB_CLOCK_REQUIRED TRUE +#define AT32_CLKOUT_SEL AT32_CLKOUT_SEL_HICK +#define AT32_CLKOUTDIV AT32_CLKOUTDIV_DIV1 +#define AT32_ERTCSEL AT32_ERTCSEL_LICK +#define AT32_PVM_ENABLE FALSE +#define AT32_PVMSEL AT32_PVMSEL_LEV1 + +/* + * IRQ system settings. + */ +#define AT32_IRQ_EXINT0_PRIORITY 6 +#define AT32_IRQ_EXINT1_PRIORITY 6 +#define AT32_IRQ_EXINT2_PRIORITY 6 +#define AT32_IRQ_EXINT3_PRIORITY 6 +#define AT32_IRQ_EXINT4_PRIORITY 6 +#define AT32_IRQ_EXINT5_9_PRIORITY 6 +#define AT32_IRQ_EXINT10_15_PRIORITY 6 +#define AT32_IRQ_EXINT16_PRIORITY 6 +#define AT32_IRQ_EXINT17_PRIORITY 15 +#define AT32_IRQ_EXINT18_PRIORITY 6 +#define AT32_IRQ_EXINT19_PRIORITY 6 +#define AT32_IRQ_EXINT20_PRIORITY 6 +#define AT32_IRQ_EXINT21_PRIORITY 15 +#define AT32_IRQ_EXINT22_PRIORITY 15 + +#define AT32_IRQ_TMR1_BRK_TMR9_PRIORITY 7 +#define AT32_IRQ_TMR1_OVF_TMR10_PRIORITY 7 +#define AT32_IRQ_TMR1_HALL_TMR11_PRIORITY 7 +#define AT32_IRQ_TMR1_CH_PRIORITY 7 +#define AT32_IRQ_TMR2_PRIORITY 7 +#define AT32_IRQ_TMR3_PRIORITY 7 +#define AT32_IRQ_TMR4_PRIORITY 7 +#define AT32_IRQ_TMR5_PRIORITY 7 +#define AT32_IRQ_TMR6_PRIORITY 7 +#define AT32_IRQ_TMR7_PRIORITY 7 +#define AT32_IRQ_TMR13_PRIORITY 7 +#define AT32_IRQ_TMR14_PRIORITY 7 + +#define AT32_IRQ_USART1_PRIORITY 12 +#define AT32_IRQ_USART2_PRIORITY 12 +#define AT32_IRQ_USART3_PRIORITY 12 +#define AT32_IRQ_UART4_PRIORITY 12 +#define AT32_IRQ_UART5_PRIORITY 12 +#define AT32_IRQ_USART6_PRIORITY 12 +#define AT32_IRQ_UART7_PRIORITY 12 +#define AT32_IRQ_UART8_PRIORITY 12 + +/* + * ADC driver system settings. + */ +#define AT32_ADC_USE_ADC1 TRUE +#define AT32_ADC_ADC1_DMA_PRIORITY 2 +#define AT32_ADC_ADC1_IRQ_PRIORITY 6 + +/* + * CAN driver system settings. + */ +#define AT32_CAN_USE_CAN1 FALSE +#define AT32_CAN_CAN1_IRQ_PRIORITY 11 + +/* + * DMA driver system settings. + */ +#define AT32_DMA_USE_DMAMUX TRUE + +/* + * GPT driver system settings. + */ +#define AT32_GPT_USE_TMR1 FALSE +#define AT32_GPT_USE_TMR2 FALSE +#define AT32_GPT_USE_TMR3 FALSE +#define AT32_GPT_USE_TMR4 FALSE +#define AT32_GPT_USE_TMR5 FALSE +#define AT32_GPT_USE_TMR9 FALSE +#define AT32_GPT_USE_TMR10 FALSE +#define AT32_GPT_USE_TMR11 FALSE +#define AT32_GPT_USE_TMR13 FALSE +#define AT32_GPT_USE_TMR14 FALSE + +/* + * I2C driver system settings. + */ +#define AT32_I2C_USE_I2C1 TRUE +#define AT32_I2C_USE_I2C2 FALSE +#define AT32_I2C_USE_DMA FALSE +#define AT32_I2C_BUSY_TIMEOUT 50 +#define AT32_I2C_I2C1_IRQ_PRIORITY 5 +#define AT32_I2C_I2C2_IRQ_PRIORITY 5 +#define AT32_I2C_I2C1_DMA_PRIORITY 3 +#define AT32_I2C_I2C2_DMA_PRIORITY 3 +#define AT32_I2C_I2C1_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_I2C_I2C1_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_I2C_I2C2_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_I2C_I2C2_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define AT32_ICU_USE_TMR1 FALSE +#define AT32_ICU_USE_TMR2 FALSE +#define AT32_ICU_USE_TMR3 FALSE +#define AT32_ICU_USE_TMR4 FALSE +#define AT32_ICU_USE_TMR5 FALSE +#define AT32_ICU_USE_TMR9 FALSE +#define AT32_ICU_USE_TMR10 FALSE +#define AT32_ICU_USE_TMR11 FALSE +#define AT32_ICU_USE_TMR13 FALSE +#define AT32_ICU_USE_TMR14 FALSE + +/* + * PWM driver system settings. + */ +#define AT32_PWM_USE_TMR1 FALSE +#define AT32_PWM_USE_TMR2 FALSE +#define AT32_PWM_USE_TMR3 FALSE +#define AT32_PWM_USE_TMR4 FALSE +#define AT32_PWM_USE_TMR5 FALSE +#define AT32_PWM_USE_TMR9 FALSE +#define AT32_PWM_USE_TMR10 FALSE +#define AT32_PWM_USE_TMR11 FALSE +#define AT32_PWM_USE_TMR13 FALSE +#define AT32_PWM_USE_TMR14 FALSE + +/* + * RTC driver system settings. + */ +#define AT32_ERTC_DIVA_VALUE 32 +#define AT32_ERTC_DIVB_VALUE 1024 +#define AT32_ERTC_CTRL_INIT 0 +#define AT32_ERTC_TAMP_INIT 0 + +/* + * SDC driver system settings. + */ +#define AT32_SDC_SDIO_DMA_PRIORITY 3 +#define AT32_SDC_SDIO_IRQ_PRIORITY 9 +#define AT32_SDC_WRITE_TIMEOUT_MS 1000 +#define AT32_SDC_READ_TIMEOUT_MS 1000 +#define AT32_SDC_CLOCK_ACTIVATION_DELAY 10 +#define AT32_SDC_SDIO_UNALIGNED_SUPPORT TRUE + +/* + * SERIAL driver system settings. + */ +#define AT32_SERIAL_USE_USART1 TRUE +#define AT32_SERIAL_USE_USART2 FALSE +#define AT32_SERIAL_USE_USART3 FALSE +#define AT32_SERIAL_USE_UART4 FALSE +#define AT32_SERIAL_USE_UART5 FALSE + +/* + * SPI driver system settings. + */ +#define AT32_SPI_USE_SPI1 TRUE +#define AT32_SPI_USE_SPI2 FALSE +#define AT32_SPI_SPI1_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_SPI_SPI1_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_SPI_SPI2_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_SPI_SPI2_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY + +#define AT32_SPI_SPI1_DMA_PRIORITY 1 +#define AT32_SPI_SPI2_DMA_PRIORITY 1 +#define AT32_SPI_SPI1_IRQ_PRIORITY 10 +#define AT32_SPI_SPI2_IRQ_PRIORITY 10 +#define AT32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define AT32_ST_IRQ_PRIORITY 8 +#define AT32_ST_USE_TIMER 2 + +/* + * UART driver system settings. + */ +#define AT32_UART_USE_USART1 FALSE +#define AT32_UART_USE_USART2 FALSE +#define AT32_UART_USE_USART3 FALSE +#define AT32_UART_USE_UART4 FALSE +#define AT32_UART_USE_UART5 FALSE + +#define AT32_UART_USART1_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_USART1_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_USART2_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_USART2_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_USART3_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_USART3_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_UART4_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_UART4_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_UART5_RX_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#define AT32_UART_UART5_TX_DMA_STREAM AT32_DMA_STREAM_ID_ANY + +#define AT32_UART_USART1_DMA_PRIORITY 0 +#define AT32_UART_USART2_DMA_PRIORITY 0 +#define AT32_UART_USART3_DMA_PRIORITY 0 +#define AT32_UART_USART4_DMA_PRIORITY 0 +#define AT32_UART_USART5_DMA_PRIORITY 0 +#define AT32_UART_USART6_DMA_PRIORITY 0 +#define AT32_UART_UART7_DMA_PRIORITY 0 +#define AT32_UART_UART8_DMA_PRIORITY 0 +#define AT32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define AT32_USB_USE_OTG1 TRUE +#define AT32_USB_OTG1_IRQ_PRIORITY 14 +#define AT32_USB_OTG1_RX_FIFO_SIZE 512 + +#define AT32_USB_USE_OTG2 TRUE +#define AT32_USB_OTG2_IRQ_PRIORITY 14 +#define AT32_USB_OTG2_RX_FIFO_SIZE 1024 +#define AT32_USE_USB_OTG2_HS TRUE +#define AT32_OTG2_SUPPORTS_HS TRUE + + +/* + * WDG driver system settings. + */ +#define AT32_WDG_USE_WDT FALSE + +/* + * DMA driver Version. + */ +#define AT32_USE_DMA_V1 FALSE + +#include "config.h" + +#endif /* MCUCONF_H */ diff --git a/demos/AT32/RT-AT-START-F405/main.c b/demos/AT32/RT-AT-START-F405/main.c new file mode 100644 index 0000000000..65e1853b01 --- /dev/null +++ b/demos/AT32/RT-AT-START-F405/main.c @@ -0,0 +1,86 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ch.h" +#include "hal.h" +#include "rt_test_root.h" +#include "oslib_test_root.h" + +/* + * This is a periodic thread that does absolutely nothing except flashing + * a LED. + */ +static THD_WORKING_AREA(waThread1, 128); +static THD_FUNCTION(Thread1, arg) { + + (void)arg; + chRegSetThreadName("blinker"); + while (true) { + palSetLine(LINE_LED_RED); + chThdSleepMilliseconds(250); + palSetLine(LINE_LED_YELLOW); + chThdSleepMilliseconds(250); + palSetLine(LINE_LED_GREEN); + chThdSleepMilliseconds(250); + palClearLine(LINE_LED_RED); + chThdSleepMilliseconds(250); + palClearLine(LINE_LED_YELLOW); + chThdSleepMilliseconds(250); + palClearLine(LINE_LED_GREEN); + chThdSleepMilliseconds(250); + } +} + +/* + * Application entry point. + */ +int main(void) { + + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + chSysInit(); + + /* + * Activates the serial driver 1 using the driver default configuration. + */ + sdStart(&SD1, NULL); + + /* + * Creates the example thread. + */ + chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); + + /* + * Normal main() thread activity, in this demo it does nothing except + * sleeping in a loop and check the button state. + */ + while (true) { + if (palReadLine(LINE_BUTTON)) { + test_execute((BaseSequentialStream *)&SD1, &rt_test_suite); + test_execute((BaseSequentialStream *)&SD1, &oslib_test_suite); + } + chThdSleepMilliseconds(500); + } +} diff --git a/os/common/ext/CMSIS/ArteryTek/AT32F402_405xx/at32f402_405xx.h b/os/common/ext/CMSIS/ArteryTek/AT32F402_405xx/at32f402_405xx.h new file mode 100644 index 0000000000..f359d99744 --- /dev/null +++ b/os/common/ext/CMSIS/ArteryTek/AT32F402_405xx/at32f402_405xx.h @@ -0,0 +1,2649 @@ +/** + ************************************************************************** + * @file at32f402_405.h + * @brief at32f402_405 header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#ifndef __AT32F402_405_H +#define __AT32F402_405_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__CC_ARM) + #pragma anon_unions +#endif + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup AT32F402_405 + * @{ + */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * tip: to avoid modifying this file each time you need to switch between these + * devices, you can define the device in your toolchain compiler preprocessor. + */ + +#if !defined (AT32F405KBU7_4) && !defined (AT32F405KCU7_4) && !defined (AT32F405CBT7) && \ + !defined (AT32F405CCT7) && !defined (AT32F405CBU7) && !defined (AT32F405CCU7) && \ + !defined (AT32F405RBT7_7) && !defined (AT32F405RCT7_7) && !defined (AT32F405RBT7) && \ + !defined (AT32F405RCT7) && !defined (AT32F402KBU7_4) && !defined (AT32F402KCU7_4)&& \ + !defined (AT32F402CBT7) && !defined (AT32F402CCT7) && !defined (AT32F402CBU7) && \ + !defined (AT32F402CCU7) && !defined (AT32F402RBT7_7) && !defined (AT32F402RCT7_7)&& \ + !defined (AT32F402RBT7) && !defined (AT32F402RCT7) + + #error "Please select first the target device used in your application (in at32f402_405.h file)" +#endif + +#if defined (AT32F405KBU7_4) || defined (AT32F405KCU7_4) || defined (AT32F405CBT7) || \ + defined (AT32F405CCT7) || defined (AT32F405CBU7) || defined (AT32F405CCU7) || \ + defined (AT32F405RBT7_7) || defined (AT32F405RCT7_7) || defined (AT32F405RBT7) || \ + defined (AT32F405RCT7) + + #define AT32F405xx +#endif + +#if defined (AT32F402KBU7_4) || defined (AT32F402KCU7_4) || defined (AT32F402CBT7) || \ + defined (AT32F402CCT7) || defined (AT32F402CBU7) || defined (AT32F402CCU7) || \ + defined (AT32F402RBT7_7) || defined (AT32F402RCT7_7) || defined (AT32F402RBT7) || \ + defined (AT32F402RCT7) + + #define AT32F402xx +#endif + +/** + * define with package + */ +#if defined (AT32F405KBU7_4) || defined (AT32F405KCU7_4) + + #define AT32F405Kx +#endif +#if defined (AT32F405CBT7) || defined (AT32F405CCT7) || defined (AT32F405CBU7) || \ + defined (AT32F405CCU7) + + #define AT32F405Rx +#endif + +#if defined (AT32F405RBT7_7) || defined (AT32F405RCT7_7) || defined (AT32F405RBT7) || \ + defined (AT32F405RCT7) + + #define AT32F405Rx +#endif + +#if defined (AT32F402KBU7_4) || defined (AT32F402KCU7_4) + + #define AT32F402Kx +#endif +#if defined (AT32F402CBT7) || defined (AT32F402CCT7) || defined (AT32F402CBU7) || \ + defined (AT32F402CCU7) + + #define AT32F402Rx +#endif + +#if defined (AT32F402RBT7_7) || defined (AT32F402RCT7_7) || defined (AT32F402RBT7) || \ + defined (AT32F402RCT7) + + #define AT32F402Rx +#endif + + +/** + * define with memory density + */ +#if defined (AT32F405KBU7_4) || defined (AT32F405CBT7) || defined (AT32F405CBU7) || \ + defined (AT32F405RBT7_7) || defined (AT32F405RBT7) + + #define AT32F405xB +#endif + +#if defined (AT32F405KCU7_4) || defined (AT32F405CCT7) || defined (AT32F405CCU7) || \ + defined (AT32F405RCT7_7) || defined (AT32F405RCT7) + + #define AT32F405xC +#endif + +#if defined (AT32F402KBU7_4) || defined (AT32F402CBT7) || defined (AT32F402CBU7) || \ + defined (AT32F402RBT7_7) || defined (AT32F402RBT7) + + #define AT32F402xB +#endif + +#if defined (AT32F402KCU7_4) || defined (AT32F402CCT7) || defined (AT32F402CCU7) || \ + defined (AT32F402RCT7_7) || defined (AT32F402RCT7) + + #define AT32F402xC +#endif + +#ifndef USE_STDPERIPH_DRIVER +/** + * @brief comment the line below if you will not use the peripherals drivers. + * in this case, these drivers will not be included and the application code will + * be based on direct access to peripherals registers + */ + #ifdef _RTE_ + #include "RTE_Components.h" + #ifdef RTE_DEVICE_STDPERIPH_FRAMEWORK + #define USE_STDPERIPH_DRIVER + #endif + #endif +#endif + +/** + * @brief at32f402_405 standard peripheral library version number + */ +#define __AT32F402_405_LIBRARY_VERSION_MAJOR (0x02) /*!< [31:24] major version */ +#define __AT32F402_405_LIBRARY_VERSION_MIDDLE (0x00) /*!< [23:16] middle version */ +#define __AT32F402_405_LIBRARY_VERSION_MINOR (0x00) /*!< [15:8] minor version */ +#define __AT32F402_405_LIBRARY_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __AT32F402_405_LIBRARY_VERSION ((__AT32F402_405_LIBRARY_VERSION_MAJOR << 24) | \ + (__AT32F402_405_LIBRARY_VERSION_MIDDLE << 16) | \ + (__AT32F402_405_LIBRARY_VERSION_MINOR << 8) | \ + (__AT32F402_405_LIBRARY_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup configuration_section_for_cmsis + * @{ + */ + +/** + * @brief configuration of the cortex-m4 processor and core peripherals + */ +#define __CM4_REV 0x0001U /*!< core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< mpu present */ +#define __NVIC_PRIO_BITS 4 /*!< at32 uses 4 bits for the priority levels */ +#define __Vendor_SysTickConfig 0 /*!< set to 1 if different systick config is used */ +#define __FPU_PRESENT 1U /*!< fpu present */ + +/** + * @brief at32f402_405 interrupt number definition, according to the selected device + * in @ref library_configuration_section + */ +typedef enum IRQn +{ + /****** cortex-m4 processor exceptions numbers ***************************************************/ + Reset_IRQn = -15, /*!< 1 reset vector, invoked on power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */ + HardFault_IRQn = -13, /*!< 3 hard fault, all classes of fault */ + MemoryManagement_IRQn = -12, /*!< 4 cortex-m4 memory management interrupt */ + BusFault_IRQn = -11, /*!< 5 cortex-m4 bus fault interrupt */ + UsageFault_IRQn = -10, /*!< 6 cortex-m4 usage fault interrupt */ + SVCall_IRQn = -5, /*!< 11 cortex-m4 sv call interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 cortex-m4 debug monitor interrupt */ + PendSV_IRQn = -2, /*!< 14 cortex-m4 pend sv interrupt */ + SysTick_IRQn = -1, /*!< 15 cortex-m4 system tick interrupt */ + + /****** at32 specific interrupt numbers *********************************************************/ + WWDT_IRQn = 0, /*!< window watchdog timer interrupt */ + PVM_IRQn = 1, /*!< pvm through exint line detection interrupt */ + TAMP_STAMP_IRQn = 2, /*!< tamper and timestamp interrupts through the exint line */ + ERTC_WKUP_IRQn = 3, /*!< ertc wakeup through the exint line */ + FLASH_IRQn = 4, /*!< flash global interrupt */ + CRM_IRQn = 5, /*!< crm global interrupt */ + EXINT0_IRQn = 6, /*!< exint line0 interrupt */ + EXINT1_IRQn = 7, /*!< exint line1 interrupt */ + EXINT2_IRQn = 8, /*!< exint line2 interrupt */ + EXINT3_IRQn = 9, /*!< exint line3 interrupt */ + EXINT4_IRQn = 10, /*!< exint line4 interrupt */ + DMA1_Channel1_IRQn = 11, /*!< dma1 channel 1 global interrupt */ + DMA1_Channel2_IRQn = 12, /*!< dma1 channel 2 global interrupt */ + DMA1_Channel3_IRQn = 13, /*!< dma1 channel 3 global interrupt */ + DMA1_Channel4_IRQn = 14, /*!< dma1 channel 4 global interrupt */ + DMA1_Channel5_IRQn = 15, /*!< dma1 channel 5 global interrupt */ + DMA1_Channel6_IRQn = 16, /*!< dma1 channel 6 global interrupt */ + DMA1_Channel7_IRQn = 17, /*!< dma1 channel 7 global interrupt */ + + ADC1_IRQn = 18, /*!< adc1 global interrupt */ + CAN1_TX_IRQn = 19, /*!< can1 tx interrupts */ + CAN1_RX0_IRQn = 20, /*!< can1 rx0 interrupts */ + CAN1_RX1_IRQn = 21, /*!< can1 rx1 interrupt */ + CAN1_SE_IRQn = 22, /*!< can1 se interrupt */ + EXINT9_5_IRQn = 23, /*!< external line[9:5] interrupts */ + TMR1_BRK_TMR9_IRQn = 24, /*!< tmr1 brake interrupt */ + TMR1_OVF_TMR10_IRQn = 25, /*!< tmr1 overflow interrupt */ + TMR1_TRG_HALL_TMR11_IRQn = 26, /*!< tmr1 trigger and hall interrupt */ + TMR1_CH_IRQn = 27, /*!< tmr1 channel interrupt */ + TMR2_GLOBAL_IRQn = 28, /*!< tmr2 global interrupt */ + TMR3_GLOBAL_IRQn = 29, /*!< tmr3 global interrupt */ + TMR4_GLOBAL_IRQn = 30, /*!< tmr4 global interrupt */ + I2C1_EVT_IRQn = 31, /*!< i2c1 event interrupt */ + I2C1_ERR_IRQn = 32, /*!< i2c1 error interrupt */ + I2C2_EVT_IRQn = 33, /*!< i2c2 event interrupt */ + I2C2_ERR_IRQn = 34, /*!< i2c2 error interrupt */ + SPI1_IRQn = 35, /*!< spi1 global interrupt */ + SPI2_IRQn = 36, /*!< spi2 global interrupt */ + USART1_IRQn = 37, /*!< usart1 global interrupt */ + USART2_IRQn = 38, /*!< usart2 global interrupt */ + USART3_IRQn = 39, /*!< usart3 global interrupt */ + EXINT15_10_IRQn = 40, /*!< external line[15:10] interrupts */ + ERTCAlarm_IRQn = 41, /*!< ertc alarm through exint line interrupt */ + OTGFS1_WKUP_IRQn = 42, /*!< otgfs1 wakeup from suspend through exint line interrupt */ + TMR13_GLOBAL_IRQn = 44, /*!< tmr13 global interrupt */ + TMR14_GLOBAL_IRQn = 45, /*!< tmr14 global interrupt */ + SPI3_IRQn = 51, /*!< spi3 global interrupt */ + USART4_IRQn = 52, /*!< usart4 global interrupt */ + USART5_IRQn = 53, /*!< usart5 global interrupt */ + TMR6_GLOBAL_IRQn = 54, /*!< tmr6 global interrupt */ + TMR7_GLOBAL_IRQn = 55, /*!< tmr7 global interrupt */ + DMA2_Channel1_IRQn = 56, /*!< dma2 channel 1 global interrupt */ + DMA2_Channel2_IRQn = 57, /*!< dma2 channel 2 global interrupt */ + DMA2_Channel3_IRQn = 58, /*!< dma2 channel 3 global interrupt */ + DMA2_Channel4_IRQn = 59, /*!< dma2 channel 4 global interrupt */ + DMA2_Channel5_IRQn = 60, /*!< dma2 channel 5 global interrupt */ + OTGFS1_IRQn = 67, /*!< otgfs1 interrupt */ + DMA2_Channel6_IRQn = 68, /*!< dma2 channel 6 global interrupt */ + DMA2_Channel7_IRQn = 69, /*!< dma2 channel 7 global interrupt */ + USART6_IRQn = 71, /*!< usart6 interrupt */ + I2C3_EVT_IRQn = 72, /*!< i2c3 event interrupt */ + I2C3_ERR_IRQn = 73, /*!< i2c3 error interrupt */ + OTGHS_EP1_OUT_IRQn = 74, /*!< otghs wakeup from suspend through exint line interrupt */ + OTGHS_EP1_IN_IRQn = 75, /*!< otghs interrupt */ + OTGHS_WKUP_IRQn = 76, /*!< otghs wakeup from suspend through exint line interrupt */ + OTGHS_IRQn = 77, /*!< otghs interrupt */ + FPU_IRQn = 81, /*!< fpu interrupt */ + UART7_IRQn = 82, /*!< uart7 interrupt */ + UART8_IRQn = 83, /*!< uart8 interrupt */ + I2SF5_IRQn = 85, /*!< i2sf5 global interrupt */ + QSPI1_IRQn = 92, /*!< qspi1 global interrupt */ + DMAMUX_IRQn = 94, /*!< dmamux global interrupt */ + ACC_IRQn = 103, /*!< acc interrupt */ + +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm4.h" +#include + +/** @addtogroup Exported_types + * @{ + */ + +typedef int32_t INT32; +typedef int16_t INT16; +typedef int8_t INT8; +typedef uint32_t UINT32; +typedef uint16_t UINT16; +typedef uint8_t UINT8; + +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef const int32_t sc32; /*!< read only */ +typedef const int16_t sc16; /*!< read only */ +typedef const int8_t sc8; /*!< read only */ + +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef __I int32_t vsc32; /*!< read only */ +typedef __I int16_t vsc16; /*!< read only */ +typedef __I int8_t vsc8; /*!< read only */ + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef const uint32_t uc32; /*!< read only */ +typedef const uint16_t uc16; /*!< read only */ +typedef const uint8_t uc8; /*!< read only */ + +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef __I uint32_t vuc32; /*!< read only */ +typedef __I uint16_t vuc16; /*!< read only */ +typedef __I uint8_t vuc8; /*!< read only */ + +typedef enum {RESET = 0, SET = !RESET} flag_status; +typedef enum {ERROR = 0, SUCCESS = !ERROR} error_status; + +/** + * @} + */ + +/** @addtogroup Exported_macro + * @{ + */ + +#define REG8(addr) *(volatile uint8_t *)(addr) +#define REG16(addr) *(volatile uint16_t *)(addr) +#define REG32(addr) *(volatile uint32_t *)(addr) + +#define MAKE_VALUE(reg_offset, bit_num) (((reg_offset) << 16) | (bit_num & 0x1f)) + +#define PERIPH_REG(periph_base, value) REG32((periph_base + (value >> 16))) +#define PERIPH_REG_BIT(value) (0x1u << (value & 0x1f)) + +/** + * @} + */ + + + + + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/* ================================================================================ */ +/* ================ ACC ================ */ +/* ================================================================================ */ + + +/** + * @brief HSI Auto Clock Calibration (ACC) + */ + +typedef struct +{ /*!< ACC Structure */ + __IO uint32_t STS; /*!< status register */ + __IO uint32_t CTRL1; /*!< control register 1 */ + __IO uint32_t CTRL2; /*!< control register 2 */ + __IO uint32_t CC1; /*!< compare value 1 */ + __IO uint32_t CC2; /*!< compare value 2 */ + __IO uint32_t CC3; /*!< compare value 3 */ +} ACC_TypeDef; + + +/* ================================================================================ */ +/* ================ ADC ================ */ +/* ================================================================================ */ + + +/** + * @brief Analog to digital converter (ADC) + */ + +typedef struct +{ /*!< ADC Structure */ + __IO uint32_t STS; /*!< status register */ + __IO uint32_t CTRL1; /*!< control register 1 */ + __IO uint32_t CTRL2; /*!< control register 2 */ + __IO uint32_t SPT1; /*!< sample time register 1 */ + __IO uint32_t SPT2; /*!< sample time register 2 */ + __IO uint32_t PCDTO1; /*!< Preempted channel 1 data offset register */ + __IO uint32_t PCDTO2; /*!< Preempted channel 2 data offset register */ + __IO uint32_t PCDTO3; /*!< Preempted channel 3 data offset register */ + __IO uint32_t PCDTO4; /*!< Preempted channel 4 data offset register */ + __IO uint32_t VMHB; /*!< Voltage monitoring high boundary register */ + __IO uint32_t VMLB; /*!< Voltage monitoring low boundary register */ + __IO uint32_t OSQ1; /*!< Ordinary sequence register 1 */ + __IO uint32_t OSQ2; /*!< Ordinary sequence register 2 */ + __IO uint32_t OSQ3; /*!< Ordinary sequence register 3 */ + __IO uint32_t PSQ; /*!< Preempted sequence register */ + __IO uint32_t PDT1; /*!< Preempted data register 1 */ + __IO uint32_t PDT2; /*!< Preempted data register 2 */ + __IO uint32_t PDT3; /*!< Preempted data register 3 */ + __IO uint32_t PDT4; /*!< Preempted data register 4 */ + __IO uint32_t ODT; /*!< Ordinary data register */ + __IO uint32_t RESERVED0[12]; + __IO uint32_t OVSP; /*!< oversampling register */ +} ADC_TypeDef; + + +/* ================================================================================ */ +/* ================ ADCCOM ================ */ +/* ================================================================================ */ + + +/** + * @brief ADC common area (ADCCOM) + */ + +typedef struct +{ /*!< ADCCOM Structure */ + __IO uint32_t RESERVED0; + __IO uint32_t CCTRL; /*!< Common control register */ +} ADCCOM_TypeDef; + + +/* ================================================================================ */ +/* ================ CAN ================ */ +/* ================================================================================ */ + + +/** + * @brief Controller Area Network (CAN) + */ +/** + * @brief Controller Area Network TX Mailbox Registers + */ + +typedef struct +{ + __IO uint32_t TMI; /*!< Transmit mailbox identifier register */ + __IO uint32_t TMC; /*!< Transmit mailbox data length and time stamp register */ + __IO uint32_t TMDTL; /*!< Transmit mailbox low byte data register */ + __IO uint32_t TMDTH; /*!< Transmit mailbox high byte data register */ +} CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFO Mailbox Registers + */ + +typedef struct +{ + __IO uint32_t RFI; /*!< Receive FIFO register */ + __IO uint32_t RFC; /*!< Receive FIFO data length and time stamp register */ + __IO uint32_t RFDTL; /*!< Receive FIFO low byte data register */ + __IO uint32_t RFDTH; /*!< Receive FIFO high byte data register */ +} CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network Filter Registers + */ + +typedef struct +{ + __IO uint32_t FFB1; /*!< Filter bank filtrate bit register 1 */ + __IO uint32_t FFB2; /*!< Filter bank filtrate bit register 2 */ +} CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ + +typedef struct +{ /*!< CAN Structure */ + __IO uint32_t MCTRL; /*!< Main control register */ + __IO uint32_t MSTS; /*!< Main status register */ + __IO uint32_t TSTS; /*!< Transmit status register */ + __IO uint32_t RF0; /*!< Receive FIFO 0 register */ + __IO uint32_t RF1; /*!< Receive FIFO 1 register */ + __IO uint32_t INTEN; /*!< Interrupt enable register */ + __IO uint32_t ESTS; /*!< Error status register */ + __IO uint32_t BTMG; /*!< Bit timing register */ + __IO uint32_t RESERVED0[88]; + CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< Transmit mailbox registers */ + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< Receive FIFO registers */ + __IO uint32_t RESERVED1[12]; + __IO uint32_t FCTRL; /*!< Filter control register */ + __IO uint32_t FMCFG; /*!< Filter mode config register */ + __IO uint32_t RESERVED2; + __IO uint32_t FBWCFG; /*!< Filter bit width config register */ + __IO uint32_t RESERVED3; + __IO uint32_t FRF; /*!< Filter related FIFO register */ + __IO uint32_t RESERVED4; + __IO uint32_t FACFG; /*!< Filter activate configuration register */ + __IO uint32_t RESERVED5[8]; + CAN_FilterRegister_TypeDef sFilterRegister[14]; /*!< Filter registers */ +} CAN_TypeDef; + + +/* ================================================================================ */ +/* ================ CRC ================ */ +/* ================================================================================ */ + + +/** + * @brief CRC calculation unit (CRC) + */ + +typedef struct +{ /*!< CRC Structure */ + __IO uint32_t DT; /*!< Data register */ + __IO uint32_t CDT; /*!< Common data register */ + __IO uint32_t CTRL; /*!< Control register */ + __IO uint32_t RESERVED0; + __IO uint32_t IDT; /*!< Initial data register */ + __IO uint32_t POLY; /*!< Polynomial coefficient register */ +} CRC_TypeDef; + + +/* ================================================================================ */ +/* ================ CRM ================ */ +/* ================================================================================ */ + + +/** + * @brief Clock and reset management (CRM) + */ + +typedef struct +{ /*!< CRM Structure */ + __IO uint32_t CTRL; /*!< Clock control register */ + __IO uint32_t PLLCFG; /*!< PLL configuration register (CRM_PLLCFG) */ + __IO uint32_t CFG; /*!< Clock configuration register(CRM_CFG) */ + __IO uint32_t CLKINT; /*!< Clock interrupt register (CRM_CLKINT) */ + __IO uint32_t AHBRST1; /*!< AHB peripheral reset register1 (CRM_AHBRST1) */ + __IO uint32_t AHBRST2; /*!< AHB peripheral reset register 2 (CRM_AHBRST2) */ + __IO uint32_t AHBRST3; /*!< AHB peripheral reset register 3 (CRM_AHBRST3) */ + __IO uint32_t RESERVED0; + __IO uint32_t APB1RST; /*!< APB1 peripheral reset register (CRM_APB1RST) */ + __IO uint32_t APB2RST; /*!< APB2 peripheral reset register (CRM_APB2RST) */ + __IO uint32_t RESERVED1[2]; + __IO uint32_t AHBEN1; /*!< AHB Peripheral Clock enable register 1 (CRM_AHBEN1) */ + __IO uint32_t AHBEN2; /*!< AHB peripheral clock enable register 2 (CRM_AHBEN2) */ + __IO uint32_t AHBEN3; /*!< AHB peripheral clock enable register 3 (CRM_AHBEN3) */ + __IO uint32_t RESERVED2; + __IO uint32_t APB1EN; /*!< APB1 peripheral clock enable register (CRM_APB1EN) */ + __IO uint32_t APB2EN; /*!< APB2 peripheral clock enable register (CRM_APB2EN) */ + __IO uint32_t RESERVED3[2]; + __IO uint32_t AHBLPEN1; /*!< AHB Low-power Peripheral Clock enable register 1 (CRM_AHBLPEN1) */ + __IO uint32_t AHBLPEN2; /*!< AHB peripheral Low-power clock enable register 2 (CRM_AHBLPEN2) */ + __IO uint32_t AHBLPEN3; /*!< AHB peripheral Low-power clock enable register 3 (CRM_AHBLPEN3) */ + __IO uint32_t RESERVED4; + __IO uint32_t APB1LPEN; /*!< APB1 peripheral Low-power clock enable register (CRM_APB1LPEN) */ + __IO uint32_t APB2LPEN; /*!< APB2 peripheral Low-power clock enable register (CRM_APB2LPEN) */ + __IO uint32_t RESERVED5[2]; + __IO uint32_t BPDC; /*!< Battery powered domain control register (CRM_BPDC) */ + __IO uint32_t CTRLSTS; /*!< Control/status register (CRM_CTRLSTS) */ + __IO uint32_t OTGHS; /*!< OTGHS register */ + __IO uint32_t RESERVED6[9]; + __IO uint32_t MISC1; /*!< Miscellaneous register1 */ + __IO uint32_t MISC2; /*!< Miscellaneous register2 */ +} CRM_TypeDef; + + +/* ================================================================================ */ +/* ================ DEBUG ================ */ +/* ================================================================================ */ + + +/** + * @brief Debug support (DEBUG) + */ + +typedef struct +{ /*!< DEBUG Structure */ + __IO uint32_t IDCODE; /*!< DEBUG IDCODE */ + __IO uint32_t CTRL; /*!< DEBUG CTRL */ + __IO uint32_t APB1_PAUSE; /*!< DEBUG APB1 PAUSE */ + __IO uint32_t APB2_PAUSE; /*!< DEBUG APB2 PAUSE */ + __IO uint32_t RESERVED0[4]; + __IO uint32_t SER_ID; /*!< SERIES ID */ +} DEBUG_TypeDef; + + +/* ================================================================================ */ +/* ================ DMA ================ */ +/* ================================================================================ */ + + +/** + * @brief DMA controller (DMA) + */ + +typedef struct +{ /*!< DMA Structure */ + __IO uint32_t STS; /*!< DMA interrupt status register (DMA_STS) */ + __IO uint32_t CLR; /*!< DMA interrupt flag clear register (DMA_CLR) */ + __IO uint32_t RESERVED1[62]; + __IO uint32_t MUXSEL; /*!< DMAMUX Table Selection */ + __IO uint32_t RESERVED2[11]; + __IO uint32_t MUXSYNCSTS; /*!< Channel Interrupt Status Register */ + __IO uint32_t MUXSYNCCLR; /*!< Channel Interrupt Clear Flag Register */ + __IO uint32_t MUXGSTS; /*!< Generator Interrupt Status Register */ + __IO uint32_t MUXGCLR; /*!< Generator Interrupt Clear Flag Register */ +} DMA_TypeDef; + + +/* ================================================================================ */ +/* ================ DMA Channel ================ */ +/* ================================================================================ */ + + +/** + * @brief DMA controller Channel(DMA Channel) + */ +typedef struct +{ /*!< DMA Channel Structure */ + __IO uint32_t CTRL; /*!< DMA channel configuration register */ + __IO uint32_t DTCNT; /*!< DMA channel number of data to transfer register */ + __IO uint32_t PADDR; /*!< DMA channel peripheral base address register */ + __IO uint32_t MADDR; /*!< DMA channel memory base address register */ +} DMA_Channel_TypeDef; + + +/* ================================================================================ */ +/* ================ DMA MUX ================ */ +/* ================================================================================ */ + + +/** + * @brief DMA MUX controller + */ +typedef struct +{ + __IO uint32_t MUXCTRL; /*!< Channel Configuration Register */ + +} DMAMUX_Channel_TypeDef; + + +/* ================================================================================ */ +/* ================ DMA Generator ================ */ +/* ================================================================================ */ + + +/** + * @brief DMA MUX Generator Configuration + */ +typedef struct +{ + __IO uint32_t GCTRL; /*!< Generator Configuration Register */ + +} DMAMUX_Generator_TypeDef; + + +/* ================================================================================ */ +/* ================ ERTC ================ */ +/* ================================================================================ */ + + +/** + * @brief Real-time clock (ERTC) + */ + +typedef struct +{ /*!< ERTC Structure */ + __IO uint32_t TIME; /*!< time register */ + __IO uint32_t DATE; /*!< date register */ + __IO uint32_t CTRL; /*!< control register */ + __IO uint32_t STS; /*!< initialization and status register */ + __IO uint32_t DIV; /*!< Diveder register */ + __IO uint32_t WAT; /*!< Wakeup timer register */ + __IO uint32_t CCAL; /*!< Calibration register */ + __IO uint32_t ALA; /*!< Alarm A register */ + __IO uint32_t ALB; /*!< Alarm B register */ + __IO uint32_t WP; /*!< write protection register */ + __IO uint32_t SBS; /*!< sub second register */ + __IO uint32_t TADJ; /*!< time adjust register */ + __IO uint32_t TSTM; /*!< time stamp time register */ + __IO uint32_t TSDT; /*!< timestamp date register */ + __IO uint32_t TSSBS; /*!< timestamp sub second register */ + __IO uint32_t SCAL; /*!< calibration register */ + __IO uint32_t TAMP; /*!< tamper and alternate function configuration register */ + __IO uint32_t ALASBS; /*!< alarm A sub second register */ + __IO uint32_t ALBSBS; /*!< alarm B sub second register */ + __IO uint32_t RESERVED0; + __IO uint32_t BPR1; /*!< Battery powered domain register */ + __IO uint32_t BPR2; /*!< Battery powered domain register */ + __IO uint32_t BPR3; /*!< Battery powered domain register */ + __IO uint32_t BPR4; /*!< Battery powered domain register */ + __IO uint32_t BPR5; /*!< Battery powered domain register */ + __IO uint32_t BPR6; /*!< Battery powered domain register */ + __IO uint32_t BPR7; /*!< Battery powered domain register */ + __IO uint32_t BPR8; /*!< Battery powered domain register */ + __IO uint32_t BPR9; /*!< Battery powered domain register */ + __IO uint32_t BPR10; /*!< Battery powered domain register */ + __IO uint32_t BPR11; /*!< Battery powered domain register */ + __IO uint32_t BPR12; /*!< Battery powered domain register */ + __IO uint32_t BPR13; /*!< Battery powered domain register */ + __IO uint32_t BPR14; /*!< Battery powered domain register */ + __IO uint32_t BPR15; /*!< Battery powered domain register */ + __IO uint32_t BPR16; /*!< Battery powered domain register */ + __IO uint32_t BPR17; /*!< Battery powered domain register */ + __IO uint32_t BPR18; /*!< Battery powered domain register */ + __IO uint32_t BPR19; /*!< Battery powered domain register */ + __IO uint32_t BPR20; /*!< Battery powered domain register */ +} ERTC_TypeDef; + + +/* ================================================================================ */ +/* ================ EXINT ================ */ +/* ================================================================================ */ + + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ /*!< EXINT Structure */ + __IO uint32_t INTEN; /*!< Interrupt enable register */ + __IO uint32_t EVTEN; /*!< Event enable register */ + __IO uint32_t POLCFG1; /*!< Rising polarity configuration register */ + __IO uint32_t POLCFG2; /*!< Falling polarity configuration register */ + __IO uint32_t SWTRG; /*!< Software triggle register */ + __IO uint32_t INTSTS; /*!< Interrupt status register */ +} EXINT_TypeDef; + + +/* ================================================================================ */ +/* ================ FLASH ================ */ +/* ================================================================================ */ + + +/** + * @brief Flash memory controler (FLASH) + */ + +typedef struct +{ /*!< FLASH Structure */ + __IO uint32_t PSR; /*!< Performance selection register */ + __IO uint32_t UNLOCK; /*!< Unlock register */ + __IO uint32_t USD_UNLOCK; /*!< USD unlock register */ + __IO uint32_t STS; /*!< Status register */ + __IO uint32_t CTRL; /*!< Control register */ + __IO uint32_t ADDR; /*!< Address register */ + __IO uint32_t RESERVED0; + __IO uint32_t USD; /*!< User system data register */ + __IO uint32_t EPPS; /*!< Erase/program protection status register */ + __IO uint32_t RESERVED1[20]; + __IO uint32_t SLIB_STS0; /*!< sLib status 0 register */ + __IO uint32_t SLIB_STS1; /*!< sLib status 1 register */ + __IO uint32_t SLIB_PWD_CLR; /*!< SLIB password clear register */ + __IO uint32_t SLIB_MISC_STS; /*!< sLib misc status register */ + __IO uint32_t CRC_ADDR; /*!< Flash CRC data start address register */ + __IO uint32_t CRC_CTRL; /*!< Flash CRC controll register */ + __IO uint32_t CRC_CHKR; /*!< FLASH CRC check result register */ + __IO uint32_t RESERVED2[52]; + __IO uint32_t SLIB_SET_PWD; /*!< sLib password setting register */ + __IO uint32_t SLIB_SET_RANGE; /*!< Configure sLib range register */ + __IO uint32_t EM_SLIB_SET; /*!< Extension momery slib set register */ + __IO uint32_t BTM_MODE_SET; /*!< Boot memory mode setting register */ + __IO uint32_t SLIB_UNLOCK; /*!< sLib unlock register */ +} FLASH_TypeDef; + + +/* ================================================================================ */ +/* ================ GPIO ================ */ +/* ================================================================================ */ + + +/** + * @brief General purpose I/Os (GPIO) + */ + +typedef struct +{ /*!< GPIO Structure */ + __IO uint32_t CFGR; /*!< GPIO configuration register */ + __IO uint32_t OMODE; /*!< GPIO output mode register */ + __IO uint32_t ODRVR; /*!< GPIO drive capability register */ + __IO uint32_t PULL; /*!< GPIO pull-up/pull-down register */ + __IO uint32_t IDT; /*!< GPIO input data register */ + __IO uint32_t ODT; /*!< GPIO output data register */ + __IO uint32_t SCR; /*!< Port bit set/clear register */ + __IO uint32_t WPR; /*!< Port write protect register */ + __IO uint32_t MUXL; /*!< GPIO muxing function low register */ + __IO uint32_t MUXH; /*!< GPIO muxing function high register */ + __IO uint32_t CLR; /*!< GPIO bit reset register */ + __IO uint32_t TOGR; /*!< GPIO bit toggle register */ + __IO uint32_t RESERVED0[3]; + __IO uint32_t HDRV; /*!< Huge current driver */ + __IO uint32_t SRCTR; +} GPIO_TypeDef; + + +/* ================================================================================ */ +/* ================ I2C ================ */ +/* ================================================================================ */ + + +/** + * @brief Inter-integrated circuit (I2C) + */ + +typedef struct +{ /*!< I2C Structure */ + __IO uint32_t CTRL1; /*!< Control register 1 */ + __IO uint32_t CTRL2; /*!< Control register 2 */ + __IO uint32_t OADDR1; /*!< Own address register 1 */ + __IO uint32_t OADDR2; /*!< Own address register 2 */ + __IO uint32_t CLKCTRL; /*!< Clock contorl register */ + __IO uint32_t TIMEOUT; /*!< Timeout register */ + __IO uint32_t STS; /*!< Interrupt and Status register */ + __IO uint32_t CLR; /*!< Interrupt clear register */ + __IO uint32_t PEC; /*!< PEC register */ + __IO uint32_t RXDT; /*!< Receive data register */ + __IO uint32_t TXDT; /*!< Transmit data register */ +} I2C_TypeDef; + + +/* ================================================================================ */ +/* ================ PWC ================ */ +/* ================================================================================ */ + + +/** + * @brief Power control (PWC) + */ + +typedef struct +{ /*!< PWC Structure */ + __IO uint32_t CTRL; /*!< Power control register (PWC_CTRL) */ + __IO uint32_t CTRLSTS; /*!< Power control and status register (PWC_CTRLSTS) */ + __IO uint32_t RESERVED0[2]; + __IO uint32_t LDOOV; /*!< LDO output voltage register */ +} PWC_TypeDef; + + +/* ================================================================================ */ +/* ================ QSPI ================ */ +/* ================================================================================ */ + + +/** + * @brief Quad SPI Controller (QSPI) + */ + +typedef struct +{ /*!< QSPI Structure */ + __IO uint32_t CMD_W0; /*!< Command word 0 */ + __IO uint32_t CMD_W1; /*!< Command word 1 */ + __IO uint32_t CMD_W2; /*!< Command word 2 */ + __IO uint32_t CMD_W3; /*!< Command word 3 */ + __IO uint32_t CTRL; /*!< Control register */ + __IO uint32_t RESERVED0; + __IO uint32_t FIFOSTS; /*!< FIFO Status register */ + __IO uint32_t RESERVED1; + __IO uint32_t CTRL2; /*!< control register 2 */ + __IO uint32_t CMDSTS; /*!< CMD status register */ + __IO uint32_t RSTS; /*!< SPI read status register */ + __IO uint32_t FSIZE; /*!< SPI flash size */ + __IO uint32_t XIP_CMD_W0; /*!< XIP command word 0 */ + __IO uint32_t XIP_CMD_W1; /*!< XIP command word 1 */ + __IO uint32_t XIP_CMD_W2; /*!< XIP command word 2 */ + __IO uint32_t XIP_CMD_W3; /*!< XIP command word 3 */ + __IO uint32_t CTRL3; /*!< control register 3 */ + __IO uint32_t RESERVED2[3]; + __IO uint32_t REV; /*!< Revision */ + __IO uint32_t RESERVED3[43]; + __IO uint32_t DT; /*!< 32/16/8 bit data port register */ +} QSPI1_TypeDef; + + +/* ================================================================================ */ +/* ================ SCFG ================ */ +/* ================================================================================ */ + + +/** + * @brief System configuration controller (SCFG) + */ + +typedef struct +{ /*!< SCFG Structure */ + __IO uint32_t CFG1; /*!< configuration register 1 */ + __IO uint32_t CFG2; /*!< configuration register 2 */ + __IO uint32_t EXINTC[4]; /*!< external interrupt configuration register 1,2,3,4 */ + __IO uint32_t RESERVED0[5]; + __IO uint32_t UHDRV; /*!< Ultra high drive register */ +} SCFG_TypeDef; + + +/* ================================================================================ */ +/* ================ SPI ================ */ +/* ================================================================================ */ + + +/** + * @brief Serial peripheral interface (SPI) + */ + +typedef struct +{ /*!< SPI Structure */ + __IO uint32_t CTRL1; /*!< control register 1 */ + __IO uint32_t CTRL2; /*!< control register 2 */ + __IO uint32_t STS; /*!< status register */ + __IO uint32_t DT; /*!< data register */ + __IO uint32_t CPOLY; /*!< CRC polynomial register */ + __IO uint32_t RCRC; /*!< Receive CRC register */ + __IO uint32_t TCRC; /*!< Transmit CRC register */ + __IO uint32_t I2SCTRL; /*!< I2S control register */ + __IO uint32_t I2SCLK; /*!< I2S clock register */ + __IO uint32_t RESERVED1[3]; + __IO uint32_t MISC1; /*!< I2S additional register */ +} SPI_TypeDef; + + +/* ================================================================================ */ +/* ================ TMR ================ */ +/* ================================================================================ */ + + +/** + * @brief timer (TMR) + */ + +typedef struct +{ /*!< TMR Structure */ + __IO uint32_t CTRL1; /*!< Control register 1 */ + __IO uint32_t CTRL2; /*!< Control register 2 */ + __IO uint32_t STCTRL; /*!< Subordinate TMR control register */ + __IO uint32_t IDEN; /*!< Interrupt/DMA enable register */ + __IO uint32_t ISTS; /*!< Interrupt status register */ + __IO uint32_t SWEVT; /*!< Software event register */ + __IO uint32_t CM1; /*!< Channel mode register 1 */ + __IO uint32_t CM2; /*!< Channel mode register 2 */ + __IO uint32_t CCTRL; /*!< Channel control register */ + __IO uint32_t CVAL; /*!< Counter value */ + __IO uint32_t DIV; /*!< Divider value */ + __IO uint32_t PR; /*!< Period value */ + __IO uint32_t RPR; /*!< Repetition of period value */ + __IO uint32_t C1DT; /*!< Channel 1 data register */ + __IO uint32_t C2DT; /*!< Channel 2 data register */ + __IO uint32_t C3DT; /*!< Channel 3 data register */ + __IO uint32_t C4DT; /*!< Channel 4 data register */ + __IO uint32_t BRK; /*!< Brake register */ + __IO uint32_t DMACTRL; /*!< DMA control register */ + __IO uint32_t DMADT; /*!< DMA data register */ + __IO uint32_t RMP; /*!< TMR input remap register */ + __IO uint32_t RESERVED0[7]; + __IO uint32_t CM3; /*!< Channel output mode register */ + __IO uint32_t C5DT; /*!< Channel 5 data register */ +} TMR_TypeDef; + + +/* ================================================================================ */ +/* ================ USART ================ */ +/* ================================================================================ */ + + +/** + * @brief Universal synchronous asynchronous receiver transmitter (USART) + */ + +typedef struct +{ /*!< USART Structure */ + __IO uint32_t STS; /*!< Status register */ + __IO uint32_t DT; /*!< Data register */ + __IO uint32_t BAUDR; /*!< Baud rate register */ + __IO uint32_t CTRL1; /*!< Control register 1 */ + __IO uint32_t CTRL2; /*!< Control register 2 */ + __IO uint32_t CTRL3; /*!< Control register 3 */ + __IO uint32_t GDIV; /*!< Guard time and division register */ + __IO uint32_t RTOV; /*!< Receiver time out value register */ + __IO uint32_t IFC; /*!< Interruption flag clear register */ +} USART_TypeDef; + + +/* ================================================================================ */ +/* ================ WDT ================ */ +/* ================================================================================ */ + + +/** + * @brief Watchdog (WDT) + */ + +typedef struct +{ /*!< WDT Structure */ + __IO uint32_t CMD; /*!< Command register */ + __IO uint32_t DIV; /*!< Division register */ + __IO uint32_t RLD; /*!< Reload register */ + __IO uint32_t STS; /*!< Status register */ + __IO uint32_t WIN; /*!< Window register */ +} WDT_TypeDef; + + + +/* ================================================================================ */ +/* ================ WWDT ================ */ +/* ================================================================================ */ + + +/** + * @brief Window watchdog (WWDT) + */ + +typedef struct +{ /*!< WWDT Structure */ + __IO uint32_t CTRL; /*!< Control register */ + __IO uint32_t CFG; /*!< Configuration register */ + __IO uint32_t STS; /*!< Status register */ +} WWDT_TypeDef; + + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ + +#define QSPI2_MEM_BASE ((uint32_t)0xB0000000) +#define QSPI2_REG_BASE ((uint32_t)0xA0002000) +#define QSPI1_REG_BASE ((uint32_t)0xA0001000) +#define QSPI1_MEM_BASE ((uint32_t)0x90000000) +#define PERIPH_BASE ((uint32_t)0x40000000) +#define SRAM_BB_BASE ((uint32_t)0x22000000) +#define PERIPH_BB_BASE ((uint32_t)0x42000000) +#define SRAM_BASE ((uint32_t)0x20000000) +#define USD_BASE ((uint32_t)0x1FFFF800) +#define FLASH_BASE ((uint32_t)0x08000000) + +#define DEBUG_BASE ((uint32_t)0xE0042000) + +#define APB1PERIPH_BASE (PERIPH_BASE) +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHBPERIPH1_BASE (PERIPH_BASE + 0x20000) +#define AHBPERIPH2_BASE (PERIPH_BASE + 0x10000000) + +/* apb1 bus base address */ +#define UART8_BASE (APB1PERIPH_BASE + 0x7C00) +#define UART7_BASE (APB1PERIPH_BASE + 0x7800) +#define PWC_BASE (APB1PERIPH_BASE + 0x7000) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400) +#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define USART5_BASE (APB1PERIPH_BASE + 0x5000) +#define USART4_BASE (APB1PERIPH_BASE + 0x4C00) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define WDT_BASE (APB1PERIPH_BASE + 0x3000) +#define WWDT_BASE (APB1PERIPH_BASE + 0x2C00) +#define ERTC_BASE (APB1PERIPH_BASE + 0x2800) +#define TMR14_BASE (APB1PERIPH_BASE + 0x2000) +#define TMR13_BASE (APB1PERIPH_BASE + 0x1C00) +#define TMR7_BASE (APB1PERIPH_BASE + 0x1400) +#define TMR6_BASE (APB1PERIPH_BASE + 0x1000) +#define TMR4_BASE (APB1PERIPH_BASE + 0x0800) +#define TMR3_BASE (APB1PERIPH_BASE + 0x0400) +#define TMR2_BASE (APB1PERIPH_BASE + 0x0000) +/* apb2 bus base address */ +#define OTGHS_PHY_BASE (APB2PERIPH_BASE + 0x7C00) +#define ACC_BASE (APB2PERIPH_BASE + 0x7400) +#define I2SF5_BASE (APB2PERIPH_BASE + 0x5000) +#define TMR11_BASE (APB2PERIPH_BASE + 0x4800) +#define TMR10_BASE (APB2PERIPH_BASE + 0x4400) +#define TMR9_BASE (APB2PERIPH_BASE + 0x4000) +#define EXINT_BASE (APB2PERIPH_BASE + 0x3C00) +#define SCFG_BASE (APB2PERIPH_BASE + 0x3800) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2000) +#define ADCCOM_BASE (APB2PERIPH_BASE + 0x2300) +#define USART6_BASE (APB2PERIPH_BASE + 0x1400) +#define USART1_BASE (APB2PERIPH_BASE + 0x1000) +#define TMR1_BASE (APB2PERIPH_BASE + 0x0000) +/* ahb bus base address */ +#define GPIOF_BASE (AHBPERIPH1_BASE + 0x1400) +#define GPIOD_BASE (AHBPERIPH1_BASE + 0x0C00) +#define GPIOC_BASE (AHBPERIPH1_BASE + 0x0800) +#define GPIOB_BASE (AHBPERIPH1_BASE + 0x0400) +#define GPIOA_BASE (AHBPERIPH1_BASE + 0x0000) + +#define DMA1_BASE (AHBPERIPH1_BASE + 0x6000) +#define DMA1_CHANNEL1_BASE (DMA1_BASE + 0x0008) +#define DMA1_CHANNEL2_BASE (DMA1_BASE + 0x001C) +#define DMA1_CHANNEL3_BASE (DMA1_BASE + 0x0030) +#define DMA1_CHANNEL4_BASE (DMA1_BASE + 0x0044) +#define DMA1_CHANNEL5_BASE (DMA1_BASE + 0x0058) +#define DMA1_CHANNEL6_BASE (DMA1_BASE + 0x006C) +#define DMA1_CHANNEL7_BASE (DMA1_BASE + 0x0080) + +#define DMA1MUX_BASE (DMA1_BASE + 0x0104) +#define DMA1MUX_CHANNEL1_BASE (DMA1MUX_BASE) +#define DMA1MUX_CHANNEL2_BASE (DMA1MUX_BASE + 0x0004) +#define DMA1MUX_CHANNEL3_BASE (DMA1MUX_BASE + 0x0008) +#define DMA1MUX_CHANNEL4_BASE (DMA1MUX_BASE + 0x000C) +#define DMA1MUX_CHANNEL5_BASE (DMA1MUX_BASE + 0x0010) +#define DMA1MUX_CHANNEL6_BASE (DMA1MUX_BASE + 0x0014) +#define DMA1MUX_CHANNEL7_BASE (DMA1MUX_BASE + 0x0018) + +#define DMA1MUX_GENERATOR1_BASE (DMA1_BASE + 0x0120) +#define DMA1MUX_GENERATOR2_BASE (DMA1_BASE + 0x0124) +#define DMA1MUX_GENERATOR3_BASE (DMA1_BASE + 0x0128) +#define DMA1MUX_GENERATOR4_BASE (DMA1_BASE + 0x012C) + +#define DMA2_BASE (AHBPERIPH1_BASE + 0x6400) +#define DMA2_CHANNEL1_BASE (DMA2_BASE + 0x0008) +#define DMA2_CHANNEL2_BASE (DMA2_BASE + 0x001C) +#define DMA2_CHANNEL3_BASE (DMA2_BASE + 0x0030) +#define DMA2_CHANNEL4_BASE (DMA2_BASE + 0x0044) +#define DMA2_CHANNEL5_BASE (DMA2_BASE + 0x0058) +#define DMA2_CHANNEL6_BASE (DMA2_BASE + 0x006C) +#define DMA2_CHANNEL7_BASE (DMA2_BASE + 0x0080) + +#define DMA2MUX_BASE (DMA2_BASE + 0x0104) +#define DMA2MUX_CHANNEL1_BASE (DMA2MUX_BASE) +#define DMA2MUX_CHANNEL2_BASE (DMA2MUX_BASE + 0x0004) +#define DMA2MUX_CHANNEL3_BASE (DMA2MUX_BASE + 0x0008) +#define DMA2MUX_CHANNEL4_BASE (DMA2MUX_BASE + 0x000C) +#define DMA2MUX_CHANNEL5_BASE (DMA2MUX_BASE + 0x0010) +#define DMA2MUX_CHANNEL6_BASE (DMA2MUX_BASE + 0x0014) +#define DMA2MUX_CHANNEL7_BASE (DMA2MUX_BASE + 0x0018) + +#define DMA2MUX_GENERATOR1_BASE (DMA2_BASE + 0x0120) +#define DMA2MUX_GENERATOR2_BASE (DMA2_BASE + 0x0124) +#define DMA2MUX_GENERATOR3_BASE (DMA2_BASE + 0x0128) +#define DMA2MUX_GENERATOR4_BASE (DMA2_BASE + 0x012C) + +#define FLASH_REG_BASE (AHBPERIPH1_BASE + 0x3C00) +#define CRM_BASE (AHBPERIPH1_BASE + 0x3800) +#define CRC_BASE (AHBPERIPH1_BASE + 0x3000) +#define OTGHS_BASE (AHBPERIPH1_BASE + 0x20000) +#define OTGFS1_BASE (AHBPERIPH2_BASE + 0x00000) + +/** + * @} + */ + + +/** @addtogroup Peripheral_instance + * @{ + */ + +#define EXINT ((EXINT_TypeDef *) EXINT_BASE) +#define CRM ((CRM_TypeDef *) CRM_BASE) +#define PWC ((PWC_TypeDef *) PWC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_REG_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define SCFG ((SCFG_TypeDef *) SCFG_BASE) +#define TMR1 ((TMR_TypeDef *) TMR1_BASE) +#define TMR2 ((TMR_TypeDef *) TMR2_BASE) +#define TMR3 ((TMR_TypeDef *) TMR3_BASE) +#define TMR4 ((TMR_TypeDef *) TMR4_BASE) +#define TMR6 ((TMR_TypeDef *) TMR6_BASE) +#define TMR7 ((TMR_TypeDef *) TMR7_BASE) +#define TMR9 ((TMR_TypeDef *) TMR9_BASE) +#define TMR10 ((TMR_TypeDef *) TMR10_BASE) +#define TMR11 ((TMR_TypeDef *) TMR11_BASE) +#define TMR13 ((TMR_TypeDef *) TMR13_BASE) +#define TMR14 ((TMR_TypeDef *) TMR14_BASE) +#define DEBUGMCU ((DEBUG_TypeDef *) DEBUG_BASE) +#define DEBUG ((DEBUG_TypeDef *) DEBUG_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA1_CHANNEL1 ((DMA_Channel_TypeDef *) DMA1_CHANNEL1_BASE) +#define DMA1_CHANNEL2 ((DMA_Channel_TypeDef *) DMA1_CHANNEL2_BASE) +#define DMA1_CHANNEL3 ((DMA_Channel_TypeDef *) DMA1_CHANNEL3_BASE) +#define DMA1_CHANNEL4 ((DMA_Channel_TypeDef *) DMA1_CHANNEL4_BASE) +#define DMA1_CHANNEL5 ((DMA_Channel_TypeDef *) DMA1_CHANNEL5_BASE) +#define DMA1_CHANNEL6 ((DMA_Channel_TypeDef *) DMA1_CHANNEL6_BASE) +#define DMA1_CHANNEL7 ((DMA_Channel_TypeDef *) DMA1_CHANNEL7_BASE) +#define DMA2_CHANNEL1 ((DMA_Channel_TypeDef *) DMA2_CHANNEL1_BASE) +#define DMA2_CHANNEL2 ((DMA_Channel_TypeDef *) DMA2_CHANNEL2_BASE) +#define DMA2_CHANNEL3 ((DMA_Channel_TypeDef *) DMA2_CHANNEL3_BASE) +#define DMA2_CHANNEL4 ((DMA_Channel_TypeDef *) DMA2_CHANNEL4_BASE) +#define DMA2_CHANNEL5 ((DMA_Channel_TypeDef *) DMA2_CHANNEL5_BASE) +#define DMA2_CHANNEL6 ((DMA_Channel_TypeDef *) DMA2_CHANNEL6_BASE) +#define DMA2_CHANNEL7 ((DMA_Channel_TypeDef *) DMA2_CHANNEL7_BASE) +#define DMA1MUX_CHANNEL1 ((DMAMUX_Channel_TypeDef *) DMA1MUX_CHANNEL1_BASE) +#define DMA1MUX_CHANNEL2 ((DMAMUX_Channel_TypeDef *) DMA1MUX_CHANNEL2_BASE) +#define DMA1MUX_CHANNEL3 ((DMAMUX_Channel_TypeDef *) DMA1MUX_CHANNEL3_BASE) +#define DMA1MUX_CHANNEL4 ((DMAMUX_Channel_TypeDef *) DMA1MUX_CHANNEL4_BASE) +#define DMA1MUX_CHANNEL5 ((DMAMUX_Channel_TypeDef *) DMA1MUX_CHANNEL5_BASE) +#define DMA1MUX_CHANNEL6 ((DMAMUX_Channel_TypeDef *) DMA1MUX_CHANNEL6_BASE) +#define DMA1MUX_CHANNEL7 ((DMAMUX_Channel_TypeDef *) DMA1MUX_CHANNEL7_BASE) +#define DMA2MUX_CHANNEL1 ((DMAMUX_Channel_TypeDef *) DMA2MUX_CHANNEL1_BASE) +#define DMA2MUX_CHANNEL2 ((DMAMUX_Channel_TypeDef *) DMA2MUX_CHANNEL2_BASE) +#define DMA2MUX_CHANNEL3 ((DMAMUX_Channel_TypeDef *) DMA2MUX_CHANNEL3_BASE) +#define DMA2MUX_CHANNEL4 ((DMAMUX_Channel_TypeDef *) DMA2MUX_CHANNEL4_BASE) +#define DMA2MUX_CHANNEL5 ((DMAMUX_Channel_TypeDef *) DMA2MUX_CHANNEL5_BASE) +#define DMA2MUX_CHANNEL6 ((DMAMUX_Channel_TypeDef *) DMA2MUX_CHANNEL6_BASE) +#define DMA2MUX_CHANNEL7 ((DMAMUX_Channel_TypeDef *) DMA2MUX_CHANNEL7_BASE) +#define DMA1MUX_GENERATOR1 ((DMAMUX_Generator_TypeDef *) DMA1MUX_GENERATOR1_BASE) +#define DMA1MUX_GENERATOR2 ((DMAMUX_Generator_TypeDef *) DMA1MUX_GENERATOR2_BASE) +#define DMA1MUX_GENERATOR3 ((DMAMUX_Generator_TypeDef *) DMA1MUX_GENERATOR3_BASE) +#define DMA1MUX_GENERATOR4 ((DMAMUX_Generator_TypeDef *) DMA1MUX_GENERATOR4_BASE) +#define DMA2MUX_GENERATOR1 ((DMAMUX_Generator_TypeDef *) DMA2MUX_GENERATOR1_BASE) +#define DMA2MUX_GENERATOR2 ((DMAMUX_Generator_TypeDef *) DMA2MUX_GENERATOR2_BASE) +#define DMA2MUX_GENERATOR3 ((DMAMUX_Generator_TypeDef *) DMA2MUX_GENERATOR3_BASE) +#define DMA2MUX_GENERATOR4 ((DMAMUX_Generator_TypeDef *) DMA2MUX_GENERATOR4_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADCCOM ((ADCCOM_TypeDef *) ADCCOM_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) USART4_BASE) +#define UART5 ((USART_TypeDef *) USART5_BASE) +#define USART6 ((USART_TypeDef *) USART6_BASE) +#define UART7 ((USART_TypeDef *) UART7_BASE) +#define UART8 ((USART_TypeDef *) UART8_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define I2SF5 ((SPI_TypeDef *) I2SF5_BASE) +#define ERTC ((ERTC_TypeDef *)ERTC_BASE) + +/** + * @} + */ + +/** @defgroup FLASH_unlock_keys + * @brief flash unlock keys + * @{ + */ + +#define FLASH_UNLOCK_KEY1 ((uint32_t)0x45670123) /*!< flash operation unlock order key1 */ +#define FLASH_UNLOCK_KEY2 ((uint32_t)0xCDEF89AB) /*!< flash operation unlock order key2 */ +#define FAP_RELIEVE_KEY ((uint16_t)0x00A5) /*!< flash fap relieve key val */ +#define FAP_HIGH_LEVEL_KEY ((uint16_t)0x00CC) /*!< flash fap high level enable key val */ +#define SLIB_UNLOCK_KEY ((uint32_t)0xA35F6D24) /*!< flash slib operation unlock order key */ + +#define FLASHSIZE_BASE ((uint32_t)0x1FFFF7E0U) /*!< FLASH Size register base address */ +#define UID_BASE ((uint32_t)0x1FFFF7E8U) /*!< Unique device ID register base address */ + +/** + * @} + */ + + +/** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + + +/* =========================================================================================================================== */ +/* ================ ADC ================ */ +/* =========================================================================================================================== */ + +/****************** Bit definition for ADC_STS register ***************/ +#define ADC_STS_VMOR (0x1U << 0) +#define ADC_STS_OCCC (0x1U << 1) +#define ADC_STS_CCE (0x1U << 1) +#define ADC_STS_PCCE (0x1U << 2) +#define ADC_STS_PCCS (0x1U << 3) +#define ADC_STS_OCCS (0x1U << 4) + +/****************** Bit definition for ADC_CTRL1 register ***************/ +#define ADC_CTRL1_CCEIEN (0x1U << 5) +#define ADC_CTRL1_VMORIEN (0x1U << 6) +#define ADC_CTRL1_PCCEIEN (0x1U << 7) +#define ADC_CTRL1_SQEN (0x1U << 8) +#define ADC_CTRL1_VMSGEN (0x1U << 9) +#define ADC_CTRL1_PCAUTOEN (0x1U << 10) +#define ADC_CTRL1_OCPEN (0x1U << 11) +#define ADC_CTRL1_PCPEN (0x1U << 12) +#define ADC_CTRL1_PCVMEN (0x1U << 22) +#define ADC_CTRL1_OCVMEN (0x1U << 23) +#define ADC_CTRL1_OCCOIE (0x1U << 26) + +/****************** Bit definition for ADC_CTRL2 register *******************/ +#define ADC_CTRL2_ADCEN (0x1U << 0) +#define ADC_CTRL2_RPEN (0x1U << 1) +#define ADC_CTRL2_ADCAL (0x1U << 2) +#define ADC_CTRL2_ADCALINIT (0x1U << 3) +#define ADC_CTRL2_OCDMAEN (0x1U << 8) +#define ADC_CTRL2_DTALIGN (0x1U << 11) +#define ADC_CTRL2_DTALIGN_R (0x0U << 11) +#define ADC_CTRL2_DTALIGN_L (0x1U << 11) +#define ADC_CTRL2_PCTEN (0x1U << 15) +#define ADC_CTRL2_OCTEN (0x1U << 20) +#define ADC_CTRL2_PCSWTRG (0x1U << 21) +#define ADC_CTRL2_OCSWTRG (0x1U << 22) +#define ADC_CTRL2_ITSRVEN (0x1U << 23) + +/****************** Bit definition for ADC_VMHB register ***************/ +#define ADC_VMHB_HB (0xFFFFU << 0) + +/****************** Bit definition for ADC_VMLB register ***************/ +#define ADC_VMLB_LB (0x0000U << 0) + + +/* =========================================================================================================================== */ +/* ================ CRM ================ */ +/* =========================================================================================================================== */ +/****************** Bit definition for CRM_CTRL register *****************/ +#define CRM_CTRL_HICKEN (0x1U << 0) +#define CRM_CTRL_HICKSTBL (0x1U << 1) +#define CRM_CTRL_HICKTRIM (0x3FU << 2) +#define CRM_CTRL_HEXTEN (0x1U << 16) +#define CRM_CTRL_HEXTSTBL (0x1U << 17) +#define CRM_CTRL_HEXTBYPS (0x1U << 18) +#define CRM_CTRL_CFDEN (0x1U << 19) +#define CRM_CTRL_PLLEN (0x1U << 24) +#define CRM_CTRL_PLLSTBL (0x1U << 25) +#define CRM_CTRL_PLLUSTBL (0x1U << 26) + +/****************** Bit definition for CRM_PLLCFG register *****************/ +#define CRM_PLLCFG_PLLUEN (0x1U << 29) +#define CRM_PLLCFG_PLLRCS (0x1U << 30) + +/****************** Bit definition for CRM_CFG register ******************/ +#define CRM_CFG_SCLKSEL (0x3U << 0) +#define CRM_CFG_SCLK_HICK (0x0U << 0) +#define CRM_CFG_SCLK_HEXT (0x1U << 0) +#define CRM_CFG_SCLK_PLL (0x2U << 0) +#define CRM_CFG_SCLKSTS (0x3U << 2) +#define CRM_CFG_SCLKSTS_HICK (0x0U << 2) +#define CRM_CFG_SCLKSTS_HEXT (0x1U << 2) +#define CRM_CFG_SCLKSTS_PLL (0x2U << 2) + +/***************** Bit definition for CRM_AHBRST1 register ***************/ +#define CRM_AHBRST1_GPIOARST (0x1U << 0) +#define CRM_AHBRST1_GPIOBRST (0x1U << 1) +#define CRM_AHBRST1_GPIOCRST (0x1U << 2) +#define CRM_AHBRST1_GPIODRST (0x1U << 3) +#define CRM_AHBRST1_GPIOFRST (0x1U << 5) +#define CRM_AHBRST1_CRCRST (0x1U << 12) +#define CRM_AHBRST1_DMA1RST (0x1U << 22) +#define CRM_AHBRST1_DMA2RST (0x1U << 24) +#define CRM_AHBRST1_OTGHSRST (0x1U << 29) + +/***************** Bit definition for CRM_AHBRST2 register ***************/ +#define CRM_AHBRST2_OTGFS1RST (0x1U << 7) + +/***************** Bit definition for CRM_AHBRST3 register ***************/ +#define CRM_AHBRST3_QSPI1RST (0x1U << 1) + +/***************** Bit definition for CRM_APB1RST register ***************/ +#define CRM_APB1RST_TMR2RST (0x1U << 0) +#define CRM_APB1RST_TMR3RST (0x1U << 1) +#define CRM_APB1RST_TMR4RST (0x1U << 2) +#define CRM_APB1RST_TMR6RST (0x1U << 4) +#define CRM_APB1RST_TMR7RST (0x1U << 5) +#define CRM_APB1RST_TMR13RST (0x1U << 7) +#define CRM_APB1RST_TMR14RST (0x1U << 8) +#define CRM_APB1RST_WWDTRST (0x1U << 11) +#define CRM_APB1RST_SPI2RST (0x1U << 14) +#define CRM_APB1RST_SPI3RST (0x1U << 15) +#define CRM_APB1RST_USART2RST (0x1U << 17) +#define CRM_APB1RST_USART3RST (0x1U << 18) +#define CRM_APB1RST_USART4RST (0x1U << 19) +#define CRM_APB1RST_USART5RST (0x1U << 20) +#define CRM_APB1RST_I2C1RST (0x1U << 21) +#define CRM_APB1RST_I2C2RST (0x1U << 22) +#define CRM_APB1RST_I2C3RST (0x1U << 23) +#define CRM_APB1RST_CAN1RST (0x1U << 25) +#define CRM_APB1RST_PWCRST (0x1U << 28) +#define CRM_APB1RST_UART7RST (0x1U << 30) +#define CRM_APB1RST_UART8RST (0x1U << 31) + +/***************** Bit definition for CRM_APB2RST register ***************/ +#define CRM_APB2RST_TMR1RST (0x1U << 0) +#define CRM_APB2RST_USART1RST (0x1U << 4) +#define CRM_APB2RST_USART6RST (0x1U << 5) +#define CRM_APB2RST_ADC1RST (0x1U << 8) +#define CRM_APB2RST_SPI1RST (0x1U << 12) +#define CRM_APB2RST_SCFGRST (0x1U << 14) +#define CRM_APB2RST_TMR9RST (0x1U << 16) +#define CRM_APB2RST_TMR10RST (0x1U << 17) +#define CRM_APB2RST_TMR11RST (0x1U << 18) +#define CRM_APB2RST_I2SF5RST (0x1U << 20) +#define CRM_APB2RST_ACCRST (0x1U << 29) + +/***************** Bit definition for CRM_AHBEN1 register ***************/ +#define CRM_AHBEN1_GPIOAEN (0x1U << 0) +#define CRM_AHBEN1_GPIOBEN (0x1U << 1) +#define CRM_AHBEN1_GPIOCEN (0x1U << 2) +#define CRM_AHBEN1_GPIODEN (0x1U << 3) +#define CRM_AHBEN1_GPIOFEN (0x1U << 5) +#define CRM_AHBEN1_CRCEN (0x1U << 12) +#define CRM_AHBEN1_DMA1EN (0x1U << 22) +#define CRM_AHBEN1_DMA2EN (0x1U << 24) +#define CRM_AHBEN1_OTGHSEN (0x1U << 29) + +/***************** Bit definition for CRM_AHBEN2 register ***************/ +#define CRM_AHBEN2_OTGFS1EN (0x1U << 7) + +/***************** Bit definition for CRM_AHBEN3 register ***************/ +#define CRM_AHBEN3_QSPI1EN (0x1U << 1) + +/***************** Bit definition for CRM_APB1EN register ***************/ +#define CRM_APB1EN_TMR2EN (0x1U << 0) +#define CRM_APB1EN_TMR3EN (0x1U << 1) +#define CRM_APB1EN_TMR4EN (0x1U << 2) +#define CRM_APB1EN_TMR6EN (0x1U << 4) +#define CRM_APB1EN_TMR7EN (0x1U << 5) +#define CRM_APB1EN_TMR13EN (0x1U << 7) +#define CRM_APB1EN_TMR14EN (0x1U << 8) +#define CRM_APB1EN_WWDTEN (0x1U << 11) +#define CRM_APB1EN_SPI2EN (0x1U << 14) +#define CRM_APB1EN_SPI3EN (0x1U << 15) +#define CRM_APB1EN_USART2EN (0x1U << 17) +#define CRM_APB1EN_USART3EN (0x1U << 18) +#define CRM_APB1EN_USART4EN (0x1U << 19) +#define CRM_APB1EN_USART5EN (0x1U << 20) +#define CRM_APB1EN_I2C1EN (0x1U << 21) +#define CRM_APB1EN_I2C2EN (0x1U << 22) +#define CRM_APB1EN_I2C3EN (0x1U << 23) +#define CRM_APB1EN_CAN1EN (0x1U << 25) +#define CRM_APB1EN_PWCEN (0x1U << 28) +#define CRM_APB1EN_UART7EN (0x1U << 30) +#define CRM_APB1EN_UART8EN (0x1U << 31) + +/***************** Bit definition for CRM_APB2EN register ***************/ +#define CRM_APB2EN_TMR1EN (0x1U << 0) +#define CRM_APB2EN_USART1EN (0x1U << 4) +#define CRM_APB2EN_USART6EN (0x1U << 5) +#define CRM_APB2EN_ADC1EN (0x1U << 8) +#define CRM_APB2EN_SPI1EN (0x1U << 12) +#define CRM_APB2EN_SCFGEN (0x1U << 14) +#define CRM_APB2EN_TMR9EN (0x1U << 16) +#define CRM_APB2EN_TMR10EN (0x1U << 17) +#define CRM_APB2EN_TMR11EN (0x1U << 18) +#define CRM_APB2EN_I2SF5EN (0x1U << 20) +#define CRM_APB2EN_ACCEN (0x1U << 29) + +/***************** Bit definition for CRM_AHBLPEN1 register ***************/ +#define CRM_AHBLPEN1_GPIOALPEN (0x1U << 0) +#define CRM_AHBLPEN1_GPIOBLPEN (0x1U << 1) +#define CRM_AHBLPEN1_GPIOCLPEN (0x1U << 2) +#define CRM_AHBLPEN1_GPIODLPEN (0x1U << 3) +#define CRM_AHBLPEN1_GPIOFLPEN (0x1U << 5) +#define CRM_AHBLPEN1_CRCLPEN (0x1U << 12) +#define CRM_AHBLPEN1_DMA1LPEN (0x1U << 22) +#define CRM_AHBLPEN1_DMA2LPEN (0x1U << 24) +#define CRM_AHBLPEN1_OTGHSLPEN (0x1U << 29) + +/***************** Bit definition for CRM_AHBLPEN2 register ***************/ +#define CRM_AHBLPEN2_OTGFS1LPEN (0x1U << 7) + +/***************** Bit definition for CRM_AHBLPEN3 register ***************/ +#define CRM_AHBLPEN3_QSPI1LPEN (0x1U << 1) + +/***************** Bit definition for CRM_APB1LPEN register ***************/ +#define CRM_APB1LPEN_TMR2LPEN (0x1U << 0) +#define CRM_APB1LPEN_TMR3LPEN (0x1U << 1) +#define CRM_APB1LPEN_TMR4LPEN (0x1U << 2) +#define CRM_APB1LPEN_TMR6LPEN (0x1U << 4) +#define CRM_APB1LPEN_TMR7LPEN (0x1U << 5) +#define CRM_APB1LPEN_TMR13LPEN (0x1U << 7) +#define CRM_APB1LPEN_TMR14LPEN (0x1U << 8) +#define CRM_APB1LPEN_WWDTLPEN (0x1U << 11) +#define CRM_APB1LPEN_SPI2LPEN (0x1U << 14) +#define CRM_APB1LPEN_SPI3LPEN (0x1U << 15) +#define CRM_APB1LPEN_USART2LPEN (0x1U << 17) +#define CRM_APB1LPEN_USART3LPEN (0x1U << 18) +#define CRM_APB1LPEN_USART4LPEN (0x1U << 19) +#define CRM_APB1LPEN_USART5LPEN (0x1U << 20) +#define CRM_APB1LPEN_I2C1LPEN (0x1U << 21) +#define CRM_APB1LPEN_I2C2LPEN (0x1U << 22) +#define CRM_APB1LPEN_I2C3LPEN (0x1U << 23) +#define CRM_APB1LPEN_CAN1LPEN (0x1U << 25) +#define CRM_APB1LPEN_PWCLPEN (0x1U << 28) +#define CRM_APB1LPEN_UART7LPEN (0x1U << 30) +#define CRM_APB1LPEN_UART8LPEN (0x1U << 31) + +/***************** Bit definition for CRM_APB2LPEN register ***************/ +#define CRM_APB2LPEN_TMR1LPEN (0x1U << 0) +#define CRM_APB2LPEN_USART1LPEN (0x1U << 4) +#define CRM_APB2LPEN_USART6LPEN (0x1U << 5) +#define CRM_APB2LPEN_ADC1LPEN (0x1U << 8) +#define CRM_APB2LPEN_SPI1LPEN (0x1U << 12) +#define CRM_APB2LPEN_SCFGLPEN (0x1U << 14) +#define CRM_APB2LPEN_TMR9LPEN (0x1U << 16) +#define CRM_APB2LPEN_TMR10LPEN (0x1U << 17) +#define CRM_APB2LPEN_TMR11LPEN (0x1U << 18) +#define CRM_APB2LPEN_I2SF5LPEN (0x1U << 20) +#define CRM_APB2LPEN_ACCLPEN (0x1U << 29) + +/****************** Bit definition for CRM_BPDC register *****************/ +#define CRM_BPDC_LEXTEN (0x1U << 0) +#define CRM_BPDC_LEXTSTBL (0x1U << 1) +#define CRM_BPDC_LEXTBYPS (0x1U << 2) +#define CRM_BPDC_ERTCSEL (0x3U << 8) +#define CRM_BPDC_ERTCSEL_LEXT (0x1U << 8) +#define CRM_BPDC_ERTCSEL_LICK (0x2U << 8) +#define CRM_BPDC_ERTCSEL_HEXTDIV (0x3U << 8) +#define CRM_BPDC_ERTCEN (0x1U << 15) +#define CRM_BPDC_BPDRST (0x1U << 16) + +/****************** Bit definition for CRM_CTRLSTS register **************/ +#define CRM_CTRLSTS_LICKEN (0x1U << 0) +#define CRM_CTRLSTS_LICKSTBL (0x1U << 1) +#define CRM_CTRLSTS_RSTFC (0x1U << 24) +#define CRM_CTRLSTS_NRSTF (0x1U << 26) +#define CRM_CTRLSTS_PORRSTF (0x1U << 27) +#define CRM_CTRLSTS_SWRSTF (0x1U << 28) +#define CRM_CTRLSTS_WDTRSTF (0x1U << 29) +#define CRM_CTRLSTS_WWDTRSTF (0x1U << 30) +#define CRM_CTRLSTS_LPRSTF (0x1U << 31) + +/****************** Bit definition for CRM_OTGHS register ****************/ +#define CRM_OTGHS_USBHS_PHY12_SEL (0x1U << 4) +#define CRM_OTGHS_USBHS_PHY12_SEL_HEXT (0x0U << 4) + +/****************** Bit definition for CRM_MISC1 register ****************/ +#define CRM_MISC1_HICKDIV (0x1U << 12) +#define CRM_MISC1_HICK_TO_SCLK (0x1U << 14) + +/****************** Bit definition for CRM_MISC2 register ****************/ +#define CRM_MISC2_AUTO_STEP_EN (0x3U << 4) +#define CRM_MISC2_PLLU_USB48_SEL (0x1U << 10) +#define CRM_MISC2_PLLU_USB48_SEL_PLLU (0x0U << 10) +#define CRM_MISC2_PLLU_USB48_SEL_HICK (0x1U << 10) + + +/* =========================================================================================================================== */ +/* ================ ERTC ================ */ +/* =========================================================================================================================== */ + +/****************** Bit definition for ERTC_TIME register *******************/ +/*!< SU configuration */ +#define ERTC_TIME_SU_Pos (0U) +#define ERTC_TIME_SU_Msk (0xFU << ERTC_TIME_SU_Pos) /*!< 0x0000000F */ +#define ERTC_TIME_SU ERTC_TIME_SU_Msk /*!< SU[3:0] (Second units) */ +#define ERTC_TIME_SU_0 (0x1U << ERTC_TIME_SU_Pos) /*!< 0x00000001 */ +#define ERTC_TIME_SU_1 (0x2U << ERTC_TIME_SU_Pos) /*!< 0x00000002 */ +#define ERTC_TIME_SU_2 (0x4U << ERTC_TIME_SU_Pos) /*!< 0x00000004 */ +#define ERTC_TIME_SU_3 (0x8U << ERTC_TIME_SU_Pos) /*!< 0x00000008 */ + +/*!< ST configuration */ +#define ERTC_TIME_ST_Pos (4U) +#define ERTC_TIME_ST_Msk (0x7U << ERTC_TIME_ST_Pos) /*!< 0x00000070 */ +#define ERTC_TIME_ST ERTC_TIME_ST_Msk /*!< ST[2:0] (Second tens) */ +#define ERTC_TIME_ST_0 (0x1U << ERTC_TIME_ST_Pos) /*!< 0x00000010 */ +#define ERTC_TIME_ST_1 (0x2U << ERTC_TIME_ST_Pos) /*!< 0x00000020 */ +#define ERTC_TIME_ST_2 (0x4U << ERTC_TIME_ST_Pos) /*!< 0x00000040 */ + +/*!< MU configuration */ +#define ERTC_TIME_MU_Pos (8U) +#define ERTC_TIME_MU_Msk (0xFU << ERTC_TIME_MU_Pos) /*!< 0x00000F00 */ +#define ERTC_TIME_MU ERTC_TIME_MU_Msk /*!< MU[3:0] (Minute units) */ +#define ERTC_TIME_MU_0 (0x1U << ERTC_TIME_MU_Pos) /*!< 0x00000100 */ +#define ERTC_TIME_MU_1 (0x2U << ERTC_TIME_MU_Pos) /*!< 0x00000200 */ +#define ERTC_TIME_MU_2 (0x4U << ERTC_TIME_MU_Pos) /*!< 0x00000400 */ +#define ERTC_TIME_MU_3 (0x8U << ERTC_TIME_MU_Pos) /*!< 0x00000800 */ + +/*!< MT configuration */ +#define ERTC_TIME_MT_Pos (12U) +#define ERTC_TIME_MT_Msk (0x7U << ERTC_TIME_MT_Pos) /*!< 0x00007000 */ +#define ERTC_TIME_MT ERTC_TIME_MT_Msk /*!< MT[2:0] (Minute tens) */ +#define ERTC_TIME_MT_0 (0x1U << ERTC_TIME_MT_Pos) /*!< 0x00001000 */ +#define ERTC_TIME_MT_1 (0x2U << ERTC_TIME_MT_Pos) /*!< 0x00002000 */ +#define ERTC_TIME_MT_2 (0x4U << ERTC_TIME_MT_Pos) /*!< 0x00004000 */ + +/*!< HU configuration */ +#define ERTC_TIME_HU_Pos (16U) +#define ERTC_TIME_HU_Msk (0xFU << ERTC_TIME_HU_Pos) /*!< 0x000F0000 */ +#define ERTC_TIME_HU ERTC_TIME_HU_Msk /*!< HU[3:0] (Hour units) */ +#define ERTC_TIME_HU_0 (0x1U << ERTC_TIME_HU_Pos) /*!< 0x00010000 */ +#define ERTC_TIME_HU_1 (0x2U << ERTC_TIME_HU_Pos) /*!< 0x00020000 */ +#define ERTC_TIME_HU_2 (0x4U << ERTC_TIME_HU_Pos) /*!< 0x00040000 */ +#define ERTC_TIME_HU_3 (0x8U << ERTC_TIME_HU_Pos) /*!< 0x00080000 */ + +/*!< HT configuration */ +#define ERTC_TIME_HT_Pos (20U) +#define ERTC_TIME_HT_Msk (0x3U << ERTC_TIME_HT_Pos) /*!< 0x00300000 */ +#define ERTC_TIME_HT ERTC_TIME_HT_Msk /*!< HT[1:0] (Hour tens) */ +#define ERTC_TIME_HT_0 (0x1U << ERTC_TIME_HT_Pos) /*!< 0x00100000 */ +#define ERTC_TIME_HT_1 (0x2U << ERTC_TIME_HT_Pos) /*!< 0x00200000 */ + +#define ERTC_TIME_AMPM_Pos (22U) +#define ERTC_TIME_AMPM_Msk (0x1U << ERTC_TIME_AMPM_Pos) /*!< 0x00400000 */ +#define ERTC_TIME_AMPM ERTC_TIME_AMPM_Msk /*!< AM/PM */ + +/****************** Bit definition for ERTC_DATE register *******************/ +/*!< DU configuration */ +#define ERTC_DATE_DU_Pos (0U) +#define ERTC_DATE_DU_Msk (0xFU << ERTC_DATE_DU_Pos) /*!< 0x0000000F */ +#define ERTC_DATE_DU ERTC_DATE_DU_Msk /*!< DU[3:0] (Date units) */ +#define ERTC_DATE_DU_0 (0x1U << ERTC_DATE_DU_Pos) /*!< 0x00000001 */ +#define ERTC_DATE_DU_1 (0x2U << ERTC_DATE_DU_Pos) /*!< 0x00000002 */ +#define ERTC_DATE_DU_2 (0x4U << ERTC_DATE_DU_Pos) /*!< 0x00000004 */ +#define ERTC_DATE_DU_3 (0x8U << ERTC_DATE_DU_Pos) /*!< 0x00000008 */ + +/*!< DT configuration */ +#define ERTC_DATE_DT_Pos (4U) +#define ERTC_DATE_DT_Msk (0x3U << ERTC_DATE_DT_Pos) /*!< 0x00300000 */ +#define ERTC_DATE_DT ERTC_DATE_DT_Msk /*!< DT[1:0] (Date tens) */ +#define ERTC_DATE_DT_0 (0x1U << ERTC_DATE_DT_Pos) /*!< 0x00000010 */ +#define ERTC_DATE_DT_1 (0x2U << ERTC_DATE_DT_Pos) /*!< 0x00000020 */ + +/*!< MU configuration */ +#define ERTC_DATE_MU_Pos (8U) +#define ERTC_DATE_MU_Msk (0xFU << ERTC_DATE_MU_Pos) /*!< 0x00000F00 */ +#define ERTC_DATE_MU ERTC_DATE_MU_Msk /*!< MU[3:0] (Month units) */ +#define ERTC_DATE_MU_0 (0x1U << ERTC_DATE_MU_Pos) /*!< 0x00000100 */ +#define ERTC_DATE_MU_1 (0x2U << ERTC_DATE_MU_Pos) /*!< 0x00000200 */ +#define ERTC_DATE_MU_2 (0x4U << ERTC_DATE_MU_Pos) /*!< 0x00000400 */ +#define ERTC_DATE_MU_3 (0x8U << ERTC_DATE_MU_Pos) /*!< 0x00000800 */ + +#define ERTC_DATE_MT_Pos (12U) +#define ERTC_DATE_MT_Msk (0x1U << ERTC_DATE_MT_Pos) /*!< 0x00001000 */ +#define ERTC_DATE_MT ERTC_DATE_MT_Msk /*!< Month tens */ + +/*!< WK configuration */ +#define ERTC_DATE_WK_Pos (13U) +#define ERTC_DATE_WK_Msk (0x7U << ERTC_DATE_WK_Pos) /*!< 0x0000E000 */ +#define ERTC_DATE_WK ERTC_DATE_WK_Msk /*!< WK[2:0] (Week day) */ +#define ERTC_DATE_WK_0 (0x1U << ERTC_DATE_WK_Pos) /*!< 0x00002000 */ +#define ERTC_DATE_WK_1 (0x2U << ERTC_DATE_WK_Pos) /*!< 0x00004000 */ +#define ERTC_DATE_WK_2 (0x4U << ERTC_DATE_WK_Pos) /*!< 0x00008000 */ + +/*!< YU configuration */ +#define ERTC_DATE_YU_Pos (16U) +#define ERTC_DATE_YU_Msk (0xFU << ERTC_DATE_YU_Pos) /*!< 0x000F0000 */ +#define ERTC_DATE_YU ERTC_DATE_YU_Msk /*!< YU[3:0] (Year units) */ +#define ERTC_DATE_YU_0 (0x1U << ERTC_DATE_YU_Pos) /*!< 0x00010000 */ +#define ERTC_DATE_YU_1 (0x2U << ERTC_DATE_YU_Pos) /*!< 0x00020000 */ +#define ERTC_DATE_YU_2 (0x4U << ERTC_DATE_YU_Pos) /*!< 0x00040000 */ +#define ERTC_DATE_YU_3 (0x8U << ERTC_DATE_YU_Pos) /*!< 0x00080000 */ + +/*!< YT configuration */ +#define ERTC_DATE_YT_Pos (20U) +#define ERTC_DATE_YT_Msk (0xFU << ERTC_DATE_YT_Pos) /*!< 0x00F00000 */ +#define ERTC_DATE_YT ERTC_DATE_YT_Msk /*!< YT[3:0] (Year tens) */ +#define ERTC_DATE_YT_0 (0x1U << ERTC_DATE_YT_Pos) /*!< 0x00100000 */ +#define ERTC_DATE_YT_1 (0x2U << ERTC_DATE_YT_Pos) /*!< 0x00200000 */ +#define ERTC_DATE_YT_2 (0x4U << ERTC_DATE_YT_Pos) /*!< 0x00400000 */ +#define ERTC_DATE_YT_3 (0x8U << ERTC_DATE_YT_Pos) /*!< 0x00800000 */ + +/****************** Bit definition for ERTC_CTRL register *******************/ +/*!< WATCLK configuration */ +#define ERTC_CTRL_WATCLK_Pos (0U) +#define ERTC_CTRL_WATCLK_Msk (0x7U << ERTC_CTRL_WATCLK_Pos) /*!< 0x00000007 */ +#define ERTC_CTRL_WATCLK ERTC_CTRL_WATCLK_Msk /*!< WATCLK[2:0] (Wakeup timer clock selection) */ +#define ERTC_CTRL_WATCLK_0 (0x1U << ERTC_CTRL_WATCLK_Pos) /*!< 0x00000001 */ +#define ERTC_CTRL_WATCLK_1 (0x2U << ERTC_CTRL_WATCLK_Pos) /*!< 0x00000002 */ +#define ERTC_CTRL_WATCLK_2 (0x4U << ERTC_CTRL_WATCLK_Pos) /*!< 0x00000004 */ + +#define ERTC_CTRL_TSEDG_Pos (3U) +#define ERTC_CTRL_TSEDG_Msk (0x1U << ERTC_CTRL_TSEDG_Pos) /*!< 0x00000008 */ +#define ERTC_CTRL_TSEDG ERTC_CTRL_TSEDG_Msk /*!< Timestamp trigger edge */ +#define ERTC_CTRL_RCDEN_Pos (4U) +#define ERTC_CTRL_RCDEN_Msk (0x1U << ERTC_CTRL_RCDEN_Pos) /*!< 0x00000010 */ +#define ERTC_CTRL_RCDEN ERTC_CTRL_RCDEN_Msk /*!< Reference clock detection enable */ +#define ERTC_CTRL_DREN_Pos (5U) +#define ERTC_CTRL_DREN_Msk (0x1U << ERTC_CTRL_DREN_Pos) /*!< 0x00000020 */ +#define ERTC_CTRL_DREN ERTC_CTRL_DREN_Msk /*!< Date/time register direct read enable */ +#define ERTC_CTRL_HM_Pos (6U) +#define ERTC_CTRL_HM_Msk (0x1U << ERTC_CTRL_HM_Pos) /*!< 0x00000040 */ +#define ERTC_CTRL_HM ERTC_CTRL_HM_Msk /*!< Hour mode */ +#define ERTC_CTRL_CCALEN_Pos (7U) +#define ERTC_CTRL_CCALEN_Msk (0x1U << ERTC_CTRL_CCALEN_Pos) /*!< 0x00000080 */ +#define ERTC_CTRL_CCALEN ERTC_CTRL_CCALEN_Msk /*!< Coarse calibration enable */ +#define ERTC_CTRL_ALAEN_Pos (8U) +#define ERTC_CTRL_ALAEN_Msk (0x1U << ERTC_CTRL_ALAEN_Pos) /*!< 0x00000100 */ +#define ERTC_CTRL_ALAEN ERTC_CTRL_ALAEN_Msk /*!< Alarm A enable */ +#define ERTC_CTRL_ALBEN_Pos (9U) +#define ERTC_CTRL_ALBEN_Msk (0x1U << ERTC_CTRL_ALBEN_Pos) /*!< 0x00000200 */ +#define ERTC_CTRL_ALBEN ERTC_CTRL_ALBEN_Msk /*!< Alarm B enable */ +#define ERTC_CTRL_WATEN_Pos (10U) +#define ERTC_CTRL_WATEN_Msk (0x1U << ERTC_CTRL_WATEN_Pos) /*!< 0x00000400 */ +#define ERTC_CTRL_WATEN ERTC_CTRL_WATEN_Msk /*!< Wakeup timer enable */ +#define ERTC_CTRL_TSEN_Pos (11U) +#define ERTC_CTRL_TSEN_Msk (0x1U << ERTC_CTRL_TSEN_Pos) /*!< 0x00000800 */ +#define ERTC_CTRL_TSEN ERTC_CTRL_TSEN_Msk /*!< Timestamp enable */ +#define ERTC_CTRL_ALAIEN_Pos (12U) +#define ERTC_CTRL_ALAIEN_Msk (0x1U << ERTC_CTRL_ALAIEN_Pos) /*!< 0x00001000 */ +#define ERTC_CTRL_ALAIEN ERTC_CTRL_ALAIEN_Msk /*!< Alarm A interrupt enable */ +#define ERTC_CTRL_ALBIEN_Pos (13U) +#define ERTC_CTRL_ALBIEN_Msk (0x1U << ERTC_CTRL_ALBIEN_Pos) /*!< 0x00002000 */ +#define ERTC_CTRL_ALBIEN ERTC_CTRL_ALBIEN_Msk /*!< Alarm B interrupt enable */ +#define ERTC_CTRL_WATIEN_Pos (14U) +#define ERTC_CTRL_WATIEN_Msk (0x1U << ERTC_CTRL_WATIEN_Pos) /*!< 0x00004000 */ +#define ERTC_CTRL_WATIEN ERTC_CTRL_WATIEN_Msk /*!< Wakeup timer interrupt enable */ +#define ERTC_CTRL_TSIEN_Pos (15U) +#define ERTC_CTRL_TSIEN_Msk (0x1U << ERTC_CTRL_TSIEN_Pos) /*!< 0x000008000 */ +#define ERTC_CTRL_TSIEN ERTC_CTRL_TSIEN_Msk /*!< Timestamp interrupt enable */ +#define ERTC_CTRL_ADD1H_Pos (16U) +#define ERTC_CTRL_ADD1H_Msk (0x1U << ERTC_CTRL_ADD1H_Pos) /*!< 0x00010000 */ +#define ERTC_CTRL_ADD1H ERTC_CTRL_ADD1H_Msk /*!< Add 1 hour */ +#define ERTC_CTRL_DEC1H_Pos (17U) +#define ERTC_CTRL_DEC1H_Msk (0x1U << ERTC_CTRL_DEC1H_Pos) /*!< 0x00020000 */ +#define ERTC_CTRL_DEC1H ERTC_CTRL_DEC1H_Msk /*!< Decrease 1 hour */ +#define ERTC_CTRL_BPR_Pos (18U) +#define ERTC_CTRL_BPR_Msk (0x1U << ERTC_CTRL_BPR_Pos) /*!< 0x00040000 */ +#define ERTC_CTRL_BPR ERTC_CTRL_BPR_Msk /*!< Battery powered domain data register */ +#define ERTC_CTRL_CALOSEL_Pos (19U) +#define ERTC_CTRL_CALOSEL_Msk (0x1U << ERTC_CTRL_CALOSEL_Pos) /*!< 0x00080000 */ +#define ERTC_CTRL_CALOSEL ERTC_CTRL_CALOSEL_Msk /*!< Calibration output selection */ +#define ERTC_CTRL_OUTP_Pos (20U) +#define ERTC_CTRL_OUTP_Msk (0x1U << ERTC_CTRL_OUTP_Pos) /*!< 0x00100000 */ +#define ERTC_CTRL_OUTP ERTC_CTRL_OUTP_Msk /*!< Output polarity */ + +/*!< OUTSEL configuration */ +#define ERTC_CTRL_OUTSEL_Pos (21U) +#define ERTC_CTRL_OUTSEL_Msk (0x3U << ERTC_CTRL_OUTSEL_Pos) /*!< 0x00600000 */ +#define ERTC_CTRL_OUTSEL ERTC_CTRL_OUTSEL_Msk /*!< OUTSEL[1:0] (Output source selection) */ +#define ERTC_CTRL_OUTSEL_0 (0x1U << ERTC_CTRL_OUTSEL_Pos) /*!< 0x00200000 */ +#define ERTC_CTRL_OUTSEL_1 (0x2U << ERTC_CTRL_OUTSEL_Pos) /*!< 0x00400000 */ + +#define ERTC_CTRL_CALOEN_Pos (23U) +#define ERTC_CTRL_CALOEN_Msk (0x1U << ERTC_CTRL_CALOEN_Pos) /*!< 0x00800000 */ +#define ERTC_CTRL_CALOEN ERTC_CTRL_CALOEN_Msk /*!< Calibration output enable */ + +/******************* Bit definition for ERTC_STS register *******************/ +#define ERTC_STS_ALAWF_Pos (0U) +#define ERTC_STS_ALAWF_Msk (0x1U << ERTC_STS_ALAWF_Pos) /*!< 0x00000001 */ +#define ERTC_STS_ALAWF ERTC_STS_ALAWF_Msk /*!< Alarm A register allows write flag */ +#define ERTC_STS_ALBWF_Pos (1U) +#define ERTC_STS_ALBWF_Msk (0x1U << ERTC_STS_ALBWF_Pos) /*!< 0x00000002 */ +#define ERTC_STS_ALBWF ERTC_STS_ALBWF_Msk /*!< Alarm B register allows write flag */ +#define ERTC_STS_WATWF_Pos (2U) +#define ERTC_STS_WATWF_Msk (0x1U << ERTC_STS_WATWF_Pos) /*!< 0x00000004 */ +#define ERTC_STS_WATWF ERTC_STS_WATWF_Msk /*!< Wakeup timer register allows write flag */ +#define ERTC_STS_TADJF_Pos (3U) +#define ERTC_STS_TADJF_Msk (0x1U << ERTC_STS_TADJF_Pos) /*!< 0x00000008 */ +#define ERTC_STS_TADJF ERTC_STS_TADJF_Msk /*!< Time adjustment flag */ +#define ERTC_STS_INITF_Pos (4U) +#define ERTC_STS_INITF_Msk (0x1U << ERTC_STS_INITF_Pos) /*!< 0x00000010 */ +#define ERTC_STS_INITF ERTC_STS_INITF_Msk /*!< Calendar initialization flag */ +#define ERTC_STS_UPDF_Pos (5U) +#define ERTC_STS_UPDF_Msk (0x1U << ERTC_STS_UPDF_Pos) /*!< 0x00000020 */ +#define ERTC_STS_UPDF ERTC_STS_UPDF_Msk /*!< Calendar update flag */ +#define ERTC_STS_IMF_Pos (6U) +#define ERTC_STS_IMF_Msk (0x1U << ERTC_STS_IMF_Pos) /*!< 0x00000040 */ +#define ERTC_STS_IMF ERTC_STS_IMF_Msk /*!< Enter initialization mode flag */ +#define ERTC_STS_IMEN_Pos (7U) +#define ERTC_STS_IMEN_Msk (0x1U << ERTC_STS_IMEN_Pos) /*!< 0x00000080 */ +#define ERTC_STS_IMEN ERTC_STS_IMEN_Msk /*!< Initialization mode enable */ +#define ERTC_STS_ALAF_Pos (8U) +#define ERTC_STS_ALAF_Msk (0x1U << ERTC_STS_ALAF_Pos) /*!< 0x00000100 */ +#define ERTC_STS_ALAF ERTC_STS_ALAF_Msk /*!< Alarm clock A flag */ +#define ERTC_STS_ALBF_Pos (9U) +#define ERTC_STS_ALBF_Msk (0x1U << ERTC_STS_ALBF_Pos) /*!< 0x00000200 */ +#define ERTC_STS_ALBF ERTC_STS_ALBF_Msk /*!< Alarm clock B flag */ +#define ERTC_STS_WATF_Pos (10U) +#define ERTC_STS_WATF_Msk (0x1U << ERTC_STS_WATF_Pos) /*!< 0x00000400 */ +#define ERTC_STS_WATF ERTC_STS_WATF_Msk /*!< Wakeup timer flag */ +#define ERTC_STS_TSF_Pos (11U) +#define ERTC_STS_TSF_Msk (0x1U << ERTC_STS_TSF_Pos) /*!< 0x00000800 */ +#define ERTC_STS_TSF ERTC_STS_TSF_Msk /*!< Timestamp flag */ +#define ERTC_STS_TSOF_Pos (12U) +#define ERTC_STS_TSOF_Msk (0x1U << ERTC_STS_TSOF_Pos) /*!< 0x00001000 */ +#define ERTC_STS_TSOF ERTC_STS_TSOF_Msk /*!< Timestamp overflow flag */ +#define ERTC_STS_TP1F_Pos (13U) +#define ERTC_STS_TP1F_Msk (0x1U << ERTC_STS_TP1F_Pos) /*!< 0x00002000 */ +#define ERTC_STS_TP1F ERTC_STS_TP1F_Msk /*!< Tamper detection 1 flag */ +#define ERTC_STS_CALUPDF_Pos (16U) +#define ERTC_STS_CALUPDF_Msk (0x1U << ERTC_STS_CALUPDF_Pos) /*!< 0x00010000 */ +#define ERTC_STS_CALUPDF ERTC_STS_CALUPDF_Msk /*!< Calibration value update complete flag */ + +/******************* Bit definition for ERTC_DIV register *******************/ +#define ERTC_DIV_DIVB_Pos (0U) +#define ERTC_DIV_DIVB_Msk (0x7FFFU << ERTC_DIV_DIVB_Pos) /*!< 0x00007FFF */ +#define ERTC_DIV_DIVB ERTC_DIV_DIVB_Msk /*!< Divider B */ +#define ERTC_DIV_DIVA_Pos (16U) +#define ERTC_DIV_DIVA_Msk (0x7FU << ERTC_DIV_DIVA_Pos) /*!< 0x007F0000 */ +#define ERTC_DIV_DIVA ERTC_DIV_DIVA_Msk /*!< Divider A */ + +/******************* Bit definition for ERTC_WAT register *******************/ +#define ERTC_WAT_VAL_Pos (0U) +#define ERTC_WAT_VAL_Msk (0xFFFFU << ERTC_WAT_VAL_Pos) /*!< 0x0000FFFF */ +#define ERTC_WAT_VAL ERTC_WAT_VAL_Msk /*!< Wakeup timer reload value */ + +/****************** Bit definition for ERTC_CCAL register *******************/ +/*!< CALVAL configuration */ +#define ERTC_CCAL_CALVAL_Pos (0U) +#define ERTC_CCAL_CALVAL_Msk (0x1FU << ERTC_CCAL_CALVAL_Pos) /*!< 0x0000001F */ +#define ERTC_CCAL_CALVAL ERTC_CCAL_CALVAL_Msk /*!< CALVAL[4:0] (Calibration value) */ +#define ERTC_CCAL_CALVAL_0 (0x1U << ERTC_CCAL_CALVAL_Pos) /*!< 0x00000001 */ +#define ERTC_CCAL_CALVAL_1 (0x2U << ERTC_CCAL_CALVAL_Pos) /*!< 0x00000002 */ +#define ERTC_CCAL_CALVAL_2 (0x4U << ERTC_CCAL_CALVAL_Pos) /*!< 0x00000004 */ +#define ERTC_CCAL_CALVAL_3 (0x8U << ERTC_CCAL_CALVAL_Pos) /*!< 0x00000008 */ +#define ERTC_CCAL_CALVAL_4 (0x10U << ERTC_CCAL_CALVAL_Pos) /*!< 0x00000010 */ + +#define ERTC_CCAL_CALDIR_Pos (7U) +#define ERTC_CCAL_CALDIR_Msk (0x1U << ERTC_CCAL_CALDIR_Pos) /*!< 0x00000080 */ +#define ERTC_CCAL_CALDIR ERTC_CCAL_CALDIR_Msk /*!< Calibration direction */ + +/******************* Bit definition for ERTC_ALA register *******************/ +/*!< SU configuration */ +#define ERTC_ALA_SU_Pos (0U) +#define ERTC_ALA_SU_Msk (0xFU << ERTC_ALA_SU_Pos) /*!< 0x0000000F */ +#define ERTC_ALA_SU ERTC_ALA_SU_Msk /*!< SU[3:0] (Second units) */ +#define ERTC_ALA_SU_0 (0x1U << ERTC_ALA_SU_Pos) /*!< 0x00000001 */ +#define ERTC_ALA_SU_1 (0x2U << ERTC_ALA_SU_Pos) /*!< 0x00000002 */ +#define ERTC_ALA_SU_2 (0x4U << ERTC_ALA_SU_Pos) /*!< 0x00000004 */ +#define ERTC_ALA_SU_3 (0x8U << ERTC_ALA_SU_Pos) /*!< 0x00000008 */ + +/*!< ST configuration */ +#define ERTC_ALA_ST_Pos (4U) +#define ERTC_ALA_ST_Msk (0x7U << ERTC_ALA_ST_Pos) /*!< 0x00000070 */ +#define ERTC_ALA_ST ERTC_ALA_ST_Msk /*!< ST[2:0] (Second tens) */ +#define ERTC_ALA_ST_0 (0x1U << ERTC_ALA_ST_Pos) /*!< 0x00000010 */ +#define ERTC_ALA_ST_1 (0x2U << ERTC_ALA_ST_Pos) /*!< 0x00000020 */ +#define ERTC_ALA_ST_2 (0x4U << ERTC_ALA_ST_Pos) /*!< 0x00000040 */ + +#define ERTC_ALA_MASK1_Pos (7U) +#define ERTC_ALA_MASK1_Msk (0x1U << ERTC_ALA_MASK1_Pos) /*!< 0x00000080 */ +#define ERTC_ALA_MASK1 ERTC_ALA_MASK1_Msk /*!< Second mask */ + +/*!< MU configuration */ +#define ERTC_ALA_MU_Pos (8U) +#define ERTC_ALA_MU_Msk (0xFU << ERTC_ALA_MU_Pos) /*!< 0x00000F00 */ +#define ERTC_ALA_MU ERTC_ALA_MU_Msk /*!< MU[3:0] (Minute units) */ +#define ERTC_ALA_MU_0 (0x1U << ERTC_ALA_MU_Pos) /*!< 0x00000100 */ +#define ERTC_ALA_MU_1 (0x2U << ERTC_ALA_MU_Pos) /*!< 0x00000200 */ +#define ERTC_ALA_MU_2 (0x4U << ERTC_ALA_MU_Pos) /*!< 0x00000400 */ +#define ERTC_ALA_MU_3 (0x8U << ERTC_ALA_MU_Pos) /*!< 0x00000800 */ + +/*!< MT configuration */ +#define ERTC_ALA_MT_Pos (12U) +#define ERTC_ALA_MT_Msk (0x7U << ERTC_ALA_MT_Pos) /*!< 0x00007000 */ +#define ERTC_ALA_MT ERTC_ALA_MT_Msk /*!< MT[2:0] (Minute tens) */ +#define ERTC_ALA_MT_0 (0x1U << ERTC_ALA_MT_Pos) /*!< 0x00001000 */ +#define ERTC_ALA_MT_1 (0x2U << ERTC_ALA_MT_Pos) /*!< 0x00002000 */ +#define ERTC_ALA_MT_2 (0x4U << ERTC_ALA_MT_Pos) /*!< 0x00004000 */ + +#define ERTC_ALA_MASK2_Pos (15U) +#define ERTC_ALA_MASK2_Msk (0x1U << ERTC_ALA_MASK2_Pos) /*!< 0x00008000 */ +#define ERTC_ALA_MASK2 ERTC_ALA_MASK2_Msk /*!< Minute mask */ + +/*!< HU configuration */ +#define ERTC_ALA_HU_Pos (16U) +#define ERTC_ALA_HU_Msk (0xFU << ERTC_ALA_HU_Pos) /*!< 0x000F0000 */ +#define ERTC_ALA_HU ERTC_ALA_HU_Msk /*!< HU[3:0] (Hour units) */ +#define ERTC_ALA_HU_0 (0x1U << ERTC_ALA_HU_Pos) /*!< 0x00010000 */ +#define ERTC_ALA_HU_1 (0x2U << ERTC_ALA_HU_Pos) /*!< 0x00020000 */ +#define ERTC_ALA_HU_2 (0x4U << ERTC_ALA_HU_Pos) /*!< 0x00040000 */ +#define ERTC_ALA_HU_3 (0x8U << ERTC_ALA_HU_Pos) /*!< 0x00080000 */ + +/*!< HT configuration */ +#define ERTC_ALA_HT_Pos (20U) +#define ERTC_ALA_HT_Msk (0x3U << ERTC_ALA_HT_Pos) /*!< 0x00300000 */ +#define ERTC_ALA_HT ERTC_ALA_HT_Msk /*!< HT[1:0] (Hour tens) */ +#define ERTC_ALA_HT_0 (0x1U << ERTC_ALA_HT_Pos) /*!< 0x00100000 */ +#define ERTC_ALA_HT_1 (0x2U << ERTC_ALA_HT_Pos) /*!< 0x00200000 */ + +#define ERTC_ALA_AMPM_Pos (22U) +#define ERTC_ALA_AMPM_Msk (0x1U << ERTC_ALA_AMPM_Pos) /*!< 0x00400000 */ +#define ERTC_ALA_AMPM ERTC_ALA_AMPM_Msk /*!< AM/PM */ +#define ERTC_ALA_MASK3_Pos (23U) +#define ERTC_ALA_MASK3_Msk (0x1U << ERTC_ALA_MASK3_Pos) /*!< 0x00800000 */ +#define ERTC_ALA_MASK3 ERTC_ALA_MASK3_Msk /*!< Hour mask */ + +/*!< DU configuration */ +#define ERTC_ALA_DU_Pos (24U) +#define ERTC_ALA_DU_Msk (0xFU << ERTC_ALA_DU_Pos) /*!< 0x0F000000 */ +#define ERTC_ALA_DU ERTC_ALA_DU_Msk /*!< DU[3:0] (Date/week day units) */ +#define ERTC_ALA_DU_0 (0x1U << ERTC_ALA_DU_Pos) /*!< 0x01000000 */ +#define ERTC_ALA_DU_1 (0x2U << ERTC_ALA_DU_Pos) /*!< 0x02000000 */ +#define ERTC_ALA_DU_2 (0x4U << ERTC_ALA_DU_Pos) /*!< 0x04000000 */ +#define ERTC_ALA_DU_3 (0x8U << ERTC_ALA_DU_Pos) /*!< 0x08000000 */ + +/*!< DT configuration */ +#define ERTC_ALA_DT_Pos (28U) +#define ERTC_ALA_DT_Msk (0x3U << ERTC_ALA_DT_Pos) /*!< 0x30000000 */ +#define ERTC_ALA_DT ERTC_ALA_DT_Msk /*!< DT[1:0] (Date/week day tens) */ +#define ERTC_ALA_DT_0 (0x1U << ERTC_ALA_DT_Pos) /*!< 0x10000000 */ +#define ERTC_ALA_DT_1 (0x2U << ERTC_ALA_DT_Pos) /*!< 0x20000000 */ + +#define ERTC_ALA_WKSEL_Pos (30U) +#define ERTC_ALA_WKSEL_Msk (0x1U << ERTC_ALA_WKSEL_Pos) /*!< 0x40000000 */ +#define ERTC_ALA_WKSEL ERTC_ALA_WKSEL_Msk /*!< Date/week day select */ +#define ERTC_ALA_MASK4_Pos (31U) +#define ERTC_ALA_MASK4_Msk (0x1U << ERTC_ALA_MASK4_Pos) /*!< 0x80000000 */ +#define ERTC_ALA_MASK4 ERTC_ALA_MASK4_Msk /*!< Date/week day mask */ + +/******************* Bit definition for ERTC_ALB register *******************/ +/*!< SU configuration */ +#define ERTC_ALB_SU_Pos (0U) +#define ERTC_ALB_SU_Msk (0xFU << ERTC_ALB_SU_Pos) /*!< 0x0000000F */ +#define ERTC_ALB_SU ERTC_ALB_SU_Msk /*!< SU[3:0] (Second units) */ +#define ERTC_ALB_SU_0 (0x1U << ERTC_ALB_SU_Pos) /*!< 0x00000001 */ +#define ERTC_ALB_SU_1 (0x2U << ERTC_ALB_SU_Pos) /*!< 0x00000002 */ +#define ERTC_ALB_SU_2 (0x4U << ERTC_ALB_SU_Pos) /*!< 0x00000004 */ +#define ERTC_ALB_SU_3 (0x8U << ERTC_ALB_SU_Pos) /*!< 0x00000008 */ + +/*!< ST configuration */ +#define ERTC_ALB_ST_Pos (4U) +#define ERTC_ALB_ST_Msk (0x7U << ERTC_ALB_ST_Pos) /*!< 0x00000070 */ +#define ERTC_ALB_ST ERTC_ALB_ST_Msk /*!< ST[2:0] (Second tens) */ +#define ERTC_ALB_ST_0 (0x1U << ERTC_ALB_ST_Pos) /*!< 0x00000010 */ +#define ERTC_ALB_ST_1 (0x2U << ERTC_ALB_ST_Pos) /*!< 0x00000020 */ +#define ERTC_ALB_ST_2 (0x4U << ERTC_ALB_ST_Pos) /*!< 0x00000040 */ + +#define ERTC_ALB_MASK1_Pos (7U) +#define ERTC_ALB_MASK1_Msk (0x1U << ERTC_ALB_MASK1_Pos) /*!< 0x00000080 */ +#define ERTC_ALB_MASK1 ERTC_ALB_MASK1_Msk /*!< Second mask */ + +/*!< MU configuration */ +#define ERTC_ALB_MU_Pos (8U) +#define ERTC_ALB_MU_Msk (0xFU << ERTC_ALB_MU_Pos) /*!< 0x00000F00 */ +#define ERTC_ALB_MU ERTC_ALB_MU_Msk /*!< MU[3:0] (Minute units) */ +#define ERTC_ALB_MU_0 (0x1U << ERTC_ALB_MU_Pos) /*!< 0x00000100 */ +#define ERTC_ALB_MU_1 (0x2U << ERTC_ALB_MU_Pos) /*!< 0x00000200 */ +#define ERTC_ALB_MU_2 (0x4U << ERTC_ALB_MU_Pos) /*!< 0x00000400 */ +#define ERTC_ALB_MU_3 (0x8U << ERTC_ALB_MU_Pos) /*!< 0x00000800 */ + +/*!< MT configuration */ +#define ERTC_ALB_MT_Pos (12U) +#define ERTC_ALB_MT_Msk (0x7U << ERTC_ALB_MT_Pos) /*!< 0x00007000 */ +#define ERTC_ALB_MT ERTC_ALB_MT_Msk /*!< MT[2:0] (Minute tens) */ +#define ERTC_ALB_MT_0 (0x1U << ERTC_ALB_MT_Pos) /*!< 0x00001000 */ +#define ERTC_ALB_MT_1 (0x2U << ERTC_ALB_MT_Pos) /*!< 0x00002000 */ +#define ERTC_ALB_MT_2 (0x4U << ERTC_ALB_MT_Pos) /*!< 0x00004000 */ + +#define ERTC_ALB_MASK2_Pos (15U) +#define ERTC_ALB_MASK2_Msk (0x1U << ERTC_ALB_MASK2_Pos) /*!< 0x00008000 */ +#define ERTC_ALB_MASK2 ERTC_ALB_MASK2_Msk /*!< Minute mask */ + +/*!< HU configuration */ +#define ERTC_ALB_HU_Pos (16U) +#define ERTC_ALB_HU_Msk (0xFU << ERTC_ALB_HU_Pos) /*!< 0x000F0000 */ +#define ERTC_ALB_HU ERTC_ALB_HU_Msk /*!< HU[3:0] (Hour units) */ +#define ERTC_ALB_HU_0 (0x1U << ERTC_ALB_HU_Pos) /*!< 0x00010000 */ +#define ERTC_ALB_HU_1 (0x2U << ERTC_ALB_HU_Pos) /*!< 0x00020000 */ +#define ERTC_ALB_HU_2 (0x4U << ERTC_ALB_HU_Pos) /*!< 0x00040000 */ +#define ERTC_ALB_HU_3 (0x8U << ERTC_ALB_HU_Pos) /*!< 0x00080000 */ + +/*!< HT configuration */ +#define ERTC_ALB_HT_Pos (20U) +#define ERTC_ALB_HT_Msk (0x3U << ERTC_ALB_HT_Pos) /*!< 0x00300000 */ +#define ERTC_ALB_HT ERTC_ALB_HT_Msk /*!< HT[1:0] (Hour tens) */ +#define ERTC_ALB_HT_0 (0x1U << ERTC_ALB_HT_Pos) /*!< 0x00100000 */ +#define ERTC_ALB_HT_1 (0x2U << ERTC_ALB_HT_Pos) /*!< 0x00200000 */ + +#define ERTC_ALB_AMPM_Pos (22U) +#define ERTC_ALB_AMPM_Msk (0x1U << ERTC_ALB_AMPM_Pos) /*!< 0x00400000 */ +#define ERTC_ALB_AMPM ERTC_ALB_AMPM_Msk /*!< AM/PM */ +#define ERTC_ALB_MASK3_Pos (23U) +#define ERTC_ALB_MASK3_Msk (0x1U << ERTC_ALB_MASK3_Pos) /*!< 0x00800000 */ +#define ERTC_ALB_MASK3 ERTC_ALB_MASK3_Msk /*!< Hour mask */ + +/*!< DU configuration */ +#define ERTC_ALB_DU_Pos (24U) +#define ERTC_ALB_DU_Msk (0xFU << ERTC_ALB_DU_Pos) /*!< 0x0F000000 */ +#define ERTC_ALB_DU ERTC_ALB_DU_Msk /*!< DU[3:0] (Date/week day units) */ +#define ERTC_ALB_DU_0 (0x1U << ERTC_ALB_DU_Pos) /*!< 0x01000000 */ +#define ERTC_ALB_DU_1 (0x2U << ERTC_ALB_DU_Pos) /*!< 0x02000000 */ +#define ERTC_ALB_DU_2 (0x4U << ERTC_ALB_DU_Pos) /*!< 0x04000000 */ +#define ERTC_ALB_DU_3 (0x8U << ERTC_ALB_DU_Pos) /*!< 0x08000000 */ + +/*!< DT configuration */ +#define ERTC_ALB_DT_Pos (28U) +#define ERTC_ALB_DT_Msk (0x3U << ERTC_ALB_DT_Pos) /*!< 0x30000000 */ +#define ERTC_ALB_DT ERTC_ALB_DT_Msk /*!< DT[1:0] (Date/week day tens) */ +#define ERTC_ALB_DT_0 (0x1U << ERTC_ALB_DT_Pos) /*!< 0x10000000 */ +#define ERTC_ALB_DT_1 (0x2U << ERTC_ALB_DT_Pos) /*!< 0x20000000 */ + +#define ERTC_ALB_WKSEL_Pos (30U) +#define ERTC_ALB_WKSEL_Msk (0x1U << ERTC_ALB_WKSEL_Pos) /*!< 0x40000000 */ +#define ERTC_ALB_WKSEL ERTC_ALB_WKSEL_Msk /*!< Date/week day select */ +#define ERTC_ALB_MASK4_Pos (31U) +#define ERTC_ALB_MASK4_Msk (0x1U << ERTC_ALB_MASK4_Pos) /*!< 0x80000000 */ +#define ERTC_ALB_MASK4 ERTC_ALB_MASK4_Msk /*!< Date/week day mask */ + +/******************* Bit definition for ERTC_WP register ********************/ +#define ERTC_WP_CMD_Pos (0U) +#define ERTC_WP_CMD_Msk (0xFFU << ERTC_WP_CMD_Pos) /*!< 0x000000FF */ +#define ERTC_WP_CMD ERTC_WP_CMD_Msk /*!< Command register */ + +/******************* Bit definition for ERTC_SBS register *******************/ +#define ERTC_SBS_SBS_Pos (0U) +#define ERTC_SBS_SBS_Msk (0xFFFFU << ERTC_SBS_SBS_Pos) /*!< 0x0000FFFF */ +#define ERTC_SBS_SBS ERTC_SBS_SBS_Msk /*!< Sub-second value */ + +/****************** Bit definition for ERTC_TADJ register *******************/ +#define ERTC_TADJ_DECSBS_Pos (0U) +#define ERTC_TADJ_DECSBS_Msk (0x7FFFU << ERTC_TADJ_DECSBS_Pos) /*!< 0x00007FFF */ +#define ERTC_TADJ_DECSBS ERTC_TADJ_DECSBS_Msk /*!< Decrease sub-second value */ +#define ERTC_TADJ_ADD1S_Pos (31U) +#define ERTC_TADJ_ADD1S_Msk (0x1U << ERTC_TADJ_ADD1S_Pos) /*!< 0x80000000 */ +#define ERTC_TADJ_ADD1S ERTC_TADJ_ADD1S_Msk /*!< Add 1 second */ + +/****************** Bit definition for ERTC_TSTM register *******************/ +/*!< SU configuration */ +#define ERTC_TSTM_SU_Pos (0U) +#define ERTC_TSTM_SU_Msk (0xFU << ERTC_TSTM_SU_Pos) /*!< 0x0000000F */ +#define ERTC_TSTM_SU ERTC_TSTM_SU_Msk /*!< SU[3:0] (Second units) */ +#define ERTC_TSTM_SU_0 (0x1U << ERTC_TSTM_SU_Pos) /*!< 0x00000001 */ +#define ERTC_TSTM_SU_1 (0x2U << ERTC_TSTM_SU_Pos) /*!< 0x00000002 */ +#define ERTC_TSTM_SU_2 (0x4U << ERTC_TSTM_SU_Pos) /*!< 0x00000004 */ +#define ERTC_TSTM_SU_3 (0x8U << ERTC_TSTM_SU_Pos) /*!< 0x00000008 */ + +/*!< ST configuration */ +#define ERTC_TSTM_ST_Pos (4U) +#define ERTC_TSTM_ST_Msk (0x7U << ERTC_TSTM_ST_Pos) /*!< 0x00000070 */ +#define ERTC_TSTM_ST ERTC_TSTM_ST_Msk /*!< ST[2:0] (Second tens) */ +#define ERTC_TSTM_ST_0 (0x1U << ERTC_TSTM_ST_Pos) /*!< 0x00000010 */ +#define ERTC_TSTM_ST_1 (0x2U << ERTC_TSTM_ST_Pos) /*!< 0x00000020 */ +#define ERTC_TSTM_ST_2 (0x4U << ERTC_TSTM_ST_Pos) /*!< 0x00000040 */ + +/*!< MU configuration */ +#define ERTC_TSTM_MU_Pos (8U) +#define ERTC_TSTM_MU_Msk (0xFU << ERTC_TSTM_MU_Pos) /*!< 0x00000F00 */ +#define ERTC_TSTM_MU ERTC_TSTM_MU_Msk /*!< MU[3:0] (Minute units) */ +#define ERTC_TSTM_MU_0 (0x1U << ERTC_TSTM_MU_Pos) /*!< 0x00000100 */ +#define ERTC_TSTM_MU_1 (0x2U << ERTC_TSTM_MU_Pos) /*!< 0x00000200 */ +#define ERTC_TSTM_MU_2 (0x4U << ERTC_TSTM_MU_Pos) /*!< 0x00000400 */ +#define ERTC_TSTM_MU_3 (0x8U << ERTC_TSTM_MU_Pos) /*!< 0x00000800 */ + +/*!< MT configuration */ +#define ERTC_TSTM_MT_Pos (12U) +#define ERTC_TSTM_MT_Msk (0x7U << ERTC_TSTM_MT_Pos) /*!< 0x00007000 */ +#define ERTC_TSTM_MT ERTC_TSTM_MT_Msk /*!< MT[2:0] (Minute tens) */ +#define ERTC_TSTM_MT_0 (0x1U << ERTC_TSTM_MT_Pos) /*!< 0x00001000 */ +#define ERTC_TSTM_MT_1 (0x2U << ERTC_TSTM_MT_Pos) /*!< 0x00002000 */ +#define ERTC_TSTM_MT_2 (0x4U << ERTC_TSTM_MT_Pos) /*!< 0x00004000 */ + +/*!< HU configuration */ +#define ERTC_TSTM_HU_Pos (16U) +#define ERTC_TSTM_HU_Msk (0xFU << ERTC_TSTM_HU_Pos) /*!< 0x000F0000 */ +#define ERTC_TSTM_HU ERTC_TSTM_HU_Msk /*!< HU[3:0] (Hour units) */ +#define ERTC_TSTM_HU_0 (0x1U << ERTC_TSTM_HU_Pos) /*!< 0x00010000 */ +#define ERTC_TSTM_HU_1 (0x2U << ERTC_TSTM_HU_Pos) /*!< 0x00020000 */ +#define ERTC_TSTM_HU_2 (0x4U << ERTC_TSTM_HU_Pos) /*!< 0x00040000 */ +#define ERTC_TSTM_HU_3 (0x8U << ERTC_TSTM_HU_Pos) /*!< 0x00080000 */ + +/*!< HT configuration */ +#define ERTC_TSTM_HT_Pos (20U) +#define ERTC_TSTM_HT_Msk (0x3U << ERTC_TSTM_HT_Pos) /*!< 0x00300000 */ +#define ERTC_TSTM_HT ERTC_TSTM_HT_Msk /*!< HT[1:0] (Hour tens) */ +#define ERTC_TSTM_HT_0 (0x1U << ERTC_TSTM_HT_Pos) /*!< 0x00100000 */ +#define ERTC_TSTM_HT_1 (0x2U << ERTC_TSTM_HT_Pos) /*!< 0x00200000 */ + +#define ERTC_TSTM_AMPM_Pos (22U) +#define ERTC_TSTM_AMPM_Msk (0x1U << ERTC_TSTM_AMPM_Pos) /*!< 0x00400000 */ +#define ERTC_TSTM_AMPM ERTC_TSTM_AMPM_Msk /*!< AM/PM */ + +/****************** Bit definition for ERTC_TSDT register *******************/ +/*!< DU configuration */ +#define ERTC_TSDT_DU_Pos (0U) +#define ERTC_TSDT_DU_Msk (0xFU << ERTC_TSDT_DU_Pos) /*!< 0x0000000F */ +#define ERTC_TSDT_DU ERTC_TSDT_DU_Msk /*!< DU[3:0] (Date units) */ +#define ERTC_TSDT_DU_0 (0x1U << ERTC_TSDT_DU_Pos) /*!< 0x00000001 */ +#define ERTC_TSDT_DU_1 (0x2U << ERTC_TSDT_DU_Pos) /*!< 0x00000002 */ +#define ERTC_TSDT_DU_2 (0x4U << ERTC_TSDT_DU_Pos) /*!< 0x00000004 */ +#define ERTC_TSDT_DU_3 (0x8U << ERTC_TSDT_DU_Pos) /*!< 0x00000008 */ + +/*!< DT configuration */ +#define ERTC_TSDT_DT_Pos (4U) +#define ERTC_TSDT_DT_Msk (0x3U << ERTC_TSDT_DT_Pos) /*!< 0x00000030 */ +#define ERTC_TSDT_DT ERTC_TSDT_DT_Msk /*!< DT[1:0] (Date tens) */ +#define ERTC_TSDT_DT_0 (0x1U << ERTC_TSDT_DT_Pos) /*!< 0x00000010 */ +#define ERTC_TSDT_DT_1 (0x2U << ERTC_TSDT_DT_Pos) /*!< 0x00000020 */ + +/*!< MU configuration */ +#define ERTC_TSDT_MU_Pos (8U) +#define ERTC_TSDT_MU_Msk (0xFU << ERTC_TSDT_MU_Pos) /*!< 0x00000F00 */ +#define ERTC_TSDT_MU ERTC_TSDT_MU_Msk /*!< MU[3:0] (Month units) */ +#define ERTC_TSDT_MU_0 (0x1U << ERTC_TSDT_MU_Pos) /*!< 0x00000100 */ +#define ERTC_TSDT_MU_1 (0x2U << ERTC_TSDT_MU_Pos) /*!< 0x00000200 */ +#define ERTC_TSDT_MU_2 (0x4U << ERTC_TSDT_MU_Pos) /*!< 0x00000400 */ +#define ERTC_TSDT_MU_3 (0x8U << ERTC_TSDT_MU_Pos) /*!< 0x00000800 */ + +#define ERTC_TSDT_MT_Pos (12U) +#define ERTC_TSDT_MT_Msk (0x1U << ERTC_TSDT_MT_Pos) /*!< 0x00001000 */ +#define ERTC_TSDT_MT ERTC_TSDT_MT_Msk /*!< Month tens */ + +/*!< WK configuration */ +#define ERTC_TSDT_WK_Pos (13U) +#define ERTC_TSDT_WK_Msk (0x7U << ERTC_TSDT_WK_Pos) /*!< 0x0000E000 */ +#define ERTC_TSDT_WK ERTC_TSDT_WK_Msk /*!< WK[2:0] (Week day) */ +#define ERTC_TSDT_WK_0 (0x1U << ERTC_TSDT_WK_Pos) /*!< 0x00002000 */ +#define ERTC_TSDT_WK_1 (0x2U << ERTC_TSDT_WK_Pos) /*!< 0x00004000 */ +#define ERTC_TSDT_WK_2 (0x4U << ERTC_TSDT_WK_Pos) /*!< 0x00008000 */ + +/****************** Bit definition for ERTC_TSSBS register ******************/ +#define ERTC_TSSBS_SBS_Pos (0U) +#define ERTC_TSSBS_SBS_Msk (0xFFFFU << ERTC_TSSBS_SBS_Pos) /*!< 0x0000FFFF */ +#define ERTC_TSSBS_SBS ERTC_TSSBS_SBS_Msk /*!< Sub-second value */ + +/****************** Bit definition for ERTC_SCAL register *******************/ +#define ERTC_SCAL_DEC_Pos (0U) +#define ERTC_SCAL_DEC_Msk (0x1FFU << ERTC_SCAL_DEC_Pos) /*!< 0x000001FF */ +#define ERTC_SCAL_DEC ERTC_SCAL_DEC_Msk /*!< Decrease ERTC clock */ +#define ERTC_SCAL_CAL16_Pos (13U) +#define ERTC_SCAL_CAL16_Msk (0x1U << ERTC_SCAL_CAL16_Pos) /*!< 0x00002000 */ +#define ERTC_SCAL_CAL16 ERTC_SCAL_CAL16_Msk /*!< 16 second calibration period */ +#define ERTC_SCAL_CAL8_Pos (14U) +#define ERTC_SCAL_CAL8_Msk (0x1U << ERTC_SCAL_CAL8_Pos) /*!< 0x00004000 */ +#define ERTC_SCAL_CAL8 ERTC_SCAL_CAL8_Msk /*!< 8 second calibration period */ +#define ERTC_SCAL_ADD_Pos (15U) +#define ERTC_SCAL_ADD_Msk (0x1U << ERTC_SCAL_ADD_Pos) /*!< 0x00008000 */ +#define ERTC_SCAL_ADD ERTC_SCAL_ADD_Msk /*!< Add ERTC clock */ + +/****************** Bit definition for ERTC_TAMP register *******************/ +#define ERTC_TAMP_TP1EN_Pos (0U) +#define ERTC_TAMP_TP1EN_Msk (0x1U << ERTC_TAMP_TP1EN_Pos) /*!< 0x00000001 */ +#define ERTC_TAMP_TP1EN ERTC_TAMP_TP1EN_Msk /*!< Tamper detection 1 enable */ +#define ERTC_TAMP_TP1EDG_Pos (1U) +#define ERTC_TAMP_TP1EDG_Msk (0x1U << ERTC_TAMP_TP1EDG_Pos) /*!< 0x00000002 */ +#define ERTC_TAMP_TP1EDG ERTC_TAMP_TP1EDG_Msk /*!< Tamper detection 1 valid edge */ +#define ERTC_TAMP_TPIEN_Pos (2U) +#define ERTC_TAMP_TPIEN_Msk (0x1U << ERTC_TAMP_TPIEN_Pos) /*!< 0x00000004 */ +#define ERTC_TAMP_TPIEN ERTC_TAMP_TPIEN_Msk /*!< Tamper detection interrupt enable */ +#define ERTC_TAMP_TPTSEN_Pos (7U) +#define ERTC_TAMP_TPTSEN_Msk (0x1U << ERTC_TAMP_TPTSEN_Pos) /*!< 0x00000080 */ +#define ERTC_TAMP_TPTSEN ERTC_TAMP_TPTSEN_Msk /*!< Tamper detection timestamp enable */ + +/*!< TPFREQ configuration */ +#define ERTC_TAMP_TPFREQ_Pos (8U) +#define ERTC_TAMP_TPFREQ_Msk (0x7U << ERTC_TAMP_TPFREQ_Pos) /*!< 0x00000700 */ +#define ERTC_TAMP_TPFREQ ERTC_TAMP_TPFREQ_Msk /*!< TPFREQ[2:0] (Tamper detection frequency) */ +#define ERTC_TAMP_TPFREQ_0 (0x1U << ERTC_TAMP_TPFREQ_Pos) /*!< 0x00000100 */ +#define ERTC_TAMP_TPFREQ_1 (0x2U << ERTC_TAMP_TPFREQ_Pos) /*!< 0x00000200 */ +#define ERTC_TAMP_TPFREQ_2 (0x4U << ERTC_TAMP_TPFREQ_Pos) /*!< 0x00000400 */ + +/*!< TPFLT configuration */ +#define ERTC_TAMP_TPFLT_Pos (11U) +#define ERTC_TAMP_TPFLT_Msk (0x3U << ERTC_TAMP_TPFLT_Pos) /*!< 0x00001800 */ +#define ERTC_TAMP_TPFLT ERTC_TAMP_TPFLT_Msk /*!< TPFLT[1:0] (Tamper detection filter time) */ +#define ERTC_TAMP_TPFLT_0 (0x1U << ERTC_TAMP_TPFLT_Pos) /*!< 0x00000800 */ +#define ERTC_TAMP_TPFLT_1 (0x2U << ERTC_TAMP_TPFLT_Pos) /*!< 0x00001000 */ + +/*!< TPPR configuration */ +#define ERTC_TAMP_TPPR_Pos (13U) +#define ERTC_TAMP_TPPR_Msk (0x3U << ERTC_TAMP_TPPR_Pos) /*!< 0x00006000 */ +#define ERTC_TAMP_TPPR ERTC_TAMP_TPPR_Msk /*!< TPPR[1:0] (Tamper detection pre-charge time) */ +#define ERTC_TAMP_TPPR_0 (0x1U << ERTC_TAMP_TPPR_Pos) /*!< 0x00002000 */ +#define ERTC_TAMP_TPPR_1 (0x2U << ERTC_TAMP_TPPR_Pos) /*!< 0x00004000 */ + +#define ERTC_TAMP_TPPU_Pos (15U) +#define ERTC_TAMP_TPPU_Msk (0x1U << ERTC_TAMP_TPPU_Pos) /*!< 0x00008000 */ +#define ERTC_TAMP_TPPU ERTC_TAMP_TPPU_Msk /*!< Tamper detection pull-up */ +#define ERTC_TAMP_OUTTYPE_Pos (18U) +#define ERTC_TAMP_OUTTYPE_Msk (0x1U << ERTC_TAMP_OUTTYPE_Pos) /*!< 0x00040000 */ +#define ERTC_TAMP_OUTTYPE ERTC_TAMP_OUTTYPE_Msk /*!< Output type */ + +/***************** Bit definition for ERTC_ALASBS register ******************/ +#define ERTC_ALASBS_SBS_Pos (0U) +#define ERTC_ALASBS_SBS_Msk (0x7FFFU << ERTC_ALASBS_SBS_Pos) /*!< 0x00007FFF */ +#define ERTC_ALASBS_SBS ERTC_ALASBS_SBS_Msk /*!< Sub-second value */ + +/*!< SBSMSK configuration */ +#define ERTC_ALASBS_SBSMSK_Pos (24U) +#define ERTC_ALASBS_SBSMSK_Msk (0xFU << ERTC_ALASBS_SBSMSK_Pos) /*!< 0x0F000000 */ +#define ERTC_ALASBS_SBSMSK ERTC_ALASBS_SBSMSK_Msk /*!< SBSMSK[3:0] (Sub-second mask) */ +#define ERTC_ALASBS_SBSMSK_0 (0x1U << ERTC_ALASBS_SBSMSK_Pos) /*!< 0x01000000 */ +#define ERTC_ALASBS_SBSMSK_1 (0x2U << ERTC_ALASBS_SBSMSK_Pos) /*!< 0x02000000 */ +#define ERTC_ALASBS_SBSMSK_2 (0x4U << ERTC_ALASBS_SBSMSK_Pos) /*!< 0x04000000 */ +#define ERTC_ALASBS_SBSMSK_3 (0x8U << ERTC_ALASBS_SBSMSK_Pos) /*!< 0x08000000 */ + +/***************** Bit definition for ERTC_ALBSBS register ******************/ +#define ERTC_ALBSBS_SBS_Pos (0U) +#define ERTC_ALBSBS_SBS_Msk (0x7FFFU << ERTC_ALBSBS_SBS_Pos) /*!< 0x00007FFF */ +#define ERTC_ALBSBS_SBS ERTC_ALBSBS_SBS_Msk /*!< Sub-second value */ + +/*!< SBSMSK configuration */ +#define ERTC_ALBSBS_SBSMSK_Pos (24U) +#define ERTC_ALBSBS_SBSMSK_Msk (0xFU << ERTC_ALBSBS_SBSMSK_Pos) /*!< 0x0F000000 */ +#define ERTC_ALBSBS_SBSMSK ERTC_ALBSBS_SBSMSK_Msk /*!< SBSMSK[3:0] (Sub-second mask) */ +#define ERTC_ALBSBS_SBSMSK_0 (0x1U << ERTC_ALBSBS_SBSMSK_Pos) /*!< 0x01000000 */ +#define ERTC_ALBSBS_SBSMSK_1 (0x2U << ERTC_ALBSBS_SBSMSK_Pos) /*!< 0x02000000 */ +#define ERTC_ALBSBS_SBSMSK_2 (0x4U << ERTC_ALBSBS_SBSMSK_Pos) /*!< 0x04000000 */ +#define ERTC_ALBSBS_SBSMSK_3 (0x8U << ERTC_ALBSBS_SBSMSK_Pos) /*!< 0x08000000 */ + +/****************** Bit definition for ERTC_BPR1 register *******************/ +#define ERTC_BPR1_DT_Pos (0U) +#define ERTC_BPR1_DT_Msk (0xFFFFFFFFU << ERTC_BPR1_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR1_DT ERTC_BPR1_DT_Msk /*!< Battery powered domain data 1 */ + +/****************** Bit definition for ERTC_BPR2 register *******************/ +#define ERTC_BPR2_DT_Pos (0U) +#define ERTC_BPR2_DT_Msk (0xFFFFFFFFU << ERTC_BPR2_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR2_DT ERTC_BPR2_DT_Msk /*!< Battery powered domain data 2 */ + +/****************** Bit definition for ERTC_BPR3 register *******************/ +#define ERTC_BPR3_DT_Pos (0U) +#define ERTC_BPR3_DT_Msk (0xFFFFFFFFU << ERTC_BPR3_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR3_DT ERTC_BPR3_DT_Msk /*!< Battery powered domain data 3 */ + +/****************** Bit definition for ERTC_BPR4 register *******************/ +#define ERTC_BPR4_DT_Pos (0U) +#define ERTC_BPR4_DT_Msk (0xFFFFFFFFU << ERTC_BPR4_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR4_DT ERTC_BPR4_DT_Msk /*!< Battery powered domain data 4 */ + +/****************** Bit definition for ERTC_BPR5 register *******************/ +#define ERTC_BPR5_DT_Pos (0U) +#define ERTC_BPR5_DT_Msk (0xFFFFFFFFU << ERTC_BPR5_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR5_DT ERTC_BPR5_DT_Msk /*!< Battery powered domain data 5 */ + +/****************** Bit definition for ERTC_BPR6 register *******************/ +#define ERTC_BPR6_DT_Pos (0U) +#define ERTC_BPR6_DT_Msk (0xFFFFFFFFU << ERTC_BPR6_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR6_DT ERTC_BPR6_DT_Msk /*!< Battery powered domain data 6 */ + +/****************** Bit definition for ERTC_BPR7 register *******************/ +#define ERTC_BPR7_DT_Pos (0U) +#define ERTC_BPR7_DT_Msk (0xFFFFFFFFU << ERTC_BPR7_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR7_DT ERTC_BPR7_DT_Msk /*!< Battery powered domain data 7 */ + +/****************** Bit definition for ERTC_BPR8 register *******************/ +#define ERTC_BPR8_DT_Pos (0U) +#define ERTC_BPR8_DT_Msk (0xFFFFFFFFU << ERTC_BPR8_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR8_DT ERTC_BPR8_DT_Msk /*!< Battery powered domain data 8 */ + +/****************** Bit definition for ERTC_BPR9 register *******************/ +#define ERTC_BPR9_DT_Pos (0U) +#define ERTC_BPR9_DT_Msk (0xFFFFFFFFU << ERTC_BPR9_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR9_DT ERTC_BPR9_DT_Msk /*!< Battery powered domain data 9 */ + +/****************** Bit definition for ERTC_BPR10 register ******************/ +#define ERTC_BPR10_DT_Pos (0U) +#define ERTC_BPR10_DT_Msk (0xFFFFFFFFU << ERTC_BPR10_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR10_DT ERTC_BPR10_DT_Msk /*!< Battery powered domain data 10 */ + +/****************** Bit definition for ERTC_BPR11 register ******************/ +#define ERTC_BPR11_DT_Pos (0U) +#define ERTC_BPR11_DT_Msk (0xFFFFFFFFU << ERTC_BPR11_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR11_DT ERTC_BPR11_DT_Msk /*!< Battery powered domain data 11 */ + +/****************** Bit definition for ERTC_BPR12 register ******************/ +#define ERTC_BPR12_DT_Pos (0U) +#define ERTC_BPR12_DT_Msk (0xFFFFFFFFU << ERTC_BPR12_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR12_DT ERTC_BPR12_DT_Msk /*!< Battery powered domain data 12 */ + +/****************** Bit definition for ERTC_BPR13 register ******************/ +#define ERTC_BPR13_DT_Pos (0U) +#define ERTC_BPR13_DT_Msk (0xFFFFFFFFU << ERTC_BPR13_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR13_DT ERTC_BPR13_DT_Msk /*!< Battery powered domain data 13 */ + +/****************** Bit definition for ERTC_BPR14 register ******************/ +#define ERTC_BPR14_DT_Pos (0U) +#define ERTC_BPR14_DT_Msk (0xFFFFFFFFU << ERTC_BPR14_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR14_DT ERTC_BPR14_DT_Msk /*!< Battery powered domain data 14 */ + +/****************** Bit definition for ERTC_BPR15 register ******************/ +#define ERTC_BPR15_DT_Pos (0U) +#define ERTC_BPR15_DT_Msk (0xFFFFFFFFU << ERTC_BPR15_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR15_DT ERTC_BPR15_DT_Msk /*!< Battery powered domain data 15 */ + +/****************** Bit definition for ERTC_BPR16 register ******************/ +#define ERTC_BPR16_DT_Pos (0U) +#define ERTC_BPR16_DT_Msk (0xFFFFFFFFU << ERTC_BPR16_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR16_DT ERTC_BPR16_DT_Msk /*!< Battery powered domain data 16 */ + +/****************** Bit definition for ERTC_BPR17 register ******************/ +#define ERTC_BPR17_DT_Pos (0U) +#define ERTC_BPR17_DT_Msk (0xFFFFFFFFU << ERTC_BPR17_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR17_DT ERTC_BPR17_DT_Msk /*!< Battery powered domain data 17 */ + +/****************** Bit definition for ERTC_BPR18 register ******************/ +#define ERTC_BPR18_DT_Pos (0U) +#define ERTC_BPR18_DT_Msk (0xFFFFFFFFU << ERTC_BPR18_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR18_DT ERTC_BPR18_DT_Msk /*!< Battery powered domain data 18 */ + +/****************** Bit definition for ERTC_BPR19 register ******************/ +#define ERTC_BPR19_DT_Pos (0U) +#define ERTC_BPR19_DT_Msk (0xFFFFFFFFU << ERTC_BPR19_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR19_DT ERTC_BPR19_DT_Msk /*!< Battery powered domain data 19 */ + +/****************** Bit definition for ERTC_BPR20 register ******************/ +#define ERTC_BPR20_DT_Pos (0U) +#define ERTC_BPR20_DT_Msk (0xFFFFFFFFU << ERTC_BPR20_DT_Pos) /*!< 0xFFFFFFFF */ +#define ERTC_BPR20_DT ERTC_BPR20_DT_Msk /*!< Battery powered domain data 20 */ + +/************************* Number of backup registers *************************/ +#define ERTC_BPR_NUMBER 0x000000014U + +/* =========================================================================================================================== */ +/* ================ PWC ================ */ +/* =========================================================================================================================== */ +/****************** Bit definition for PWC_CTRL register *****************/ +#define PWC_CTRL_PVMEN (0x1U << 4) +#define PWC_CTRL_BPWEN (0x1U << 8) + + +/* =========================================================================================================================== */ +/* ================ FLASH ================ */ +/* =========================================================================================================================== */ +/****************** Bit definition for FLASH_STS register ****************/ +#define FLASH_STS_OBF (0x1U << 0) +#define FLASH_STS_PRGMERR (0x1U << 2) +#define FLASH_STS_EPPERR (0x1U << 4) +#define FLASH_STS_ODF (0x1U << 5) + +/****************** Bit definition for FLASH_CTRL register ***************/ +#define FLASH_CTRL_FPRGM (0x1U << 0) +#define FLASH_CTRL_SECERS (0x1U << 1) +#define FLASH_CTRL_BANKERS (0x1U << 2) +#define FLASH_CTRL_USDPRGM (0x1U << 4) +#define FLASH_CTRL_USDERS (0x1U << 5) +#define FLASH_CTRL_ERSTR (0x1U << 6) +#define FLASH_CTRL_OPLK (0x1U << 7) + + +/* =========================================================================================================================== */ +/* ================ TMR ================ */ +/* =========================================================================================================================== */ +/****************** Bit definition for TMR_IDEN register ****************/ +#define TMR_IDEN_OVFIEN (0x1U << 0) +#define TMR_IDEN_C1IEN (0x1U << 1) +#define TMR_IDEN_C2IEN (0x1U << 2) +#define TMR_IDEN_C3IEN (0x1U << 3) +#define TMR_IDEN_C4IEN (0x1U << 4) +#define TMR_IDEN_HALLIEN (0x1U << 5) +#define TMR_IDEN_TIEN (0x1U << 6) +#define TMR_IDEN_BRKIEN (0x1U << 7) +#define TMR_IDEN_OVFDEN (0x1U << 8) +#define TMR_IDEN_C1DEN (0x1U << 9) +#define TMR_IDEN_C2DEN (0x1U << 10) +#define TMR_IDEN_C3DEN (0x1U << 11) +#define TMR_IDEN_C4DEN (0x1U << 12) +#define TMR_IDEN_HALLDEN (0x1U << 13) +#define TMR_IDEN_TDEN (0x1U << 14) + + +/* =========================================================================================================================== */ +/* ================ DMA ================ */ +/* =========================================================================================================================== */ +/****************** Bit definition for DMA_CxCTRL register **************/ +#define DMA_CTRL_CHEN (0x1U << 0) +#define DMA_CTRL_FDTIEN (0x1U << 1) +#define DMA_CTRL_HDTIEN (0x1U << 2) +#define DMA_CTRL_DTERRIEN (0x1U << 3) +#define DMA_CTRL_DTD (0x1U << 4) +#define DMA_CTRL_LM (0x1U << 5) +#define DMA_CTRL_PINCM (0x1U << 6) +#define DMA_CTRL_MINCM (0x1U << 7) +#define DMA_CTRL_PWIDTH (0x3U << 8) +#define DMA_CTRL_PWIDTH_8BITS (0x0U << 8) +#define DMA_CTRL_PWIDTH_16BITS (0x1U << 8) +#define DMA_CTRL_PWIDTH_32BITS (0x2U << 8) +#define DMA_CTRL_MWIDTH (0x3U << 10) +#define DMA_CTRL_MWIDTH_8BITS (0x0U << 10) +#define DMA_CTRL_MWIDTH_16BITS (0x1U << 10) +#define DMA_CTRL_MWIDTH_32BITS (0x2U << 10) +#define DMA_CTRL_CHPL (0x3U << 12) +#define DMA_CTRL_CHPL_LOW (0x0U << 12) +#define DMA_CTRL_CHPL_MID (0x1U << 12) +#define DMA_CTRL_CHPL_HIGH (0x2U << 12) +#define DMA_CTRL_CHPL_HIGHEST (0x3U << 12) +#define DMA_CTRL_M2M (0x1U << 14) + +/****************** Bit definition for DMA_MUXSEL register *************/ +#define DMA_MUXSEL_TBL_SEL (0x1U << 0) + +/****************** Bit definition for DMA_MUXCxCTRL register *************/ +#define DMA_MUXCTRL_SYNCOVIEN (0x1U << 8) +#define DMA_MUXCTRL_EVTGEN (0x1U << 9) +#define DMA_MUXCTRL_SYNCEN (0x1U << 16) +#define DMA_MUXCTRL_SYNCPOL (0x3U << 17) +#define DMA_MUXCTRL_SYNCPOL_NONE (0x0U << 17) +#define DMA_MUXCTRL_SYNCPOL_RISING (0x1U << 17) +#define DMA_MUXCTRL_SYNCPOL_FALLING (0x2U << 17) +#define DMA_MUXCTRL_SYNCPOL_BOTH (0x3U << 17) + +/****************** Bit definition for DMA_MUXGxCTRL register *************/ +#define DMA_MUXGCTRL_TRGOVIEN (0x1U << 8) +#define DMA_MUXGCTRL_GEN (0x1U << 16) +#define DMA_MUXGCTRL_GPOL (0x3U << 17) +#define DMA_MUXGCTRL_GPOL_NONE (0x0U << 17) +#define DMA_MUXGCTRL_GPOL_RISING (0x1U << 17) +#define DMA_MUXGCTRL_GPOL_FALLING (0x2U << 17) +#define DMA_MUXGCTRL_GPOL_BOTH (0x3U << 17) + + +/* =========================================================================================================================== */ +/* ================ I2C ================ */ +/* =========================================================================================================================== */ +/****************** Bit definition for I2C_CTRL1 register ***************/ +#define I2C_CTRL1_I2CEN (0x1U << 0) +#define I2C_CTRL1_TDIEN (0x1U << 1) +#define I2C_CTRL1_RDIEN (0x1U << 2) +#define I2C_CTRL1_ADDRIEN (0x1U << 3) +#define I2C_CTRL1_ACKFAILIEN (0x1U << 4) +#define I2C_CTRL1_STOPIEN (0x1U << 5) +#define I2C_CTRL1_TDCIEN (0x1U << 6) +#define I2C_CTRL1_ERRIEN (0x1U << 7) +#define I2C_CTRL1_DMATEN (0x1U << 14) +#define I2C_CTRL1_DMAREN (0x1U << 15) +#define I2C_CTRL1_SCTRL (0x1U << 16) +#define I2C_CTRL1_STRETCH (0x1U << 17) +#define I2C_CTRL1_GCAEN (0x1U << 19) +#define I2C_CTRL1_HADDREN (0x1U << 20) +#define I2C_CTRL1_DEVADDREN (0x1U << 21) +#define I2C_CTRL1_SMBALERT (0x1U << 22) +#define I2C_CTRL1_PECEN (0x1U << 23) + +/****************** Bit definition for I2C_CTRL2 register ***************/ +#define I2C_CTRL2_DIR (0x1U << 10) +#define I2C_CTRL2_ADDR10 (0x1U << 11) +#define I2C_CTRL2_READH10 (0x1U << 12) +#define I2C_CTRL2_GENSTART (0x1U << 13) +#define I2C_CTRL2_GENSTOP (0x1U << 14) +#define I2C_CTRL2_NACKEN (0x1U << 15) +#define I2C_CTRL2_RLDEN (0x1U << 24) +#define I2C_CTRL2_ASTOPEN (0x1U << 25) +#define I2C_CTRL2_PECTEN (0x1U << 26) +#define I2C_CTRL2_CNT_MASK (0xFF << 16) + +/****************** Bit definition for I2C_TIMEOUT register ***************/ +#define I2C_TIMEOUT_TOMODE (0x1U << 12) +#define I2C_TIMEOUT_TOMODE_LOW (0x0U << 12) +#define I2C_TIMEOUT_TOMODE_HIGH (0x1U << 12) +#define I2C_TIMEOUT_TOEN (0x1U << 15) +#define I2C_TIMEOUT_EXTEN (0x1U << 31) + +/****************** Bit definition for I2C_STS register ***************/ +#define I2C_STS_TDBE (0x1U << 0) +#define I2C_STS_TDIS (0x1U << 1) +#define I2C_STS_RDBF (0x1U << 2) +#define I2C_STS_ADDRF (0x1U << 3) +#define I2C_STS_ACKFAILF (0x1U << 4) +#define I2C_STS_STOPF (0x1U << 5) +#define I2C_STS_TDC (0x1U << 6) +#define I2C_STS_TCRLD (0x1U << 7) +#define I2C_STS_BUSERR (0x1U << 8) +#define I2C_STS_ARLOST (0x1U << 9) +#define I2C_STS_OUF (0x1U << 10) +#define I2C_STS_PECERR (0x1U << 11) +#define I2C_STS_TMOUT (0x1U << 12) +#define I2C_STS_ALERTF (0x1U << 13) +#define I2C_STS_BUSYF (0x1U << 15) +#define I2C_STS_SDIR (0x1U << 16) + + +/* =========================================================================================================================== */ +/* ================ USART ================ */ +/* =========================================================================================================================== */ + + +/******************* Bit definition for USART_STS register **************/ +#define USART_STS_PERR (0x1U << 0) +#define USART_STS_FERR (0x1U << 1) +#define USART_STS_NERR (0x1U << 2) +#define USART_STS_ROERR (0x1U << 3) +#define USART_STS_IDLEF (0x1U << 4) +#define USART_STS_RDBF (0x1U << 5) +#define USART_STS_TDC (0x1U << 6) +#define USART_STS_TDBE (0x1U << 7) +#define USART_STS_BFF (0x1U << 8) +#define USART_STS_CTSCF (0x1U << 9) +#define USART_STS_RTODF (0x1U << 11) +#define USART_STS_CMDF (0x1U << 17) + +/******************* Bit definition for USART_DT register ***************/ +#define USART_DT_DT (0x1FFU << 0) + +/****************** Bit definition for USART_CTRL1 register *************/ +#define USART_CTRL1_SBF (0x1U << 0) +#define USART_CTRL1_RM (0x1U << 1) +#define USART_CTRL1_REN (0x1U << 2) +#define USART_CTRL1_TEN (0x1U << 3) +#define USART_CTRL1_IDLEIEN (0x1U << 4) +#define USART_CTRL1_RDBFIEN (0x1U << 5) +#define USART_CTRL1_TDCIEN (0x1U << 6) +#define USART_CTRL1_TDBEIEN (0x1U << 7) +#define USART_CTRL1_PERRIEN (0x1U << 8) +#define USART_CTRL1_PSEL (0x1U << 9) +#define USART_CTRL1_PEN (0x1U << 10) +#define USART_CTRL1_WUM (0x1U << 11) +#define USART_CTRL1_DBN0 (0x1U << 12) +#define USART_CTRL1_UEN (0x1U << 13) +#define USART_CTRL1_CMDIE (0x1U << 14) +#define USART_CTRL1_RETODIE (0x1U << 26) +#define USART_CTRL1_RTODEN (0x1U << 27) +#define USART_CTRL1_DBN1 (0x1U << 28) +#define USART_CTRL1_DBN_7BITS (0x1U << 28) +#define USART_CTRL1_DBN_8BITS (0x0U << 28) +#define USART_CTRL1_DBN_9BITS (0x1U << 12) +#define USART_CTRL1_DBN (0x1U << 12) + +/****************** Bit definition for USART_CTRL2 register *************/ +#define USART_CTRL2_IDL (0xFU << 0) +#define USART_CTRL2_IDBN (0x1U << 4) +#define USART_CTRL2_BFBN (0x1U << 5) +#define USART_CTRL2_BFIEN (0x1U << 6) +#define USART_CTRL2_LBCP (0x1U << 8) +#define USART_CTRL2_CLKPHA (0x1U << 9) +#define USART_CTRL2_CLKPOL (0x1U << 10) +#define USART_CTRL2_CLKEN (0x1U << 11) +#define USART_CTRL2_STOPBN (0x3U << 12) +#define USART_CTRL2_STOP_0 (0x1U << 12) +#define USART_CTRL2_STOP_1 (0x1U << 13) +#define USART_CTRL2_STOPBN_1_BITS (0x0U << 12) +#define USART_CTRL2_STOPBN_0P5_BITS (0x1U << 12) +#define USART_CTRL2_STOPBN_2_BITS (0x2U << 12) +#define USART_CTRL2_STOPBN_1P5_BITS (0x3U << 12) +#define USART_CTRL2_LINEN (0x1U << 14) +#define USART_CTRL2_TRPSWAP (0x1U << 15) +#define USART_CTRL2_RXREV (0x1U << 16) +#define USART_CTRL2_TXREV (0x1U << 17) +#define USART_CTRL2_DTREV (0x1U << 18) +#define USART_CTRL2_MTF (0x1U << 19) +#define USART_CTRL2_IDH (0xFU << 28) + +/****************** Bit definition for USART_CTRL3 register *************/ +#define USART_CTRL3_ERRIEN (0x1U << 0) +#define USART_CTRL3_IRDAEN (0x1U << 1) +#define USART_CTRL3_IRDALP (0x1U << 2) +#define USART_CTRL3_SLBEN (0x1U << 3) +#define USART_CTRL3_SCNACKEN (0x1U << 4) +#define USART_CTRL3_SCMEN (0x1U << 5) +#define USART_CTRL3_DMAREN (0x1U << 6) +#define USART_CTRL3_DMATEN (0x1U << 7) +#define USART_CTRL3_RTSEN (0x1U << 8) +#define USART_CTRL3_CTSEN (0x1U << 9) +#define USART_CTRL3_CTSCFIEN (0x1U << 10) +#define USART_CTRL3_RS485EN (0x1U << 14) +#define USART_CTRL3_DEP (0x1U << 15) + +/******************* Bit definition for USART_IFC register ***************/ +#define USART_IFC_RTODFC (0x1U << 11) +#define USART_IFC_CMDFC (0x1U << 17) + + +/* =========================================================================================================================== */ +/* ================ SPI ================ */ +/* =========================================================================================================================== */ + +/******************* Bit definition for SPI_CTRL1 register **************/ +#define SPI_CTRL1_CLKPHA (0x1U << 0) +#define SPI_CTRL1_CLKPOL (0x1U << 1) +#define SPI_CTRL1_MSTEN (0x1U << 2) +#define SPI_CTRL1_MDIV (0x7U << 3) +#define SPI_CTRL1_MDIV_2 (0x0U << 3) +#define SPI_CTRL1_MDIV_4 (0x1U << 3) +#define SPI_CTRL1_MDIV_8 (0x2U << 3) +#define SPI_CTRL1_MDIV_16 (0x3U << 3) +#define SPI_CTRL1_MDIV_32 (0x4U << 3) +#define SPI_CTRL1_MDIV_64 (0x5U << 3) +#define SPI_CTRL1_MDIV_128 (0x6U << 3) +#define SPI_CTRL1_MDIV_256 (0x7U << 3) +#define SPI_CTRL1_MDIV_512 (0x0U << 3) +#define SPI_CTRL1_MDIV_1024 (0x1U << 3) +#define SPI_CTRL1_SPIEN (0x1U << 6) +#define SPI_CTRL1_LTF (0x1U << 7) +#define SPI_CTRL1_SWCSIL (0x1U << 8) +#define SPI_CTRL1_SWCSEN (0x1U << 9) +#define SPI_CTRL1_ORA (0x1U << 10) +#define SPI_CTRL1_FBN (0x1U << 11) +#define SPI_CTRL1_NTC (0x1U << 12) +#define SPI_CTRL1_CCEN (0x1U << 13) +#define SPI_CTRL1_SLBTD (0x1U << 14) +#define SPI_CTRL1_SLBEN (0x1U << 15) + +/******************* Bit definition for SPI_CTRL2 register **************/ +#define SPI_CTRL2_DMAREN (0x1U << 0) +#define SPI_CTRL2_DMATEN (0x1U << 1) +#define SPI_CTRL2_HWCSOE (0x1U << 2) +#define SPI_CTRL2_TIEN (0x1U << 4) +#define SPI_CTRL2_ERRIE (0x1U << 5) +#define SPI_CTRL2_RDBFIE (0x1U << 6) +#define SPI_CTRL2_TDBEIE (0x1U << 7) +#define SPI_CTRL2_MDIV (0x1U << 8) +#define SPI_CTRL2_MDIV_512_1024 (0x1U << 8) +#define SPI_CTRL2_MDIV3EN (0x1U << 9) + +/******************* Bit definition for SPI_STS register ********************/ +#define SPI_STS_RDBF (0x1U << 0) +#define SPI_STS_TDBE (0x1U << 1) +#define SPI_STS_ACS (0x1U << 2) +#define SPI_STS_TUERR (0x1U << 3) +#define SPI_STS_CCERR (0x1U << 4) +#define SPI_STS_MMERR (0x1U << 5) +#define SPI_STS_ROERR (0x1U << 6) +#define SPI_STS_BF (0x1U << 7) +#define SPI_STS_CSPAS (0x1U << 8) + +/******************* Bit definition for SPI_I2SCTRL register *****************/ +#define SPI_I2SCTRL_I2SCBN (0x1U << 0) +#define SPI_I2SCTRL_I2SDBN (0x3U << 1) +#define SPI_I2SCTRL_I2SDBN_16BITS (0x0U << 1) +#define SPI_I2SCTRL_I2SDBN_24BITS (0x1U << 1) +#define SPI_I2SCTRL_I2SDBN_32BITS (0x2U << 1) +#define SPI_I2SCTRL_I2SDBN_NONE (0x3U << 1) +#define SPI_I2SCTRL_I2SCLKPOL (0x1U << 3) +#define SPI_I2SCTRL_STDSEL (0x3U << 4) +#define SPI_I2SCTRL_STDSEL_PHILIPS (0x0U << 4) +#define SPI_I2SCTRL_STDSEL_MSB (0x1U << 4) +#define SPI_I2SCTRL_STDSEL_LSB (0x2U << 4) +#define SPI_I2SCTRL_STDSEL_PCM (0x3U << 4) +#define SPI_I2SCTRL_PCMFSSEL (0x1U << 7) +#define SPI_I2SCTRL_OPERSEL (0x3U << 8) +#define SPI_I2SCTRL_OPERSEL_ST (0x0U << 8) +#define SPI_I2SCTRL_OPERSEL_SR (0x1U << 8) +#define SPI_I2SCTRL_OPERSEL_HT (0x2U << 8) +#define SPI_I2SCTRL_OPERSEL_HR (0x3U << 8) +#define SPI_I2SCTRL_I2SEN (0x1U << 10) +#define SPI_I2SCTRL_I2SMSEL (0x1U << 11) + +/******************* Bit definition for SPI_I2SCLKP register ************/ +#define SPI_I2SCLKP_I2SDIV_1 (0xFFU << 0) +#define SPI_I2SCLKP_I2SODD (0x1U << 8) +#define SPI_I2SCLKP_I2SMCLKOE (0x1U << 9) +#define SPI_I2SCLKP_I2SDIV_2 (0x3U << 10) + + +/* =========================================================================================================================== */ +/* ================ DEBUG ================ */ +/* =========================================================================================================================== */ + +/****************** Bit definition for DEBUG_APB1_PAUSE register **************/ +#define DEBUG_APB1_PAUSE_TMR2_PAUSE (0x1U << 0) +#define DEBUG_APB1_PAUSE_TMR3_PAUSE (0x1U << 1) +#define DEBUG_APB1_PAUSE_TMR4_PAUSE (0x1U << 2) +#define DEBUG_APB1_PAUSE_TMR6_PAUSE (0x1U << 4) +#define DEBUG_APB1_PAUSE_TMR7_PAUSE (0x1U << 5) +#define DEBUG_APB1_PAUSE_TMR13_PAUSE (0x1U << 7) +#define DEBUG_APB1_PAUSE_TMR14_PAUSE (0x1U << 8) +#define DEBUG_APB1_PAUSE_ERTC_PAUSE (0x1U << 10) +#define DEBUG_APB1_PAUSE_WWDT_PAUSE (0x1U << 11) +#define DEBUG_APB1_PAUSE_WDT_PAUSE (0x1U << 12) +#define DEBUG_APB1_PAUSE_I2C1_SMBUS_TIMEOUT (0x1U << 24) +#define DEBUG_APB1_PAUSE_CAN1_PAUSE (0x1U << 25) +#define DEBUG_APB1_PAUSE_I2C2_SMBUS_TIMEOUT (0x1U << 27) +#define DEBUG_APB1_PAUSE_I2C3_SMBUS_TIMEOUT (0x1U << 28) + +/****************** Bit definition for DEBUG_APB2_PAUSE register **************/ +#define DEBUG_APB2_PAUSE_TMR1_PAUSE (0x1U << 0) +#define DEBUG_APB2_PAUSE_TMR9_PAUSE (0x1U << 16) +#define DEBUG_APB2_PAUSE_TMR10_PAUSE (0x1U << 17) +#define DEBUG_APB2_PAUSE_TMR11_PAUSE (0x1U << 18) + +/** + * @} + */ + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F405xB.ld b/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F405xB.ld new file mode 100644 index 0000000000..bc182b3840 --- /dev/null +++ b/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F405xB.ld @@ -0,0 +1,85 @@ +/* + COPYRIGHT(C) 2023, Artery + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * AT32F402_405xB memory setup. + */ +MEMORY +{ + flash0 (rx) : org = 0x08000000, len = 128k + flash1 (rx) : org = 0x00000000, len = 0 + flash2 (rx) : org = 0x00000000, len = 0 + flash3 (rx) : org = 0x00000000, len = 0 + flash4 (rx) : org = 0x00000000, len = 0 + flash5 (rx) : org = 0x00000000, len = 0 + flash6 (rx) : org = 0x00000000, len = 0 + flash7 (rx) : org = 0x00000000, len = 0 + ram0 (wx) : org = 0x20000000, len = 64k + ram1 (wx) : org = 0x00000000, len = 0 + ram2 (wx) : org = 0x00000000, len = 0 + ram3 (wx) : org = 0x00000000, len = 0 + ram4 (wx) : org = 0x00000000, len = 0 + ram5 (wx) : org = 0x00000000, len = 0 + ram6 (wx) : org = 0x00000000, len = 0 + ram7 (wx) : org = 0x00000000, len = 0 +} + +/* For each data/text section two region are defined, a virtual region + and a load region (_LMA suffix).*/ + +/* Flash region to be used for exception vectors.*/ +REGION_ALIAS("VECTORS_FLASH", flash0); +REGION_ALIAS("VECTORS_FLASH_LMA", flash0); + +/* Flash region to be used for constructors and destructors.*/ +REGION_ALIAS("XTORS_FLASH", flash0); +REGION_ALIAS("XTORS_FLASH_LMA", flash0); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash0); +REGION_ALIAS("TEXT_FLASH_LMA", flash0); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash0); +REGION_ALIAS("RODATA_FLASH_LMA", flash0); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash0); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("MAIN_STACK_RAM", ram0); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram0); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); +REGION_ALIAS("DATA_RAM_LMA", flash0); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for the default heap.*/ +REGION_ALIAS("HEAP_RAM", ram0); + +/* Generic rules inclusion.*/ +INCLUDE rules.ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F405xC.ld b/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F405xC.ld new file mode 100644 index 0000000000..758f2285e4 --- /dev/null +++ b/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F405xC.ld @@ -0,0 +1,85 @@ +/* + COPYRIGHT(C) 2023, Artery + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * AT32F402_405xC memory setup. + */ +MEMORY +{ + flash0 (rx) : org = 0x08000000, len = 256k + flash1 (rx) : org = 0x00000000, len = 0 + flash2 (rx) : org = 0x00000000, len = 0 + flash3 (rx) : org = 0x00000000, len = 0 + flash4 (rx) : org = 0x00000000, len = 0 + flash5 (rx) : org = 0x00000000, len = 0 + flash6 (rx) : org = 0x00000000, len = 0 + flash7 (rx) : org = 0x00000000, len = 0 + ram0 (wx) : org = 0x20000000, len = 96k + ram1 (wx) : org = 0x00000000, len = 0 + ram2 (wx) : org = 0x00000000, len = 0 + ram3 (wx) : org = 0x00000000, len = 0 + ram4 (wx) : org = 0x00000000, len = 0 + ram5 (wx) : org = 0x00000000, len = 0 + ram6 (wx) : org = 0x00000000, len = 0 + ram7 (wx) : org = 0x00000000, len = 0 +} + +/* For each data/text section two region are defined, a virtual region + and a load region (_LMA suffix).*/ + +/* Flash region to be used for exception vectors.*/ +REGION_ALIAS("VECTORS_FLASH", flash0); +REGION_ALIAS("VECTORS_FLASH_LMA", flash0); + +/* Flash region to be used for constructors and destructors.*/ +REGION_ALIAS("XTORS_FLASH", flash0); +REGION_ALIAS("XTORS_FLASH_LMA", flash0); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash0); +REGION_ALIAS("TEXT_FLASH_LMA", flash0); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash0); +REGION_ALIAS("RODATA_FLASH_LMA", flash0); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash0); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("MAIN_STACK_RAM", ram0); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram0); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); +REGION_ALIAS("DATA_RAM_LMA", flash0); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for the default heap.*/ +REGION_ALIAS("HEAP_RAM", ram0); + +/* Generic rules inclusion.*/ +INCLUDE rules.ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f405xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f405xx.mk new file mode 100644 index 0000000000..ac07851b44 --- /dev/null +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f405xx.mk @@ -0,0 +1,19 @@ +# List of the ChibiOS generic AT32F402_405 startup and CMSIS files. +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c + +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.S \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.S \ + +STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld \ + $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/devices/AT32F402_405xx \ + $(CHIBIOS)/os/common/ext/ARM/CMSIS/Core/Include \ + $(CHIBIOS_CONTRIB)/os/common/ext/CMSIS/ArteryTek/AT32F402_405xx + +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld +STARTUPLD_CONTRIB = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/ld + +# Shared variables +ALLXASMSRC += $(STARTUPASM) +ALLCSRC += $(STARTUPSRC) +ALLINC += $(STARTUPINC) \ No newline at end of file diff --git a/os/common/startup/ARMCMx/devices/AT32F402_405xx/cmparams.h b/os/common/startup/ARMCMx/devices/AT32F402_405xx/cmparams.h new file mode 100644 index 0000000000..3b4ed7770d --- /dev/null +++ b/os/common/startup/ARMCMx/devices/AT32F402_405xx/cmparams.h @@ -0,0 +1,88 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2014 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2023..2024 Zhaqian + ChibiOS/RT - Copyright (C) 2023..2024 Maxjta + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file AT32F402_405xx/cmparams.h + * @brief ARM Cortex-M4 parameters for the ArteryTek AT32F402_405 + * + * @defgroup ARMCMx_AT32F402_405 ArteryTek AT32F402_405 Specific Parameters + * @ingroup ARMCMx_SPECIFIC + * @details This file contains the Cortex-M4 specific parameters for the + * ArteryTek AT32F402_405 platform. + * @{ + */ + +#ifndef _CMPARAMS_H_ +#define _CMPARAMS_H_ + +/** + * @brief Cortex core model. + */ +#define CORTEX_MODEL 4 + +/** + * @brief Systick unit presence. + */ +#define CORTEX_HAS_ST TRUE + +/** + * @brief Floating Point unit presence. + */ +#define CORTEX_HAS_FPU TRUE + +/** + * @brief Number of bits in priority masks. + */ +#define CORTEX_PRIORITY_BITS 4 + +/** + * @brief Number of interrupt vectors. + * @note This number does not include the 16 system vectors and must be + * rounded to a multiple of 8. + */ +#define CORTEX_NUM_VECTORS 112 + +/* The following code is not processed when the file is included from an + asm module.*/ +#if !defined(_FROM_ASM_) + +#if !defined (AT32F405xx) && !defined (AT32F402xx) + #include "board.h" +#endif + +/* Including the device CMSIS header. Note, we are not using the definitions + from this header because we need this file to be usable also from + assembler source files. We verify that the info matches instead.*/ +#include "at32f402_405xx.h" + +#if CORTEX_MODEL != __CORTEX_M +#error "CMSIS __CORTEX_M mismatch" +#endif + +#if CORTEX_PRIORITY_BITS != __NVIC_PRIO_BITS +#error "CMSIS __NVIC_PRIO_BITS mismatch" +#endif + +#endif /* !defined(_FROM_ASM_) */ + +#endif /* _CMPARAMS_H_ */ + +/** @} */ diff --git a/os/hal/boards/AT_START_F405/board.c b/os/hal/boards/AT_START_F405/board.c new file mode 100644 index 0000000000..346e5194fb --- /dev/null +++ b/os/hal/boards/AT_START_F405/board.c @@ -0,0 +1,186 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2003..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ +/** + * @brief Type of AT32 GPIO port setup. + */ +typedef struct { + uint32_t cfgr; + uint32_t omode; + uint32_t odrvr; + uint32_t pull; + uint32_t odt; + uint32_t muxl; + uint32_t muxh; + uint32_t hdrv; +} gpio_setup_t; + + +/** + * @brief Type of AT32 GPIO initialization data. + */ +typedef struct { +#if AT32_HAS_GPIOA || defined(__DOXYGEN__) + gpio_setup_t PAData; +#endif +#if AT32_HAS_GPIOB || defined(__DOXYGEN__) + gpio_setup_t PBData; +#endif +#if AT32_HAS_GPIOC || defined(__DOXYGEN__) + gpio_setup_t PCData; +#endif +#if AT32_HAS_GPIOD || defined(__DOXYGEN__) + gpio_setup_t PDData; +#endif +#if AT32_HAS_GPIOF || defined(__DOXYGEN__) + gpio_setup_t PFData; +#endif +} gpio_config_t; + +/** + * @brief AT32 GPIO static initialization data. + */ +static const gpio_config_t gpio_default_config = { +#if AT32_HAS_GPIOA + {VAL_GPIOA_MODE, VAL_GPIOA_OUTPUT, VAL_GPIOA_ODRVR, VAL_GPIOA_PULL, + VAL_GPIOA_ODT, VAL_GPIOA_MUXL, VAL_GPIOA_MUXH, VAL_GPIOA_HDRV}, +#endif +#if AT32_HAS_GPIOB + {VAL_GPIOB_MODE, VAL_GPIOB_OUTPUT, VAL_GPIOB_ODRVR, VAL_GPIOB_PULL, + VAL_GPIOB_ODT, VAL_GPIOB_MUXL, VAL_GPIOB_MUXH, VAL_GPIOB_HDRV}, +#endif +#if AT32_HAS_GPIOC + {VAL_GPIOC_MODE, VAL_GPIOC_OUTPUT, VAL_GPIOC_ODRVR, VAL_GPIOC_PULL, + VAL_GPIOC_ODT, VAL_GPIOC_MUXL, VAL_GPIOC_MUXH, VAL_GPIOC_HDRV}, +#endif +#if AT32_HAS_GPIOD + {VAL_GPIOD_MODE, VAL_GPIOD_OUTPUT, VAL_GPIOD_ODRVR, VAL_GPIOD_PULL, + VAL_GPIOD_ODT, VAL_GPIOD_MUXL, VAL_GPIOD_MUXH, VAL_GPIOD_HDRV}, +#endif +#if AT32_HAS_GPIOF + {VAL_GPIOF_MODE, VAL_GPIOF_OUTPUT, VAL_GPIOF_ODRVR, VAL_GPIOF_PULL, + VAL_GPIOF_ODT, VAL_GPIOF_MUXL, VAL_GPIOF_MUXH, VAL_GPIOF_HDRV}, +#endif +}; + +/** + * @brief PAL setup. + * @details Digital I/O ports static configuration as defined in @p board.h. + * This variable is used by the HAL when initializing the PAL driver. + */ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ +static void gpio_init_lld(at32_gpio_t *gpiop, const gpio_setup_t *config) { + + gpiop->OMODE = config->omode; + gpiop->ODRVR = config->odrvr; + gpiop->PULL = config->pull; + gpiop->ODT = config->odt; + gpiop->MUXL = config->muxl; + gpiop->MUXH = config->muxh; + gpiop->CFGR = config->cfgr; + gpiop->HDRV = config->hdrv; + +} + +static void at32_gpio_init(void) { + + /* Enabling GPIO-related clocks, the mask comes from the + registry header file.*/ + crmEnableAHB1(AT32_GPIO_EN_MASK, false); + crmResetAHB1(AT32_GPIO_EN_MASK); + + /* Initializing all the defined GPIO ports.*/ +#if AT32_HAS_GPIOA + gpio_init_lld(GPIOA, &gpio_default_config.PAData); +#endif +#if AT32_HAS_GPIOB + gpio_init_lld(GPIOB, &gpio_default_config.PBData); +#endif +#if AT32_HAS_GPIOC + gpio_init_lld(GPIOC, &gpio_default_config.PCData); +#endif +#if AT32_HAS_GPIOD + gpio_init_lld(GPIOD, &gpio_default_config.PDData); +#endif +#if AT32_HAS_GPIOF + gpio_init_lld(GPIOF, &gpio_default_config.PFData); +#endif +} +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Early initialization code. + * @details System clocks are initialized before everything else. + */ +void __early_init(void) { + at32_clock_init(); + at32_gpio_init(); +} + +#if HAL_USE_SDC || defined(__DOXYGEN__) +/** + * @brief SDC card detection. + */ +bool sdc_lld_is_card_inserted(SDCDriver *sdcp) { + static bool last_status = false; + + if (blkIsTransferring(sdcp)) + return last_status; + return last_status = (bool)palReadPad(GPIOA, GPIOA_ARD_A2); +} + +/** + * @brief SDC card write protection detection. + */ +bool sdc_lld_is_write_protected(SDCDriver *sdcp) { + + (void)sdcp; + return false; +} +#endif /* HAL_USE_SDC */ + +/** + * @brief Board-specific initialization code. + * @note You can add your board-specific code here. + */ +void boardInit(void) { + +} diff --git a/os/hal/boards/AT_START_F405/board.h b/os/hal/boards/AT_START_F405/board.h new file mode 100644 index 0000000000..c38edc6ff7 --- /dev/null +++ b/os/hal/boards/AT_START_F405/board.h @@ -0,0 +1,682 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/* + * Setup for a AT-START-F405 board. + */ + +/* + * Board identifier. + */ +#define BOARD_AT_START_F405 +#define BOARD_NAME "Artery AT-START-F405" + +/* + * Board oscillators-related settings. + */ +#if !defined(AT32_LEXTCLK) +#define AT32_LEXTCLK 32768 +#endif + +#if !defined(AT32_HEXTCLK) +#define AT32_HEXTCLK 12000000 +#endif + +/* + * MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h. + */ +#define AT32F405RCT7 + +/* + * IO pins assignments. + */ +#define GPIOA_BUTTON 0U +#define GPIOA_PIN1 1U +#define GPIOA_PIN2 2U +#define GPIOA_PIN3 3U +#define GPIOA_PIN4 4U +#define GPIOA_PIN5 5U +#define GPIOA_PIN6 6U +#define GPIOA_PIN7 7U +#define GPIOA_PIN8 8U +#define GPIOA_PIN9 9U +#define GPIOA_PIN10 10U +#define GPIOA_PIN11 11U +#define GPIOA_PIN12 12U +#define GPIOA_SWDIO 13U +#define GPIOA_SWCLK 14U +#define GPIOA_PIN15 15U + +#define GPIOB_PIN0 0U +#define GPIOB_PIN1 1U +#define GPIOB_PIN2 2U +#define GPIOB_PIN3 3U +#define GPIOB_PIN4 4U +#define GPIOB_PIN5 5U +#define GPIOB_PIN6 6U +#define GPIOB_PIN7 7U +#define GPIOB_PIN8 8U +#define GPIOB_PIN9 9U +#define GPIOB_PIN10 10U +#define GPIOB_PIN11 11U +#define GPIOB_PIN12 12U +#define GPIOB_PIN13 13U +#define GPIOB_PIN14 14U +#define GPIOB_PIN15 15U + +#define GPIOC_PIN0 0U +#define GPIOC_PIN1 1U +#define GPIOC_PIN2 2U +#define GPIOC_PIN3 3U +#define GPIOC_PIN4 4U +#define GPIOC_PIN5 5U +#define GPIOC_PIN6 6U +#define GPIOC_PIN7 7U +#define GPIOC_PIN8 8U +#define GPIOC_PIN9 9U +#define GPIOC_PIN10 10U +#define GPIOC_PIN11 11U +#define GPIOC_PIN12 12U +#define GPIOC_PIN13 13U +#define GPIOC_PIN14 14U +#define GPIOC_PIN15 15U + +#define GPIOD_PIN2 15U + +#define GPIOF_HEXT_IN 0U +#define GPIOF_HEXT_OUT 1U +#define GPIOF_PIN4 4U +#define GPIOF_PIN5 5U +#define GPIOF_PIN6 6U +#define GPIOF_PIN7 7U +#define GPIOF_PIN11 11U + + +/* + * IO lines assignments. + */ +#define LINE_BUTTON PAL_LINE(GPIOA, 0U) +#define LINE_LED_RED PAL_LINE(GPIOF, 4U) +#define LINE_LED_YELLOW PAL_LINE(GPIOF, 5U) +#define LINE_LED_GREEN PAL_LINE(GPIOF, 6U) + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + + +/* + * I/O ports initial setup, this configuration is established soon after reset + * in the initialization code. + * Please refer to the AT32 Reference Manual for details. + */ +#define PIN_MODE_INPUT(n) (0U << ((n) * 2U)) +#define PIN_MODE_OUTPUT(n) (1U << ((n) * 2U)) +#define PIN_MODE_MUX(n) (2U << ((n) * 2U)) +#define PIN_MODE_ANALOG(n) (3U << ((n) * 2U)) +#define PIN_ODT_LOW(n) (0U << (n)) +#define PIN_ODT_HIGH(n) (1U << (n)) +#define PIN_OUTPUT_PUSHPULL(n) (0U << (n)) +#define PIN_OUTPUT_OPENDRAIN(n) (1U << (n)) +#define PIN_ODRVR_STRONGER(n) (1U << ((n) * 2U)) +#define PIN_ODRVR_MODERATE(n) (2U << ((n) * 2U)) +#define PIN_PULL_NONE(n) (0U << ((n) * 2U)) +#define PIN_PULL_UP(n) (1U << ((n) * 2U)) +#define PIN_PULL_DOWN(n) (2U << ((n) * 2U)) +#define PIN_MUX(n, v) ((v) << (((n) % 8U) * 4U)) +#define PIN_HDRV_NOTACTIVE(n) (0U << (n)) +#define PIN_HDRV_ACTIVE(n) (1U << (n)) + + +/* + * GPIOA setup: + * + * PA0 - PIN0 (output none pull). + * PA1 - PIN1 (input none pull). + * PA2 - PIN2 (input none pull). + * PA3 - PIN3 (input none pull). + * PA4 - PIN4 (input none pull). + * PA5 - PIN5 (input none pull). + * PA6 - PIN6 (input none pull). + * PA7 - PIN7 (input none pull). + * PA8 - PIN8 (input none pull). + * PA9 - PIN9 (mux 7). + * PA10 - PIN10 (mux 7). + * PA11 - PIN11 (input none pull). + * PA12 - PIN12 (input none pull). + * PA13 - SWDIO (mux 0). + * PA14 - SWCLK (mux 0). + * PA15 - PIN15 (input none pull). + */ +#define VAL_GPIOA_MODE (PIN_MODE_INPUT(GPIOA_BUTTON) | \ + PIN_MODE_INPUT(GPIOA_PIN1) | \ + PIN_MODE_INPUT(GPIOA_PIN2) | \ + PIN_MODE_INPUT(GPIOA_PIN3) | \ + PIN_MODE_INPUT(GPIOA_PIN4) | \ + PIN_MODE_INPUT(GPIOA_PIN5) | \ + PIN_MODE_INPUT(GPIOA_PIN6) | \ + PIN_MODE_INPUT(GPIOA_PIN7) | \ + PIN_MODE_INPUT(GPIOA_PIN8) | \ + PIN_MODE_MUX(GPIOA_PIN9) | \ + PIN_MODE_MUX(GPIOA_PIN10) | \ + PIN_MODE_INPUT(GPIOA_PIN11) | \ + PIN_MODE_INPUT(GPIOA_PIN12) | \ + PIN_MODE_MUX(GPIOA_SWDIO) | \ + PIN_MODE_MUX(GPIOA_SWCLK) | \ + PIN_MODE_INPUT(GPIOA_PIN15)) + +#define VAL_GPIOA_ODT (PIN_ODT_HIGH(GPIOA_BUTTON) | \ + PIN_ODT_HIGH(GPIOA_PIN1) | \ + PIN_ODT_HIGH(GPIOA_PIN2) | \ + PIN_ODT_HIGH(GPIOA_PIN3) | \ + PIN_ODT_HIGH(GPIOA_PIN4) | \ + PIN_ODT_HIGH(GPIOA_PIN5) | \ + PIN_ODT_HIGH(GPIOA_PIN6) | \ + PIN_ODT_HIGH(GPIOA_PIN7) | \ + PIN_ODT_HIGH(GPIOA_PIN8) | \ + PIN_ODT_HIGH(GPIOA_PIN9) | \ + PIN_ODT_HIGH(GPIOA_PIN10) | \ + PIN_ODT_HIGH(GPIOA_PIN11) | \ + PIN_ODT_HIGH(GPIOA_PIN12) | \ + PIN_ODT_HIGH(GPIOA_SWDIO) | \ + PIN_ODT_HIGH(GPIOA_SWCLK) | \ + PIN_ODT_HIGH(GPIOA_PIN15)) + +#define VAL_GPIOA_OUTPUT (PIN_OUTPUT_PUSHPULL(GPIOA_BUTTON) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN1) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN2) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN3) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN4) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN5) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN6) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN7) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN8) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN9) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN10) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN11) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN12) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_SWDIO) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_SWCLK) | \ + PIN_OUTPUT_PUSHPULL(GPIOA_PIN15)) + +#define VAL_GPIOA_ODRVR (PIN_ODRVR_STRONGER(GPIOA_BUTTON) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN1) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN2) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN3) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN4) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN5) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN6) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN7) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN8) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN9) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN10) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN11) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN12) | \ + PIN_ODRVR_STRONGER(GPIOA_SWDIO) | \ + PIN_ODRVR_STRONGER(GPIOA_SWCLK) | \ + PIN_ODRVR_STRONGER(GPIOA_PIN15)) + +#define VAL_GPIOA_PULL (PIN_PULL_NONE(GPIOA_BUTTON) | \ + PIN_PULL_NONE(GPIOA_PIN1) | \ + PIN_PULL_NONE(GPIOA_PIN2) | \ + PIN_PULL_NONE(GPIOA_PIN3) | \ + PIN_PULL_NONE(GPIOA_PIN4) | \ + PIN_PULL_NONE(GPIOA_PIN5) | \ + PIN_PULL_NONE(GPIOA_PIN6) | \ + PIN_PULL_NONE(GPIOA_PIN7) | \ + PIN_PULL_NONE(GPIOA_PIN8) | \ + PIN_PULL_NONE(GPIOA_PIN9) | \ + PIN_PULL_NONE(GPIOA_PIN10) | \ + PIN_PULL_NONE(GPIOA_PIN11) | \ + PIN_PULL_NONE(GPIOA_PIN12) | \ + PIN_PULL_NONE(GPIOA_SWDIO) | \ + PIN_PULL_NONE(GPIOA_SWCLK) | \ + PIN_PULL_NONE(GPIOA_PIN15)) + +#define VAL_GPIOA_MUXL (PIN_MUX(GPIOA_BUTTON, 0U) | \ + PIN_MUX(GPIOA_PIN1, 0U) | \ + PIN_MUX(GPIOA_PIN2, 0U) | \ + PIN_MUX(GPIOA_PIN3, 0U) | \ + PIN_MUX(GPIOA_PIN4, 5U) | \ + PIN_MUX(GPIOA_PIN5, 5U) | \ + PIN_MUX(GPIOA_PIN6, 5U) | \ + PIN_MUX(GPIOA_PIN7, 5U)) + +#define VAL_GPIOA_MUXH (PIN_MUX(GPIOA_PIN8, 0U) | \ + PIN_MUX(GPIOA_PIN9, 7U) | \ + PIN_MUX(GPIOA_PIN10, 7U) | \ + PIN_MUX(GPIOA_PIN11, 0U) | \ + PIN_MUX(GPIOA_PIN12, 0U) | \ + PIN_MUX(GPIOA_SWDIO, 0U) | \ + PIN_MUX(GPIOA_SWCLK, 0U) | \ + PIN_MUX(GPIOA_PIN15, 0U)) + +#define VAL_GPIOA_HDRV (PIN_HDRV_NOTACTIVE(GPIOA_BUTTON) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN1) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN2) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN3) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN4) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN5) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN6) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN7) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN8) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN9) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN10) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN11) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN12) | \ + PIN_HDRV_NOTACTIVE(GPIOA_SWDIO) | \ + PIN_HDRV_NOTACTIVE(GPIOA_SWCLK) | \ + PIN_HDRV_NOTACTIVE(GPIOA_PIN15)) +/* + * GPIOB setup: + * + * PB0 - PIN0 (input none pull). + * PB1 - PIN1 (input none pull). + * PB2 - PIN2 (input none pull). + * PB3 - PIN3 (input none pull). + * PB4 - PIN4 (input none pull). + * PB5 - PIN5 (input none pull). + * PB6 - PIN6 (input none pull). + * PB7 - PIN7 (input none pull). + * PB8 - PIN8 (input none pull). + * PB9 - PIN9 (input none pull). + * PB10 - PIN10 (input none pull). + * PB11 - PIN11 (input none pull). + * PB12 - PIN12 (input none pull). + * PB13 - PIN13 (input none pull). + * PB14 - PIN14 (input none pull). + * PB15 - PIN15 (input none pull). + */ +#define VAL_GPIOB_MODE (PIN_MODE_INPUT(GPIOB_PIN0) | \ + PIN_MODE_INPUT(GPIOB_PIN1) | \ + PIN_MODE_INPUT(GPIOB_PIN2) | \ + PIN_MODE_INPUT(GPIOB_PIN3) | \ + PIN_MODE_INPUT(GPIOB_PIN4) | \ + PIN_MODE_INPUT(GPIOB_PIN5) | \ + PIN_MODE_INPUT(GPIOB_PIN6) | \ + PIN_MODE_INPUT(GPIOB_PIN7) | \ + PIN_MODE_INPUT(GPIOB_PIN8) | \ + PIN_MODE_INPUT(GPIOB_PIN9) | \ + PIN_MODE_INPUT(GPIOB_PIN10) | \ + PIN_MODE_INPUT(GPIOB_PIN11) | \ + PIN_MODE_INPUT(GPIOB_PIN12) | \ + PIN_MODE_INPUT(GPIOB_PIN13) | \ + PIN_MODE_INPUT(GPIOB_PIN14) | \ + PIN_MODE_INPUT(GPIOB_PIN15)) + +#define VAL_GPIOB_ODT (PIN_ODT_HIGH(GPIOB_PIN0) | \ + PIN_ODT_HIGH(GPIOB_PIN1) | \ + PIN_ODT_HIGH(GPIOB_PIN2) | \ + PIN_ODT_HIGH(GPIOB_PIN3) | \ + PIN_ODT_HIGH(GPIOB_PIN4) | \ + PIN_ODT_HIGH(GPIOB_PIN5) | \ + PIN_ODT_HIGH(GPIOB_PIN6) | \ + PIN_ODT_HIGH(GPIOB_PIN7) | \ + PIN_ODT_HIGH(GPIOB_PIN8) | \ + PIN_ODT_HIGH(GPIOB_PIN9) | \ + PIN_ODT_HIGH(GPIOB_PIN10) | \ + PIN_ODT_HIGH(GPIOB_PIN11) | \ + PIN_ODT_HIGH(GPIOB_PIN12) | \ + PIN_ODT_HIGH(GPIOB_PIN13) | \ + PIN_ODT_HIGH(GPIOB_PIN14) | \ + PIN_ODT_HIGH(GPIOB_PIN15)) + +#define VAL_GPIOB_OUTPUT (PIN_OUTPUT_PUSHPULL(GPIOB_PIN0) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN1) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN2) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN3) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN4) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN5) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN6) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN7) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN8) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN9) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN10) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN11) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN12) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN13) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN14) | \ + PIN_OUTPUT_PUSHPULL(GPIOB_PIN15)) + +#define VAL_GPIOB_ODRVR (PIN_ODRVR_STRONGER(GPIOB_PIN0) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN1) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN2) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN3) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN4) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN5) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN6) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN7) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN8) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN9) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN10) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN11) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN12) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN13) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN14) | \ + PIN_ODRVR_STRONGER(GPIOB_PIN15)) + +#define VAL_GPIOB_PULL (PIN_PULL_NONE(GPIOB_PIN0) | \ + PIN_PULL_NONE(GPIOB_PIN1) | \ + PIN_PULL_NONE(GPIOB_PIN2) | \ + PIN_PULL_NONE(GPIOB_PIN3) | \ + PIN_PULL_NONE(GPIOB_PIN4) | \ + PIN_PULL_NONE(GPIOB_PIN5) | \ + PIN_PULL_NONE(GPIOB_PIN6) | \ + PIN_PULL_NONE(GPIOB_PIN7) | \ + PIN_PULL_NONE(GPIOB_PIN8) | \ + PIN_PULL_NONE(GPIOB_PIN9) | \ + PIN_PULL_NONE(GPIOB_PIN10) | \ + PIN_PULL_NONE(GPIOB_PIN11) | \ + PIN_PULL_NONE(GPIOB_PIN12) | \ + PIN_PULL_NONE(GPIOB_PIN13) | \ + PIN_PULL_NONE(GPIOB_PIN14) | \ + PIN_PULL_NONE(GPIOB_PIN15)) + +#define VAL_GPIOB_MUXL (PIN_MUX(GPIOB_PIN0, 0U) | \ + PIN_MUX(GPIOB_PIN1, 0U) | \ + PIN_MUX(GPIOB_PIN2, 0U) | \ + PIN_MUX(GPIOB_PIN3, 0U) | \ + PIN_MUX(GPIOB_PIN4, 0U) | \ + PIN_MUX(GPIOB_PIN5, 0U) | \ + PIN_MUX(GPIOB_PIN6, 0U) | \ + PIN_MUX(GPIOB_PIN7, 0U)) + +#define VAL_GPIOB_MUXH (PIN_MUX(GPIOB_PIN8, 0U) | \ + PIN_MUX(GPIOB_PIN9, 0U) | \ + PIN_MUX(GPIOB_PIN10, 0U) | \ + PIN_MUX(GPIOB_PIN11, 0U) | \ + PIN_MUX(GPIOB_PIN12, 0U) | \ + PIN_MUX(GPIOB_PIN13, 0U) | \ + PIN_MUX(GPIOB_PIN14, 0U) | \ + PIN_MUX(GPIOB_PIN15, 0U)) + +#define VAL_GPIOB_HDRV (PIN_HDRV_NOTACTIVE(GPIOB_PIN0) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN1) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN2) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN3) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN4) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN5) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN6) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN7) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN8) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN9) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN10) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN11) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN12) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN13) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN14) | \ + PIN_HDRV_NOTACTIVE(GPIOB_PIN15)) + +/* + * GPIOC setup: + * + * PC0 - PIN0 (input none pull). + * PC1 - PIN1 (input none pull). + * PC2 - PIN2 (input none pull). + * PC3 - PIN3 (input none pull). + * PC4 - PIN4 (input none pull). + * PC5 - PIN5 (input none pull). + * PC6 - PIN6 (input none pull). + * PC7 - PIN7 (input none pull). + * PC8 - PIN8 (input none pull). + * PC9 - PIN9 (input none pull). + * PC10 - PIN10 (input none pull). + * PC11 - PIN11 (input none pull). + * PC12 - PIN12 (input none pull). + * PC13 - PIN13 (input none pull). + * PC14 - PIN14 (input none pull). + * PC15 - PIN15 (input none pull). + */ +#define VAL_GPIOC_MODE (PIN_MODE_INPUT(GPIOC_PIN0) | \ + PIN_MODE_INPUT(GPIOC_PIN1) | \ + PIN_MODE_INPUT(GPIOC_PIN2) | \ + PIN_MODE_INPUT(GPIOC_PIN3) | \ + PIN_MODE_INPUT(GPIOC_PIN4) | \ + PIN_MODE_INPUT(GPIOC_PIN5) | \ + PIN_MODE_INPUT(GPIOC_PIN6) | \ + PIN_MODE_INPUT(GPIOC_PIN7) | \ + PIN_MODE_INPUT(GPIOC_PIN8) | \ + PIN_MODE_INPUT(GPIOC_PIN9) | \ + PIN_MODE_INPUT(GPIOC_PIN10) | \ + PIN_MODE_INPUT(GPIOC_PIN11) | \ + PIN_MODE_INPUT(GPIOC_PIN12) | \ + PIN_MODE_INPUT(GPIOC_PIN13) | \ + PIN_MODE_INPUT(GPIOC_PIN14) | \ + PIN_MODE_INPUT(GPIOC_PIN15)) + +#define VAL_GPIOC_ODT (PIN_ODT_HIGH(GPIOC_PIN0) | \ + PIN_ODT_HIGH(GPIOC_PIN1) | \ + PIN_ODT_HIGH(GPIOC_PIN2) | \ + PIN_ODT_HIGH(GPIOC_PIN3) | \ + PIN_ODT_HIGH(GPIOC_PIN4) | \ + PIN_ODT_HIGH(GPIOC_PIN5) | \ + PIN_ODT_HIGH(GPIOC_PIN6) | \ + PIN_ODT_HIGH(GPIOC_PIN7) | \ + PIN_ODT_HIGH(GPIOC_PIN8) | \ + PIN_ODT_HIGH(GPIOC_PIN9) | \ + PIN_ODT_HIGH(GPIOC_PIN10) | \ + PIN_ODT_HIGH(GPIOC_PIN11) | \ + PIN_ODT_HIGH(GPIOC_PIN12) | \ + PIN_ODT_HIGH(GPIOC_PIN13) | \ + PIN_ODT_HIGH(GPIOC_PIN14) | \ + PIN_ODT_HIGH(GPIOC_PIN15)) + +#define VAL_GPIOC_OUTPUT (PIN_OUTPUT_PUSHPULL(GPIOC_PIN0) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN1) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN2) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN3) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN4) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN5) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN6) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN7) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN8) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN9) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN10) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN11) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN12) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN13) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN14) | \ + PIN_OUTPUT_PUSHPULL(GPIOC_PIN15)) + +#define VAL_GPIOC_ODRVR (PIN_ODRVR_STRONGER(GPIOC_PIN0) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN1) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN2) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN3) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN4) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN5) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN6) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN7) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN8) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN9) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN10) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN11) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN12) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN13) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN14) | \ + PIN_ODRVR_STRONGER(GPIOC_PIN15)) + +#define VAL_GPIOC_PULL (PIN_PULL_NONE(GPIOC_PIN0) | \ + PIN_PULL_NONE(GPIOC_PIN1) | \ + PIN_PULL_NONE(GPIOC_PIN2) | \ + PIN_PULL_NONE(GPIOC_PIN3) | \ + PIN_PULL_NONE(GPIOC_PIN4) | \ + PIN_PULL_NONE(GPIOC_PIN5) | \ + PIN_PULL_NONE(GPIOC_PIN6) | \ + PIN_PULL_NONE(GPIOC_PIN7) | \ + PIN_PULL_NONE(GPIOC_PIN8) | \ + PIN_PULL_NONE(GPIOC_PIN9) | \ + PIN_PULL_NONE(GPIOC_PIN10) | \ + PIN_PULL_NONE(GPIOC_PIN11) | \ + PIN_PULL_NONE(GPIOC_PIN12) | \ + PIN_PULL_NONE(GPIOC_PIN13) | \ + PIN_PULL_NONE(GPIOC_PIN14) | \ + PIN_PULL_NONE(GPIOC_PIN15)) + +#define VAL_GPIOC_MUXL (PIN_MUX(GPIOC_PIN0, 0U) | \ + PIN_MUX(GPIOC_PIN1, 0U) | \ + PIN_MUX(GPIOC_PIN2, 0U) | \ + PIN_MUX(GPIOC_PIN3, 0U) | \ + PIN_MUX(GPIOC_PIN4, 0U) | \ + PIN_MUX(GPIOC_PIN5, 0U) | \ + PIN_MUX(GPIOC_PIN6, 0U) | \ + PIN_MUX(GPIOC_PIN7, 0U)) + +#define VAL_GPIOC_MUXH (PIN_MUX(GPIOC_PIN8, 0U) | \ + PIN_MUX(GPIOC_PIN9, 0U) | \ + PIN_MUX(GPIOC_PIN10, 0U) | \ + PIN_MUX(GPIOC_PIN11, 0U) | \ + PIN_MUX(GPIOC_PIN12, 0U) | \ + PIN_MUX(GPIOC_PIN13, 0U) | \ + PIN_MUX(GPIOC_PIN14, 0U) | \ + PIN_MUX(GPIOC_PIN15, 0U)) + +#define VAL_GPIOC_HDRV (PIN_HDRV_NOTACTIVE(GPIOC_PIN0) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN1) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN2) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN3) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN4) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN5) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN6) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN7) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN8) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN9) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN10) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN11) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN12) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN13) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN14) | \ + PIN_HDRV_NOTACTIVE(GPIOC_PIN15)) + +/* + * GPIOD setup: + * PD2 - PIN2 (input none pull). + */ +#define VAL_GPIOD_MODE (PIN_MODE_INPUT(GPIOD_PIN2)) +#define VAL_GPIOD_ODT (PIN_ODT_HIGH(GPIOD_PIN2)) +#define VAL_GPIOD_OUTPUT (PIN_OUTPUT_PUSHPULL(GPIOD_PIN2)) +#define VAL_GPIOD_ODRVR (PIN_ODRVR_STRONGER(GPIOD_PIN2)) +#define VAL_GPIOD_PULL (PIN_PULL_NONE(GPIOD_PIN2)) +#define VAL_GPIOD_MUXL (PIN_MUX(GPIOD_PIN2, 0U)) +#define VAL_GPIOD_MUXH 0U +#define VAL_GPIOD_HDRV (PIN_HDRV_NOTACTIVE(GPIOD_PIN2)) + +/* + * GPIOF setup: + * + * PF0 - PIN0 (input none pull). + * PF1 - PIN1 (input none pull). + * PF4 - PIN4 (output none pull). + * PF5 - PIN5 (output none pull). + * PF6 - PIN6 (output none pull). + * PF7 - PIN7 (input none pull). + * PF11 - PIN11 (input none pull). + */ +#define VAL_GPIOF_MODE (PIN_MODE_INPUT(GPIOF_HEXT_IN) | \ + PIN_MODE_INPUT(GPIOF_HEXT_OUT) | \ + PIN_MODE_OUTPUT(GPIOF_PIN4) | \ + PIN_MODE_OUTPUT(GPIOF_PIN5) | \ + PIN_MODE_OUTPUT(GPIOF_PIN6) | \ + PIN_MODE_INPUT(GPIOF_PIN7) | \ + PIN_MODE_INPUT(GPIOF_PIN11)) + +#define VAL_GPIOF_ODT (PIN_ODT_HIGH(GPIOF_HEXT_IN) | \ + PIN_ODT_HIGH(GPIOF_HEXT_OUT) | \ + PIN_ODT_HIGH(GPIOF_PIN4) | \ + PIN_ODT_HIGH(GPIOF_PIN5) | \ + PIN_ODT_HIGH(GPIOF_PIN6) | \ + PIN_ODT_HIGH(GPIOF_PIN7) | \ + PIN_ODT_HIGH(GPIOF_PIN11)) + + +#define VAL_GPIOF_OUTPUT (PIN_OUTPUT_PUSHPULL(GPIOF_HEXT_IN) | \ + PIN_OUTPUT_PUSHPULL(GPIOF_HEXT_OUT) | \ + PIN_OUTPUT_PUSHPULL(GPIOF_PIN4) | \ + PIN_OUTPUT_PUSHPULL(GPIOF_PIN5) | \ + PIN_OUTPUT_PUSHPULL(GPIOF_PIN6) | \ + PIN_OUTPUT_PUSHPULL(GPIOF_PIN7) | \ + PIN_OUTPUT_PUSHPULL(GPIOF_PIN11)) + + +#define VAL_GPIOF_ODRVR (PIN_ODRVR_STRONGER(GPIOF_HEXT_IN) | \ + PIN_ODRVR_STRONGER(GPIOF_HEXT_OUT) | \ + PIN_ODRVR_STRONGER(GPIOF_PIN4) | \ + PIN_ODRVR_STRONGER(GPIOF_PIN5) | \ + PIN_ODRVR_STRONGER(GPIOF_PIN6) | \ + PIN_ODRVR_STRONGER(GPIOF_PIN7) | \ + PIN_ODRVR_STRONGER(GPIOF_PIN11)) + +#define VAL_GPIOF_PULL (PIN_PULL_NONE(GPIOF_HEXT_IN) | \ + PIN_PULL_NONE(GPIOF_HEXT_OUT) | \ + PIN_PULL_NONE(GPIOF_PIN4) | \ + PIN_PULL_NONE(GPIOF_PIN5) | \ + PIN_PULL_NONE(GPIOF_PIN6) | \ + PIN_PULL_NONE(GPIOF_PIN7) | \ + PIN_PULL_NONE(GPIOF_PIN11)) + +#define VAL_GPIOF_MUXL (PIN_MUX(GPIOF_HEXT_IN, 0U) | \ + PIN_MUX(GPIOF_HEXT_OUT, 0U) | \ + PIN_MUX(GPIOF_PIN4, 0U) | \ + PIN_MUX(GPIOF_PIN5, 0U) | \ + PIN_MUX(GPIOF_PIN6, 0U) | \ + PIN_MUX(GPIOF_PIN7, 0U) | \ + PIN_MUX(GPIOF_PIN11, 0U)) +#define VAL_GPIOF_MUXH 0U + +#define VAL_GPIOF_HDRV (PIN_HDRV_NOTACTIVE(GPIOF_HEXT_IN) | \ + PIN_HDRV_NOTACTIVE(GPIOF_HEXT_OUT) | \ + PIN_HDRV_NOTACTIVE(GPIOF_PIN4) | \ + PIN_HDRV_NOTACTIVE(GPIOF_PIN5) | \ + PIN_HDRV_NOTACTIVE(GPIOF_PIN6) | \ + PIN_HDRV_NOTACTIVE(GPIOF_PIN7) | \ + PIN_HDRV_NOTACTIVE(GPIOF_PIN11)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(_FROM_ASM_) +#ifdef __cplusplus +extern "C" { +#endif + void boardInit(void); +#ifdef __cplusplus +} +#endif +#endif /* _FROM_ASM_ */ + +#endif /* _BOARD_H_ */ diff --git a/os/hal/boards/AT_START_F405/board.mk b/os/hal/boards/AT_START_F405/board.mk new file mode 100644 index 0000000000..5486230056 --- /dev/null +++ b/os/hal/boards/AT_START_F405/board.mk @@ -0,0 +1,9 @@ +# List of all the board related files. +BOARDSRC = $(CHIBIOS_CONTRIB)/os/hal/boards/AT_START_F405/board.c + +# Required include directories +BOARDINC = ${CHIBIOS_CONTRIB}/os/hal/boards/AT_START_F405 + +# Shared variables +ALLCSRC += $(BOARDSRC) +ALLINC += $(BOARDINC) diff --git a/os/hal/ports/AT32/AT32F405xx/at32_crm.h b/os/hal/ports/AT32/AT32F405xx/at32_crm.h new file mode 100644 index 0000000000..fb5a4274cc --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/at32_crm.h @@ -0,0 +1,1192 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/at32_crm.h + * @brief CRM helper driver header. + * @note This file requires definitions from the AT header file + * @p at32f402_405xx.h. + * + * @addtogroup AT32F405xx_CRM + * @{ + */ + +#ifndef AT32_CRM_H +#define AT32_CRM_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile TMRe settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Generic CRM operations + * @{ + */ +/** + * @brief Enables the clock of one or more peripheral on the APB1 bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask APB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableAPB1(mask, lp) { \ + CRM->APB1EN |= (mask); \ + if (lp) \ + CRM->APB1LPEN |= (mask); \ + else \ + CRM->APB1LPEN &= ~(mask); \ + (void)CRM->APB1LPEN; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB1 bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask APB1 peripherals mask + * + * @api + */ +#define crmDisableAPB1(mask) { \ + CRM->APB1EN &= ~(mask); \ + CRM->APB1LPEN &= ~(mask); \ + (void)CRM->APB1LPEN; \ +} + +/** + * @brief Resets one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * + * @api + */ +#define crmResetAPB1(mask) { \ + CRM->APB1RST |= (mask); \ + CRM->APB1RST &= ~(mask); \ + (void)CRM->APB1RST; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the APB2 bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask APB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableAPB2(mask, lp) { \ + CRM->APB2EN |= (mask); \ + if (lp) \ + CRM->APB2LPEN |= (mask); \ + else \ + CRM->APB2LPEN &= ~(mask); \ + (void)CRM->APB2LPEN; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB2 bus. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] mask APB2 peripherals mask + * + * @api + */ +#define crmDisableAPB2(mask) { \ + CRM->APB2EN &= ~(mask); \ + CRM->APB2LPEN &= ~(mask); \ + (void)CRM->APB2LPEN; \ +} + +/** + * @brief Resets one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * + * @api + */ +#define crmResetAPB2(mask) { \ + CRM->APB2RST |= (mask); \ + CRM->APB2RST &= ~(mask); \ + (void)CRM->APB2RST; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableAHB1(mask, lp) { \ + CRM->AHBEN1 |= (mask); \ + if (lp) \ + CRM->AHBLPEN1 |= (mask); \ + else \ + CRM->AHBLPEN1 &= ~(mask); \ + (void)CRM->AHBLPEN1; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * + * @api + */ +#define crmDisableAHB1(mask) { \ + CRM->AHBEN1 &= ~(mask); \ + CRM->AHBLPEN1 &= ~(mask); \ + (void)CRM->AHBLPEN1; \ +} + +/** + * @brief Resets one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * + * @api + */ +#define crmResetAHB1(mask) { \ + CRM->AHBRST1 |= (mask); \ + CRM->AHBRST1 &= ~(mask); \ + (void)CRM->AHBRST1; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableAHB2(mask, lp) { \ + CRM->AHBEN2 |= (mask); \ + if (lp) \ + CRM->AHBLPEN2 |= (mask); \ + else \ + CRM->AHBLPEN2 &= ~(mask); \ + (void)CRM->AHBLPEN2; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * + * @api + */ +#define crmDisableAHB2(mask) { \ + CRM->AHBEN2 &= ~(mask); \ + CRM->AHBLPEN2 &= ~(mask); \ + (void)CRM->AHBLPEN2; \ +} + +/** + * @brief Resets one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * + * @api + */ +#define crmResetAHB2(mask) { \ + CRM->AHBRST2 |= (mask); \ + CRM->AHBRST2 &= ~(mask); \ + (void)CRM->AHBRST2; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableAHB3(mask, lp) { \ + CRM->AHBEN3 |= (mask); \ + if (lp) \ + CRM->AHBLPEN3 |= (mask); \ + else \ + CRM->AHBLPEN3 &= ~(mask); \ + (void)CRM->AHBLPEN3; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * + * @api + */ +#define crmDisableAHB3(mask) { \ + CRM->AHBEN3 &= ~(mask); \ + CRM->AHBLPEN3 &= ~(mask); \ + (void)CRM->AHBLPEN3; \ +} + +/** + * @brief Resets one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * + * @api + */ +#define crmResetAHB3(mask) { \ + CRM->AHBRST3 |= (mask); \ + CRM->AHBRST3 &= ~(mask); \ + (void)CRM->AHBRST3; \ +} +/** @} */ + +/** + * @name ADC peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the ADC1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableADC1(lp) crmEnableAPB2(CRM_APB2EN_ADC1EN, lp) + +/** + * @brief Disables the ADC1 peripheral clock. + * + * @api + */ +#define crmDisableADC1() crmDisableAPB2(CRM_APB2EN_ADC1EN) + +/** + * @brief Resets the ADC1 peripheral. + * + * @api + */ +#define crmResetADC1() crmResetAPB2(CRM_APB2RST_ADC1RST) +/** @} */ + +/** + * @name PWC interface specific CRM operations + * @{ + */ +/** + * @brief Enables the PWC interface clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnablePWCInterface(lp) crmEnableAPB1(CRM_APB1EN_PWCEN, lp) + +/** + * @brief Disables PWC interface clock. + * + * @api + */ +#define crmDisablePWCInterface() crmDisableAPB1(CRM_APB1EN_PWCEN) + +/** + * @brief Resets the PWC interface. + * + * @api + */ +#define crmResetPWCInterface() crmResetAPB1(CRM_APB1RST_PWCRST) +/** @} */ + +/** + * @name CAN peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the CAN1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableCAN1(lp) crmEnableAPB1(CRM_APB1EN_CAN1EN, lp) + +/** + * @brief Disables the CAN1 peripheral clock. + * + * @api + */ +#define crmDisableCAN1() crmDisableAPB1(CRM_APB1EN_CAN1EN) + +/** + * @brief Resets the CAN1 peripheral. + * + * @api + */ +#define crmResetCAN1() crmResetAPB1(CRM_APB1RST_CAN1RST) + +/** + * @name DMA peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the DMA1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableDMA1(lp) crmEnableAHB1(CRM_AHBEN1_DMA1EN, lp) + +/** + * @brief Disables the DMA1 peripheral clock. + * + * @api + */ +#define crmDisableDMA1() crmDisableAHB1(CRM_AHBEN1_DMA1EN) + +/** + * @brief Resets the DMA1 peripheral. + * @note Not supported in this family, does nothing. + * + * @api + */ +#define crmResetDMA1() crmResetAHB1(CRM_AHBRST1_DMA1RST) + +/** + * @brief Enables the DMA2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableDMA2(lp) crmEnableAHB1(CRM_AHBEN1_DMA2EN, lp) + +/** + * @brief Disables the DMA2 peripheral clock. + * + * @api + */ +#define crmDisableDMA2() crmDisableAHB1(CRM_AHBEN1_DMA2EN) + +/** + * @brief Resets the DMA2 peripheral. + * @note Not supported in this family, does nothing. + * + * @api + */ +#define crmResetDMA2() crmResetAHB1(CRM_AHBRST1_DMA2RST) +/** @} */ + +/** + * @name I2C peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the I2C1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableI2C1(lp) crmEnableAPB1(CRM_APB1EN_I2C1EN, lp) + +/** + * @brief Disables the I2C1 peripheral clock. + * + * @api + */ +#define crmDisableI2C1() crmDisableAPB1(CRM_APB1EN_I2C1EN) + +/** + * @brief Resets the I2C1 peripheral. + * + * @api + */ +#define crmResetI2C1() crmResetAPB1(CRM_APB1RST_I2C1RST) + +/** + * @brief Enables the I2C2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableI2C2(lp) crmEnableAPB1(CRM_APB1EN_I2C2EN, lp) + +/** + * @brief Disables the I2C2 peripheral clock. + * + * @api + */ +#define crmDisableI2C2() crmDisableAPB1(CRM_APB1EN_I2C2EN) + +/** + * @brief Resets the I2C2 peripheral. + * + * @api + */ +#define crmResetI2C2() crmResetAPB1(CRM_APB1RST_I2C2RST) + +/** + * @brief Enables the I2C3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableI2C3(lp) crmEnableAPB1(CRM_APB1EN_I2C3EN, lp) + +/** + * @brief Disables the I2C3 peripheral clock. + * + * @api + */ +#define crmDisableI2C3() crmDisableAPB1(CRM_APB1EN_I2C3EN) + +/** + * @brief Resets the I2C3 peripheral. + * + * @api + */ +#define crmResetI2C3() crmResetAPB1(CRM_APB1RST_I2C3RST) +/** @} */ + +/** + * @name OTG peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the OTG_FS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableOTG_FS1(lp) crmEnableAHB2(CRM_AHBEN2_OTGFS1EN, lp) +#define crmEnableOTG_FS(lp) crmEnableOTG_FS1(lp) + +/** + * @brief Disables the OTG_FS peripheral clock. + * + * @api + */ +#define crmDisableOTG_FS1() crmDisableAHB2(CRM_AHBEN2_OTGFS1EN) +#define crmDisableOTG_FS() crmDisableOTG_FS1() + +/** + * @brief Resets the OTG_FS peripheral. + * + * @api + */ +#define crmResetOTG_FS1() crmResetAHB2(CRM_AHBRST2_OTGFS1RST) +#define crmResetOTG_FS() crmResetOTG_FS1() +/** + * @brief Enables the OTG_HS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableOTG_HS(lp) crmEnableAHB1(CRM_AHBEN1_OTGHSEN, lp) + +/** + * @brief Disables the OTG_HS peripheral clock. + * + * @api + */ +#define crmDisableOTG_HS() crmDisableAHB1(CRM_AHBEN1_OTGHSEN) + +/** + * @brief Resets the OTG_HS peripheral. + * + * @api + */ +#define crmResetOTG_HS() crmResetAHB1(CRM_AHBRST1_OTGHSRST) +/** @} */ + +/** + * @name QUADSPI peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the QUADSPI1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableQUADSPI1(lp) crmEnableAHB3(CRM_AHBEN3_QSPI1EN, lp) + +/** + * @brief Disables the QUADSPI1 peripheral clock. + * + * @api + */ +#define crmDisableQUADSPI1() crmDisableAHB3(CRM_AHBEN3_QSPI1EN) + +/** + * @brief Resets the QUADSPI1 peripheral. + * + * @api + */ +#define crmResetQUADSPI1() crmResetAHB3(CRM_AHBRST3_QSPI1RST) +/** @} */ + +/** + * @name SPI peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the SPI1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableSPI1(lp) crmEnableAPB2(CRM_APB2EN_SPI1EN, lp) + +/** + * @brief Disables the SPI1 peripheral clock. + * + * @api + */ +#define crmDisableSPI1() crmDisableAPB2(CRM_APB2EN_SPI1EN) + +/** + * @brief Resets the SPI1 peripheral. + * + * @api + */ +#define crmResetSPI1() crmResetAPB2(CRM_APB2RST_SPI1RST) + +/** + * @brief Enables the SPI2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableSPI2(lp) crmEnableAPB1(CRM_APB1EN_SPI2EN, lp) + +/** + * @brief Disables the SPI2 peripheral clock. + * + * @api + */ +#define crmDisableSPI2() crmDisableAPB1(CRM_APB1EN_SPI2EN) + +/** + * @brief Resets the SPI2 peripheral. + * + * @api + */ +#define crmResetSPI2() crmResetAPB1(CRM_APB1RST_SPI2RST) + +/** + * @brief Enables the SPI3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableSPI3(lp) crmEnableAPB1(CRM_APB1EN_SPI3EN, lp) + +/** + * @brief Disables the SPI3 peripheral clock. + * + * @api + */ +#define crmDisableSPI3() crmDisableAPB1(CRM_APB1EN_SPI3EN) + +/** + * @brief Resets the SPI3 peripheral. + * + * @api + */ +#define crmResetSPI3() crmResetAPB1(CRM_APB1RST_SPI3RST) +/** @} */ + +/** + * @name TMR peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the TMR1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR1(lp) crmEnableAPB2(CRM_APB2EN_TMR1EN, lp) + +/** + * @brief Disables the TMR1 peripheral clock. + * + * @api + */ +#define crmDisableTMR1() crmDisableAPB2(CRM_APB2EN_TMR1EN) + +/** + * @brief Resets the TMR1 peripheral. + * + * @api + */ +#define crmResetTMR1() crmResetAPB2(CRM_APB2RST_TMR1RST) + +/** + * @brief Enables the TMR2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR2(lp) crmEnableAPB1(CRM_APB1EN_TMR2EN, lp) + +/** + * @brief Disables the TMR2 peripheral clock. + * + * @api + */ +#define crmDisableTMR2() crmDisableAPB1(CRM_APB1EN_TMR2EN) + +/** + * @brief Resets the TMR2 peripheral. + * + * @api + */ +#define crmResetTMR2() crmResetAPB1(CRM_APB1RST_TMR2RST) + +/** + * @brief Enables the TMR3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR3(lp) crmEnableAPB1(CRM_APB1EN_TMR3EN, lp) + +/** + * @brief Disables the TMR3 peripheral clock. + * + * @api + */ +#define crmDisableTMR3() crmDisableAPB1(CRM_APB1EN_TMR3EN) + +/** + * @brief Resets the TMR3 peripheral. + * + * @api + */ +#define crmResetTMR3() crmResetAPB1(CRM_APB1RST_TMR3RST) + +/** + * @brief Enables the TMR4 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR4(lp) crmEnableAPB1(CRM_APB1EN_TMR4EN, lp) + +/** + * @brief Disables the TMR4 peripheral clock. + * + * @api + */ +#define crmDisableTMR4() crmDisableAPB1(CRM_APB1EN_TMR4EN) + +/** + * @brief Resets the TMR4 peripheral. + * + * @api + */ +#define crmResetTMR4() crmResetAPB1(CRM_APB1RST_TMR4RST) + +/** + * @brief Enables the TMR6 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR6(lp) crmEnableAPB1(CRM_APB1EN_TMR6EN, lp) + +/** + * @brief Disables the TMR6 peripheral clock. + * + * @api + */ +#define crmDisableTMR6() crmDisableAPB1(CRM_APB1EN_TMR6EN) + +/** + * @brief Resets the TMR6 peripheral. + * + * @api + */ +#define crmResetTMR6() crmResetAPB1(CRM_APB1RST_TMR6RST) + +/** + * @brief Enables the TMR7 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR7(lp) crmEnableAPB1(CRM_APB1EN_TMR7EN, lp) + +/** + * @brief Disables the TMR7 peripheral clock. + * + * @api + */ +#define crmDisableTMR7() crmDisableAPB1(CRM_APB1EN_TMR7EN) + +/** + * @brief Resets the TMR7 peripheral. + * + * @api + */ +#define crmResetTMR7() crmResetAPB1(CRM_APB1RST_TMR7RST) + +/** + + * @brief Enables the TMR9 peripheral clock. + + * @note The @p lp parameter is ignored in this family. + + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR9(lp) crmEnableAPB2(CRM_APB2EN_TMR9EN, lp) + +/** + * @brief Disables the TMR9 peripheral clock. + * + * @api + */ +#define crmDisableTMR9() crmDisableAPB2(CRM_APB2EN_TMR9EN) + +/** + * @brief Resets the TMR9 peripheral. + * + * @api + */ +#define crmResetTMR9() crmResetAPB2(CRM_APB2RST_TMR9RST) + +/** + * @brief Enables the TMR10 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR10(lp) crmEnableAPB2(CRM_APB2EN_TMR10EN, lp) + +/** + * @brief Disables the TMR10 peripheral clock. + * + * @api + */ +#define crmDisableTMR10() crmDisableAPB2(CRM_APB2EN_TMR10EN) + +/** + * @brief Resets the TMR10 peripheral. + * + * @api + */ +#define crmResetTMR10() crmResetAPB2(CRM_APB2RST_TMR10RST) + +/** + * @brief Enables the TMR11 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR11(lp) crmEnableAPB2(CRM_APB2EN_TMR11EN, lp) + +/** + * @brief Disables the TMR11 peripheral clock. + * + * @api + */ +#define crmDisableTMR11() crmDisableAPB2(CRM_APB2EN_TMR11EN) + +/** + * @brief Resets the TMR11 peripheral. + * + * @api + */ +#define crmResetTMR11() crmResetAPB2(CRM_APB2RST_TMR11RST) + +/** + * @brief Enables the TMR13 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR13(lp) crmEnableAPB1(CRM_APB1EN_TMR13EN, lp) + +/** + * @brief Disables the TMR13 peripheral clock. + * + * @api + */ +#define crmDisableTMR13() crmDisableAPB1(CRM_APB1EN_TMR13EN) + +/** + * @brief Resets the TMR13 peripheral. + * + * @api + */ +#define crmResetTMR13() crmResetAPB1(CRM_APB1RST_TMR13RST) + +/** + * @brief Enables the TMR14 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableTMR14(lp) crmEnableAPB1(CRM_APB1EN_TMR14EN, lp) + +/** + * @brief Disables the TMR14 peripheral clock. + * + * @api + */ +#define crmDisableTMR14() crmDisableAPB1(CRM_APB1EN_TMR14EN) + +/** + * @brief Resets the TMR14 peripheral. + * + * @api + */ +#define crmResetTMR14() crmResetAPB1(CRM_APB1RST_TMR14RST) +/** @} */ + +/** + * @name USART/UART peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the USART1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableUSART1(lp) crmEnableAPB2(CRM_APB2EN_USART1EN, lp) + +/** + * @brief Disables the USART1 peripheral clock. + * + * @api + */ +#define crmDisableUSART1() crmDisableAPB2(CRM_APB2EN_USART1EN) + +/** + * @brief Resets the USART1 peripheral. + * + * @api + */ +#define crmResetUSART1() crmResetAPB2(CRM_APB2RST_USART1RST) + +/** + * @brief Enables the USART2 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableUSART2(lp) crmEnableAPB1(CRM_APB1EN_USART2EN, lp) + +/** + * @brief Disables the USART2 peripheral clock. + * + * @api + */ +#define crmDisableUSART2() crmDisableAPB1(CRM_APB1EN_USART2EN) + +/** + * @brief Resets the USART2 peripheral. + * + * @api + */ +#define crmResetUSART2() crmResetAPB1(CRM_APB1RST_USART2RST) + +/** + * @brief Enables the USART3 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableUSART3(lp) crmEnableAPB1(CRM_APB1EN_USART3EN, lp) + +/** + * @brief Disables the USART3 peripheral clock. + * + * @api + */ +#define crmDisableUSART3() crmDisableAPB1(CRM_APB1EN_USART3EN) + +/** + * @brief Resets the USART3 peripheral. + * + * @api + */ +#define crmResetUSART3() crmResetAPB1(CRM_APB1RST_USART3RST) +/** @} */ + +/** + * @brief Enables the UART4 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableUART4(lp) crmEnableAPB1(CRM_APB1EN_USART4EN, lp) + +/** + * @brief Disables the UART4 peripheral clock. + * + * @api + */ +#define crmDisableUART4() crmDisableAPB1(CRM_APB1EN_USART4EN) + +/** + * @brief Resets the UART4 peripheral. + * + * @api + */ +#define crmResetUART4() crmResetAPB1(CRM_APB1RST_USART4RST) + +/** + * @brief Enables the UART5 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableUART5(lp) crmEnableAPB1(CRM_APB1EN_USART5EN, lp) + +/** + * @brief Disables the UART5 peripheral clock. + * + * @api + */ +#define crmDisableUART5() crmDisableAPB1(CRM_APB1EN_USART5EN) + +/** + * @brief Resets the UART5 peripheral. + * + * @api + */ +#define crmResetUART5() crmResetAPB1(CRM_APB1RST_USART5RST) + +/** + * @brief Enables the USART6 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableUSART6(lp) crmEnableAPB2(CRM_APB2EN_USART6EN, lp) + +/** + * @brief Disables the USART6 peripheral clock. + * + * @api + */ +#define crmDisableUSART6() crmDisableAPB2(CRM_APB2EN_USART6EN) + +/** + * @brief Resets the USART6 peripheral. + * + * @api + */ +#define crmResetUSART6() crmResetAPB2(CRM_APB2RST_USART6RST) + +/** + * @brief Enables the UART7 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableUART7(lp) crmEnableAPB1(CRM_APB1EN_UART7EN, lp) + +/** + * @brief Disables the UART7 peripheral clock. + * + * @api + */ +#define crmDisableUART7() crmDisableAPB1(CRM_APB1EN_UART7EN) + +/** + * @brief Resets the UART7 peripheral. + * + * @api + */ +#define crmResetUART7() crmResetAPB1(CRM_APB1RST_UART7RST) + +/** + * @brief Enables the UART8 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableUART8(lp) crmEnableAPB1(CRM_APB1EN_UART8EN, lp) + +/** + * @brief Disables the UART8 peripheral clock. + * + * @api + */ +#define crmDisableUART8() crmDisableAPB1(CRM_APB1EN_UART8EN) + +/** + * @brief Resets the UART8 peripheral. + * + * @api + */ +#define crmResetUART8() crmResetAPB1(CRM_APB1RST_UART8RST) +/** @} */ + +/** + * @name ACC peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the ACC peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableACC(lp) crmEnableAPB2(CRM_APB2EN_ACCEN, lp) + +/** + * @brief Disables the ACC peripheral clock. + * + * @api + */ +#define crmDisableACC() crmDisableAPB2(CRM_APB2EN_ACCEN) + +/** + * @brief Resets the ACC peripheral. + * + * @api + */ +#define crmResetACC() crmResetAPB2(CRM_APB2RST_ACCRST) +/** @} */ + +/** + * @name SCFG peripherals specific CRM operations + * @{ + */ +/** + * @brief Enables the SCFG peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define crmEnableSCFG(lp) crmEnableAPB2(CRM_APB2EN_SCFGEN, lp) + +/** + * @brief Disables the SCFG peripheral clock. + * + * @api + */ +#define crmDisableSCFG() crmDisableAPB2(CRM_APB2EN_SCFGEN) + +/** + * @brief Resets the SCFG peripheral. + * + * @api + */ +#define crmResetSCFG() crmResetAPB2(CRM_APB2RST_SCFGRST) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* AT32_CRM_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/at32_dmamux.h b/os/hal/ports/AT32/AT32F405xx/at32_dmamux.h new file mode 100644 index 0000000000..d6d4e4847f --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/at32_dmamux.h @@ -0,0 +1,148 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/at32_dmamux.h + * @brief AT32F405xx DMAMUX handler header. + * + * @addtogroup AT32F405xx_DMAMUX + * @{ + */ + +#ifndef AT32_DMAMUX_H +#define AT32_DMAMUX_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name DMAMUX request sources + * @{ + */ +#define AT32_DMAMUX_MUXREQG1 1 +#define AT32_DMAMUX_MUXREQG2 2 +#define AT32_DMAMUX_MUXREQG3 3 +#define AT32_DMAMUX_MUXREQG4 4 +#define AT32_DMAMUX_ADC1 5 +#define AT32_DMAMUX_SPI1_RX 10 +#define AT32_DMAMUX_SPI1_TX 11 +#define AT32_DMAMUX_SPI2_RX 12 +#define AT32_DMAMUX_SPI2_TX 13 +#define AT32_DMAMUX_SPI3_RX 14 +#define AT32_DMAMUX_SPI3_TX 15 +#define AT32_DMAMUX_I2C1_RX 16 +#define AT32_DMAMUX_I2C1_TX 17 +#define AT32_DMAMUX_I2C2_RX 18 +#define AT32_DMAMUX_I2C2_TX 19 +#define AT32_DMAMUX_I2C3_RX 20 +#define AT32_DMAMUX_I2C3_TX 21 +#define AT32_DMAMUX_USART1_RX 24 +#define AT32_DMAMUX_USART1_TX 25 +#define AT32_DMAMUX_USART2_RX 26 +#define AT32_DMAMUX_USART2_TX 27 +#define AT32_DMAMUX_USART3_RX 28 +#define AT32_DMAMUX_USART3_TX 29 +#define AT32_DMAMUX_USART4_RX 30 +#define AT32_DMAMUX_USART4_TX 31 +#define AT32_DMAMUX_USART5_RX 32 +#define AT32_DMAMUX_USART5_TX 33 +#define AT32_DMAMUX_QSPI1 40 +#define AT32_DMAMUX_TMR1_CH1 42 +#define AT32_DMAMUX_TMR1_CH2 43 +#define AT32_DMAMUX_TMR1_CH3 44 +#define AT32_DMAMUX_TMR1_CH4 45 +#define AT32_DMAMUX_TMR1_OVERFLOW 46 +#define AT32_DMAMUX_TMR1_TRIG 47 +#define AT32_DMAMUX_TMR1_HALL 48 +#define AT32_DMAMUX_TMR2_CH1 56 +#define AT32_DMAMUX_TMR2_CH2 57 +#define AT32_DMAMUX_TMR2_CH3 58 +#define AT32_DMAMUX_TMR2_CH4 59 +#define AT32_DMAMUX_TMR2_OVERFLOW 60 +#define AT32_DMAMUX_TMR3_CH1 61 +#define AT32_DMAMUX_TMR3_CH2 62 +#define AT32_DMAMUX_TMR3_CH3 63 +#define AT32_DMAMUX_TMR3_CH4 64 +#define AT32_DMAMUX_TMR3_OVERFLOW 65 +#define AT32_DMAMUX_TMR3_TRIG 66 +#define AT32_DMAMUX_TMR4_CH1 67 +#define AT32_DMAMUX_TMR4_CH2 68 +#define AT32_DMAMUX_TMR4_CH3 69 +#define AT32_DMAMUX_TMR4_CH4 70 +#define AT32_DMAMUX_TMR4_OVERFLOW 71 +#define AT32_DMAMUX_TMR9_CH1 78 +#define AT32_DMAMUX_TMR9_OVERFLOW 79 +#define AT32_DMAMUX_TMR9_TRIG 80 +#define AT32_DMAMUX_TMR9_HALL 81 +#define AT32_DMAMUX_TMR10_CH1 82 +#define AT32_DMAMUX_TMR10_OVERFLOW 83 +#define AT32_DMAMUX_TMR11_CH1 84 +#define AT32_DMAMUX_TMR11_OVERFLOW 85 +#define AT32_DMAMUX_I2SF5_RX 108 +#define AT32_DMAMUX_I2S_TX 109 +#define AT32_DMAMUX_USART6_RX 114 +#define AT32_DMAMUX_USART6_TX 115 +#define AT32_DMAMUX_UART7_RX 116 +#define AT32_DMAMUX_UART7_TX 117 +#define AT32_DMAMUX_UART8_RX 118 +#define AT32_DMAMUX_UART8_TX 119 +#define AT32_DMAMUX_TMR13_CH1 120 +#define AT32_DMAMUX_TMR13_OVERFLOW 121 +#define AT32_DMAMUX_TMR14_CH1 122 +#define AT32_DMAMUX_TMR14_OVERFLOW 123 +#define AT32_DMAMUX_TMR9_CH2 124 +#define AT32_DMAMUX_TMR2_TRIG 126 +#define AT32_DMAMUX_TMR4_TRIG 127 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +#define AT32_DMAMUX_UART4_RX AT32_DMAMUX_USART4_RX +#define AT32_DMAMUX_UART4_TX AT32_DMAMUX_USART4_TX +#define AT32_DMAMUX_UART5_RX AT32_DMAMUX_USART5_RX +#define AT32_DMAMUX_UART5_TX AT32_DMAMUX_USART5_TX + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* AT32_DMAMUX_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/at32_isr.c b/os/hal/ports/AT32/AT32F405xx/at32_isr.c new file mode 100644 index 0000000000..0678e5685d --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/at32_isr.c @@ -0,0 +1,173 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/at32_isr.c + * @brief AT32F405xx ISR handler code. + * + * @addtogroup AT32F405xx_ISR + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +#define exint_serve_irq(intsts, channel) { \ + \ + if ((intsts) & (1U << (channel))) { \ + _pal_isr_code(channel); \ + } \ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ +#include "at32_exint0.inc" +#include "at32_exint1.inc" +#include "at32_exint2.inc" +#include "at32_exint3.inc" +#include "at32_exint4.inc" +#include "at32_exint5_9.inc" +#include "at32_exint10_15.inc" +#include "at32_exint16.inc" +#include "at32_exint17.inc" +#include "at32_exint18.inc" +#include "at32_exint19.inc" +#include "at32_exint20.inc" +#include "at32_exint21.inc" +#include "at32_exint22.inc" + +#include "at32_tmr1_9_10_11.inc" +#include "at32_tmr2.inc" +#include "at32_tmr3.inc" +#include "at32_tmr4.inc" +#include "at32_tmr6.inc" +#include "at32_tmr7.inc" +#include "at32_tmr13.inc" +#include "at32_tmr14.inc" + +#include "at32_usart1.inc" +#include "at32_usart2.inc" +#include "at32_usart3.inc" +#include "at32_uart4.inc" +#include "at32_uart5.inc" +#include "at32_usart6.inc" +#include "at32_uart7.inc" +#include "at32_uart8.inc" + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Enables IRQ sources. + * + * @notapi + */ +void irqInit(void) { + + exint0_irq_init(); + exint1_irq_init(); + exint2_irq_init(); + exint3_irq_init(); + exint4_irq_init(); + exint5_9_irq_init(); + exint10_15_irq_init(); + exint16_irq_init(); + exint17_irq_init(); + exint18_irq_init(); + exint19_irq_init(); + exint20_irq_init(); + exint21_irq_init(); + exint22_irq_init(); + + tmr1_tmr9_tmr10_tmr11_irq_init(); + tmr2_irq_init(); + tmr3_irq_init(); + tmr4_irq_init(); + tmr6_irq_init(); + tmr7_irq_init(); + tmr13_irq_init(); + tmr14_irq_init(); + + usart1_irq_init(); + usart2_irq_init(); + usart3_irq_init(); + uart4_irq_init(); + uart5_irq_init(); + usart6_irq_init(); + uart7_irq_init(); + uart8_irq_init(); +} + +/** + * @brief Disables IRQ sources. + * + * @notapi + */ +void irqDeinit(void) { + + exint0_irq_deinit(); + exint1_irq_deinit(); + exint2_irq_deinit(); + exint3_irq_deinit(); + exint4_irq_deinit(); + exint5_9_irq_deinit(); + exint10_15_irq_deinit(); + exint16_irq_deinit(); + exint17_irq_deinit(); + exint18_irq_deinit(); + exint19_irq_deinit(); + exint20_irq_deinit(); + exint21_irq_deinit(); + exint22_irq_deinit(); + + tmr1_tmr9_tmr10_tmr11_irq_deinit(); + tmr2_irq_deinit(); + tmr3_irq_deinit(); + tmr4_irq_deinit(); + tmr6_irq_deinit(); + tmr7_irq_deinit(); + tmr13_irq_deinit(); + tmr14_irq_deinit(); + + usart1_irq_deinit(); + usart2_irq_deinit(); + usart3_irq_deinit(); + uart4_irq_deinit(); + uart5_irq_deinit(); + usart6_irq_deinit(); + uart7_irq_deinit(); + uart8_irq_deinit(); +} + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/at32_isr.h b/os/hal/ports/AT32/AT32F405xx/at32_isr.h new file mode 100644 index 0000000000..92a8c614ff --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/at32_isr.h @@ -0,0 +1,285 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/at32_isr.h + * @brief AT32F405xx ISR handler header. + * + * @addtogroup AT32F405xx_ISR + * @{ + */ + +#ifndef AT32_ISR_H +#define AT32_ISR_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name ISRs suppressed in standard drivers + * @{ + */ +#define AT32_TMR1_SUPPRESS_ISR +#define AT32_TMR2_SUPPRESS_ISR +#define AT32_TMR3_SUPPRESS_ISR +#define AT32_TMR4_SUPPRESS_ISR +#define AT32_TMR6_SUPPRESS_ISR +#define AT32_TMR7_SUPPRESS_ISR +#define AT32_TMR9_SUPPRESS_ISR +#define AT32_TMR10_SUPPRESS_ISR +#define AT32_TMR11_SUPPRESS_ISR +#define AT32_TMR13_SUPPRESS_ISR +#define AT32_TMR14_SUPPRESS_ISR + +#define AT32_USART1_SUPPRESS_ISR +#define AT32_USART2_SUPPRESS_ISR +#define AT32_USART3_SUPPRESS_ISR +#define AT32_UART4_SUPPRESS_ISR +#define AT32_UART5_SUPPRESS_ISR +#define AT32_USART6_SUPPRESS_ISR +#define AT32_UART7_SUPPRESS_ISR +#define AT32_UART8_SUPPRESS_ISR +/** @} */ + +/** + * @name ISR names and numbers + * @{ + */ +/* + * ADC units. + */ +#define AT32_ADC_HANDLER Vector88 +#define AT32_ADC_NUMBER 18 + +/* + * CAN units. + */ +#define AT32_CAN1_TX_HANDLER Vector8C +#define AT32_CAN1_RX0_HANDLER Vector90 +#define AT32_CAN1_RX1_HANDLER Vector94 +#define AT32_CAN1_SCE_HANDLER Vector98 + +#define AT32_CAN1_TX_NUMBER 19 +#define AT32_CAN1_RX0_NUMBER 20 +#define AT32_CAN1_RX1_NUMBER 21 +#define AT32_CAN1_SCE_NUMBER 22 + +/* + * DMA units. + */ +#define AT32_DMA1_CH1_HANDLER Vector6C +#define AT32_DMA1_CH2_HANDLER Vector70 +#define AT32_DMA1_CH3_HANDLER Vector74 +#define AT32_DMA1_CH4_HANDLER Vector78 +#define AT32_DMA1_CH5_HANDLER Vector7C +#define AT32_DMA1_CH6_HANDLER Vector80 +#define AT32_DMA1_CH7_HANDLER Vector84 +#define AT32_DMA2_CH1_HANDLER Vector120 +#define AT32_DMA2_CH2_HANDLER Vector124 +#define AT32_DMA2_CH3_HANDLER Vector128 +#define AT32_DMA2_CH4_HANDLER Vector12C +#define AT32_DMA2_CH5_HANDLER Vector130 +#define AT32_DMA2_CH6_HANDLER Vector150 +#define AT32_DMA2_CH7_HANDLER Vector154 +#define AT32_DMAMUX_HANDLER Vector1B8 + +#define AT32_DMA1_CH1_NUMBER 11 +#define AT32_DMA1_CH2_NUMBER 12 +#define AT32_DMA1_CH3_NUMBER 13 +#define AT32_DMA1_CH4_NUMBER 14 +#define AT32_DMA1_CH5_NUMBER 15 +#define AT32_DMA1_CH6_NUMBER 16 +#define AT32_DMA1_CH7_NUMBER 17 +#define AT32_DMA2_CH1_NUMBER 56 +#define AT32_DMA2_CH2_NUMBER 57 +#define AT32_DMA2_CH3_NUMBER 58 +#define AT32_DMA2_CH4_NUMBER 59 +#define AT32_DMA2_CH5_NUMBER 60 +#define AT32_DMA2_CH6_NUMBER 68 +#define AT32_DMA2_CH7_NUMBER 69 +#define AT32_DMAMUX_NUMBER 94 + +/* + * ERTC unit. + */ +#define AT32_ERTC_TAMP_STAMP_HANDLER Vector48 +#define AT32_ERTC_WKUP_HANDLER Vector4C +#define AT32_ERTC_ALARM_HANDLER VectorE4 + +#define AT32_ERTC_TAMP_STAMP_NUMBER 2 +#define AT32_ERTC_WKUP_NUMBER 3 +#define AT32_ERTC_ALARM_NUMBER 41 + +#define AT32_ERTC_ALARM_EXINT 17 +#define AT32_ERTC_TAMP_STAMP_EXINT 21 +#define AT32_ERTC_WKUP_EXINT 22 +#define AT32_ERTC_IRQ_ENABLE() do { \ + nvicEnableVector(AT32_ERTC_TAMP_STAMP_NUMBER, AT32_IRQ_EXINT21_PRIORITY); \ + nvicEnableVector(AT32_ERTC_WKUP_NUMBER, AT32_IRQ_EXINT22_PRIORITY); \ + nvicEnableVector(AT32_ERTC_ALARM_NUMBER, AT32_IRQ_EXINT17_PRIORITY); \ +} while (false) + +/* + * EXINT unit. + */ +#define AT32_EXINT0_HANDLER Vector58 +#define AT32_EXINT1_HANDLER Vector5C +#define AT32_EXINT2_HANDLER Vector60 +#define AT32_EXINT3_HANDLER Vector64 +#define AT32_EXINT4_HANDLER Vector68 +#define AT32_EXINT5_9_HANDLER Vector9C +#define AT32_EXINT10_15_HANDLER VectorE0 +#define AT32_EXINT16_HANDLER Vector44 /* PVM */ +#define AT32_EXINT17_HANDLER VectorE4 /* ERTC ALARM */ +#define AT32_EXINT18_HANDLER VectorE8 /* OTGFS1 WAKEUP */ +#define AT32_EXINT20_HANDLER Vector170 /* OTGHS WAKEUP */ +#define AT32_EXINT21_HANDLER Vector48 /* ERTC TAMP */ +#define AT32_EXINT22_HANDLER Vector4C /* ERTC WAKEUP */ + +#define AT32_EXINT0_NUMBER 6 +#define AT32_EXINT1_NUMBER 7 +#define AT32_EXINT2_NUMBER 8 +#define AT32_EXINT3_NUMBER 9 +#define AT32_EXINT4_NUMBER 10 +#define AT32_EXINT5_9_NUMBER 23 +#define AT32_EXINT10_15_NUMBER 40 +#define AT32_EXINT16_NUMBER 1 +#define AT32_EXINT17_NUMBER 41 +#define AT32_EXINT18_NUMBER 42 +#define AT32_EXINT20_NUMBER 76 +#define AT32_EXINT21_NUMBER 2 +#define AT32_EXINT22_NUMBER 3 + +/* + * I2C units. + */ +#define AT32_I2C1_EVENT_HANDLER VectorBC +#define AT32_I2C1_ERROR_HANDLER VectorC0 +#define AT32_I2C2_EVENT_HANDLER VectorC4 +#define AT32_I2C2_ERROR_HANDLER VectorC8 +#define AT32_I2C3_EVENT_HANDLER Vector160 +#define AT32_I2C3_ERROR_HANDLER Vector164 + +#define AT32_I2C1_EVENT_NUMBER 31 +#define AT32_I2C1_ERROR_NUMBER 32 +#define AT32_I2C2_EVENT_NUMBER 33 +#define AT32_I2C2_ERROR_NUMBER 34 +#define AT32_I2C3_EVENT_NUMBER 72 +#define AT32_I2C3_ERROR_NUMBER 73 + +/* + * USB units. + */ +#define AT32_OTG1_HANDLER Vector14C +#define AT32_OTG2_HANDLER Vector174 +#define AT32_OTG2_EP1OUT_HANDLER Vector168 +#define AT32_OTG2_EP1IN_HANDLER Vector16C + +#define AT32_OTG1_NUMBER 67 +#define AT32_OTG2_NUMBER 77 +#define AT32_OTG2_EP1OUT_NUMBER 74 +#define AT32_OTG2_EP1IN_NUMBER 75 + +/* + * TMR units. + */ +#define AT32_TMR1_BRK_TMR9_HANDLER VectorA0 +#define AT32_TMR1_OVF_TMR10_HANDLER VectorA4 +#define AT32_TMR1_HALL_TMR11_HANDLER VectorA8 +#define AT32_TMR1_CH_HANDLER VectorAC +#define AT32_TMR2_HANDLER VectorB0 +#define AT32_TMR3_HANDLER VectorB4 +#define AT32_TMR4_HANDLER VectorB8 +#define AT32_TMR6_HANDLER Vector118 +#define AT32_TMR7_HANDLER Vector11C +#define AT32_TMR13_HANDLER VectorF0 +#define AT32_TMR14_HANDLER VectorF4 + +#define AT32_TMR1_BRK_TMR9_NUMBER 24 +#define AT32_TMR1_OVF_TMR10_NUMBER 25 +#define AT32_TMR1_HALL_TMR11_NUMBER 26 +#define AT32_TMR1_CH_NUMBER 27 +#define AT32_TMR2_NUMBER 28 +#define AT32_TMR3_NUMBER 29 +#define AT32_TMR4_NUMBER 30 +#define AT32_TMR6_NUMBER 54 +#define AT32_TMR7_NUMBER 55 +#define AT32_TMR13_NUMBER 44 +#define AT32_TMR14_NUMBER 45 + +/* + * USART units. + */ +#define AT32_USART1_HANDLER VectorD4 +#define AT32_USART2_HANDLER VectorD8 +#define AT32_USART3_HANDLER VectorDC +#define AT32_UART4_HANDLER Vector110 +#define AT32_UART5_HANDLER Vector114 +#define AT32_USART6_HANDLER Vector15C +#define AT32_UART7_HANDLER Vector188 +#define AT32_UART8_HANDLER Vector18C + +#define AT32_USART1_NUMBER 37 +#define AT32_USART2_NUMBER 38 +#define AT32_USART3_NUMBER 39 +#define AT32_UART4_NUMBER 52 +#define AT32_UART5_NUMBER 53 +#define AT32_USART6_NUMBER 71 +#define AT32_UART7_NUMBER 82 +#define AT32_UART8_NUMBER 83 + +/* + * ACC units. + */ +#define AT32_ACC_HANDLER Vector1DC +#define AT32_ACC_NUMBER 103 + +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void irqInit(void); + void irqDeinit(void); +#ifdef __cplusplus +} +#endif + +#endif /* AT32_ISR_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/at32_registry.h b/os/hal/ports/AT32/AT32F405xx/at32_registry.h new file mode 100644 index 0000000000..6235b66030 --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/at32_registry.h @@ -0,0 +1,579 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/at32_registry.h + * @brief AT32F405xx capabilities registry. + * + * @addtogroup HAL + * @{ + */ + +#ifndef AT32_REGISTRY_H +#define AT32_REGISTRY_H + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ +#if defined(AT32F402Kx) || defined(AT32F405Kx) || defined(__DOXYGEN__) +/** + * @name AT32F402_5Kx capabilities + * @{ + */ +/* ADC attributes.*/ +#define AT32_HAS_ADC1 TRUE +#define AT32_HAS_ADC2 FALSE +#define AT32_HAS_ADC3 FALSE + +/* CAN attributes.*/ +#define AT32_HAS_CAN1 TRUE +#define AT32_HAS_CAN2 FALSE +#define AT32_CAN_MAX_FILTERS 14 + +/* DAC attributes.*/ +#define AT32_HAS_DAC1_CH1 FALSE +#define AT32_HAS_DAC1_CH2 FALSE + +/* DMA attributes.*/ +#define AT32_ADVANCED_DMA TRUE +#define AT32_DMA_SUPPORTS_DMAMUX TRUE +#define AT32_DMA_SUPPORTS_CSELR FALSE + +#define AT32_DMA1_NUM_CHANNELS 7 +#define AT32_DMA2_NUM_CHANNELS 7 + +/* ETH attributes.*/ +#define AT32_HAS_ETH FALSE + +/* EXINT attributes.*/ +#define AT32_EXINT_NUM_LINES 22 +#define AT32_EXINT_INTEN_MASK 0x00000000U + +/* Flash attributes.*/ +#define AT32_FLASH_NUMBER_OF_BANKS 1 +#if defined(AT32F402xB) || defined(AT32F405xB) +#define AT32_FLASH_SECTOR_SIZE 1024U +#elif defined(AT32F402xC) || defined(AT32F405xC) +#define AT32_FLASH_SECTOR_SIZE 2048U +#endif +#if !defined(AT32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__) +#define AT32_FLASH_SECTORS_PER_BANK 128 /* Maximum, can be redefined.*/ +#endif + +/* GPIO attributes.*/ +#define AT32_HAS_GPIOA TRUE +#define AT32_HAS_GPIOB TRUE +#define AT32_HAS_GPIOC FALSE +#define AT32_HAS_GPIOD FALSE +#define AT32_HAS_GPIOE FALSE +#define AT32_HAS_GPIOF TRUE +#define AT32_HAS_GPIOG FALSE +#define AT32_HAS_GPIOH FALSE +#define AT32_HAS_GPIOI FALSE +#define AT32_HAS_GPIOJ FALSE +#define AT32_HAS_GPIOK FALSE + +#define AT32_GPIO_EN_MASK (CRM_AHBEN1_GPIOAEN | \ + CRM_AHBEN1_GPIOBEN | \ + CRM_AHBEN1_GPIOFEN) + +/* I2C attributes.*/ +#define AT32_HAS_I2C1 TRUE +#define AT32_HAS_I2C2 TRUE +#define AT32_HAS_I2C3 TRUE + +/* RTC attributes.*/ +#define AT32_HAS_ERTC TRUE +#define AT32_ERTC_HAS_SUBSECONDS TRUE +#define AT32_ERTC_IS_CALENDAR TRUE +#define AT32_ERTC_HAS_PERIODIC_WAKEUPS TRUE +#define AT32_ERTC_NUM_ALARMS 2 +#define AT32_ERTC_STORAGE_SIZE 80 + +/* SDIO attributes.*/ +#define AT32_HAS_SDIO FALSE + +/* SPI attributes.*/ +#define AT32_HAS_SPI1 TRUE +#define AT32_SPI1_SUPPORTS_I2S TRUE +#define AT32_SPI1_I2S_FULLDUPLEX FALSE + +#define AT32_HAS_SPI2 FALSE + +#define AT32_HAS_SPI3 TRUE +#define AT32_SPI3_SUPPORTS_I2S TRUE +#define AT32_SPI3_I2S_FULLDUPLEX FALSE + +/* TMR attributes.*/ +#define AT32_TMR_MAX_CHANNELS 4 + +#define AT32_HAS_TMR1 TRUE +#define AT32_TMR1_IS_32BITS FALSE +#define AT32_TMR1_CHANNELS 4 + +#define AT32_HAS_TMR2 TRUE +#define AT32_TMR2_IS_32BITS TRUE +#define AT32_TMR2_CHANNELS 4 + +#define AT32_HAS_TMR3 TRUE +#define AT32_TMR3_IS_32BITS FALSE +#define AT32_TMR3_CHANNELS 4 + +#define AT32_HAS_TMR4 TRUE +#define AT32_TMR4_IS_32BITS FALSE +#define AT32_TMR4_CHANNELS 4 + +#define AT32_HAS_TMR5 FALSE + +#define AT32_HAS_TMR6 TRUE +#define AT32_TMR6_IS_32BITS FALSE +#define AT32_TMR6_CHANNELS 0 + +#define AT32_HAS_TMR7 TRUE +#define AT32_TMR7_IS_32BITS FALSE +#define AT32_TMR7_CHANNELS 0 + +#define AT32_HAS_TMR8 FALSE + +#define AT32_HAS_TMR9 TRUE +#define AT32_TMR9_IS_32BITS FALSE +#define AT32_TMR9_CHANNELS 2 + +#define AT32_HAS_TMR10 TRUE +#define AT32_TMR10_IS_32BITS FALSE +#define AT32_TMR10_CHANNELS 1 + +#define AT32_HAS_TMR11 TRUE +#define AT32_TMR11_IS_32BITS FALSE +#define AT32_TMR11_CHANNELS 1 + +#define AT32_HAS_TMR12 FALSE + +#define AT32_HAS_TMR13 TRUE +#define AT32_TMR13_IS_32BITS FALSE +#define AT32_TMR13_CHANNELS 1 + +#define AT32_HAS_TMR14 TRUE +#define AT32_TMR14_IS_32BITS FALSE +#define AT32_TMR14_CHANNELS 1 + +/* USART attributes.*/ +#define AT32_HAS_USART1 TRUE +#define AT32_HAS_USART2 TRUE +#define AT32_HAS_USART3 TRUE +#define AT32_HAS_UART4 TRUE +#define AT32_HAS_UART5 TRUE +#define AT32_HAS_USART6 TRUE +#define AT32_HAS_UART7 TRUE +#define AT32_HAS_UART8 FALSE + +/* USB attributes.*/ +#define AT32_OTG_STEPPING 2 +#define AT32_HAS_OTG1 TRUE +#define AT32_OTG1_ENDPOINTS 8 + +#if defined(AT32F405xx) +#define AT32_HAS_OTG2 TRUE +#define AT32_OTG2_ENDPOINTS 8 +#define AT32_OTG2_SUPPORTS_HS TRUE +#else +#define AT32_HAS_OTG2 FALSE +#endif + +#define AT32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define AT32_HAS_IWDG TRUE +#define AT32_IWDG_IS_WINDOWED TRUE + +/* FSMC attributes.*/ +#define AT32_HAS_FSMC FALSE + +/* CRC attributes.*/ +#define AT32_HAS_CRC TRUE +#define AT32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(AT32F402Kx) || defined(AT32F405Kx) */ + +#if defined(AT32F402Cx) || defined(AT32F405Cx) +/** + * @name AT32F402_5Cx capabilities + * @{ + */ +/* ADC attributes.*/ +#define AT32_HAS_ADC1 TRUE +#define AT32_HAS_ADC2 FALSE +#define AT32_HAS_ADC3 FALSE + +/* CAN attributes.*/ +#define AT32_HAS_CAN1 TRUE +#define AT32_HAS_CAN2 FALSE +#define AT32_CAN_MAX_FILTERS 14 + +/* DAC attributes.*/ +#define AT32_HAS_DAC1_CH1 FALSE +#define AT32_HAS_DAC1_CH2 FALSE + +/* DMA attributes.*/ +#define AT32_ADVANCED_DMA TRUE +#define AT32_DMA_SUPPORTS_DMAMUX TRUE +#define AT32_DMA_SUPPORTS_CSELR FALSE + +#define AT32_DMA1_NUM_CHANNELS 7 +#define AT32_DMA2_NUM_CHANNELS 7 + +/* ETH attributes.*/ +#define AT32_HAS_ETH FALSE + +/* EXINT attributes.*/ +#define AT32_EXINT_NUM_LINES 22 +#define AT32_EXINT_INTEN_MASK 0x00000000U + +/* Flash attributes.*/ +#define AT32_FLASH_NUMBER_OF_BANKS 1 +#if defined(AT32F402xB) || defined(AT32F405xB) +#define AT32_FLASH_SECTOR_SIZE 1024U +#elif defined(AT32F402xC) || defined(AT32F405xC) +#define AT32_FLASH_SECTOR_SIZE 2048U +#endif +#if !defined(AT32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__) +#define AT32_FLASH_SECTORS_PER_BANK 128 /* Maximum, can be redefined.*/ +#endif + +/* GPIO attributes.*/ +#define AT32_HAS_GPIOA TRUE +#define AT32_HAS_GPIOB TRUE +#define AT32_HAS_GPIOC TRUE +#define AT32_HAS_GPIOD FALSE +#define AT32_HAS_GPIOE FALSE +#define AT32_HAS_GPIOF TRUE +#define AT32_HAS_GPIOG FALSE +#define AT32_HAS_GPIOH FALSE +#define AT32_HAS_GPIOI FALSE +#define AT32_HAS_GPIOJ FALSE +#define AT32_HAS_GPIOK FALSE + +#define AT32_GPIO_EN_MASK (CRM_AHBEN1_GPIOAEN | \ + CRM_AHBEN1_GPIOBEN | \ + CRM_AHBEN1_GPIOCEN | \ + CRM_AHBEN1_GPIOFEN) + +/* I2C attributes.*/ +#define AT32_HAS_I2C1 TRUE +#define AT32_HAS_I2C2 TRUE +#define AT32_HAS_I2C3 TRUE + +/* RTC attributes.*/ +#define AT32_HAS_ERTC TRUE +#define AT32_ERTC_HAS_SUBSECONDS TRUE +#define AT32_ERTC_IS_CALENDAR TRUE +#define AT32_ERTC_HAS_PERIODIC_WAKEUPS TRUE +#define AT32_ERTC_NUM_ALARMS 2 +#define AT32_ERTC_STORAGE_SIZE 80 + +/* SDIO attributes.*/ +#define AT32_HAS_SDIO FALSE + +/* SPI attributes.*/ +#define AT32_HAS_SPI1 TRUE +#define AT32_SPI1_SUPPORTS_I2S TRUE +#define AT32_SPI1_I2S_FULLDUPLEX FALSE + +#define AT32_HAS_SPI2 TRUE +#define AT32_SPI2_SUPPORTS_I2S TRUE +#define AT32_SPI2_I2S_FULLDUPLEX FALSE + +#define AT32_HAS_SPI3 TRUE +#define AT32_SPI3_SUPPORTS_I2S TRUE +#define AT32_SPI3_I2S_FULLDUPLEX FALSE + +/* TMR attributes.*/ +#define AT32_TMR_MAX_CHANNELS 4 + +#define AT32_HAS_TMR1 TRUE +#define AT32_TMR1_IS_32BITS FALSE +#define AT32_TMR1_CHANNELS 4 + +#define AT32_HAS_TMR2 TRUE +#define AT32_TMR2_IS_32BITS TRUE +#define AT32_TMR2_CHANNELS 4 + +#define AT32_HAS_TMR3 TRUE +#define AT32_TMR3_IS_32BITS FALSE +#define AT32_TMR3_CHANNELS 4 + +#define AT32_HAS_TMR4 TRUE +#define AT32_TMR4_IS_32BITS FALSE +#define AT32_TMR4_CHANNELS 4 + +#define AT32_HAS_TMR5 FALSE + +#define AT32_HAS_TMR6 TRUE +#define AT32_TMR6_IS_32BITS FALSE +#define AT32_TMR6_CHANNELS 0 + +#define AT32_HAS_TMR7 TRUE +#define AT32_TMR7_IS_32BITS FALSE +#define AT32_TMR7_CHANNELS 0 + +#define AT32_HAS_TMR8 FALSE + +#define AT32_HAS_TMR9 TRUE +#define AT32_TMR9_IS_32BITS FALSE +#define AT32_TMR9_CHANNELS 2 + +#define AT32_HAS_TMR10 TRUE +#define AT32_TMR10_IS_32BITS FALSE +#define AT32_TMR10_CHANNELS 1 + +#define AT32_HAS_TMR11 TRUE +#define AT32_TMR11_IS_32BITS FALSE +#define AT32_TMR11_CHANNELS 1 + +#define AT32_HAS_TMR12 FALSE + +#define AT32_HAS_TMR13 TRUE +#define AT32_TMR13_IS_32BITS FALSE +#define AT32_TMR13_CHANNELS 1 + +#define AT32_HAS_TMR14 TRUE +#define AT32_TMR14_IS_32BITS FALSE +#define AT32_TMR14_CHANNELS 1 + +/* USART attributes.*/ +#define AT32_HAS_USART1 TRUE +#define AT32_HAS_USART2 TRUE +#define AT32_HAS_USART3 TRUE +#define AT32_HAS_UART4 TRUE +#define AT32_HAS_UART5 TRUE +#define AT32_HAS_USART6 TRUE +#define AT32_HAS_UART7 TRUE +#define AT32_HAS_UART8 FALSE + +/* USB attributes.*/ +#define AT32_OTG_STEPPING 2 +#define AT32_HAS_OTG1 TRUE +#define AT32_OTG1_ENDPOINTS 8 + +#if defined(AT32F405xx) +#define AT32_HAS_OTG2 TRUE +#define AT32_OTG2_ENDPOINTS 8 +#else +#define AT32_HAS_OTG2 FALSE +#endif + +#define AT32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define AT32_HAS_IWDG TRUE +#define AT32_IWDG_IS_WINDOWED TRUE + +/* FSMC attributes.*/ +#define AT32_HAS_FSMC FALSE + +/* CRC attributes.*/ +#define AT32_HAS_CRC TRUE +#define AT32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(AT32F402Cx) || defined(AT32F405Cx) */ + +#if defined(AT32F402Rx) || defined(AT32F405Rx) +/** + * @name AT32F402_405Rx capabilities + * @{ + */ +/* ADC attributes.*/ +#define AT32_HAS_ADC1 TRUE +#define AT32_HAS_ADC2 FALSE +#define AT32_HAS_ADC3 FALSE + +/* CAN attributes.*/ +#define AT32_HAS_CAN1 TRUE +#define AT32_HAS_CAN2 FALSE +#define AT32_CAN_MAX_FILTERS 14 + +/* DAC attributes.*/ +#define AT32_HAS_DAC1_CH1 FALSE +#define AT32_HAS_DAC1_CH2 FALSE + +/* DMA attributes.*/ +#define AT32_ADVANCED_DMA TRUE +#define AT32_DMA_SUPPORTS_DMAMUX TRUE +#define AT32_DMA_SUPPORTS_CSELR FALSE + +#define AT32_DMA1_NUM_CHANNELS 7 +#define AT32_DMA2_NUM_CHANNELS 7 + +/* ETH attributes.*/ +#define AT32_HAS_ETH FALSE + +/* EXINT attributes.*/ +#define AT32_EXINT_NUM_LINES 22 +#define AT32_EXINT_INTEN_MASK 0x00000000U + +/* Flash attributes.*/ +#define AT32_FLASH_NUMBER_OF_BANKS 1 +#if defined(AT32F402xB) || defined(AT32F405xB) +#define AT32_FLASH_SECTOR_SIZE 1024U +#elif defined(AT32F402xC) || defined(AT32F405xC) +#define AT32_FLASH_SECTOR_SIZE 2048U +#endif +#if !defined(AT32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__) +#define AT32_FLASH_SECTORS_PER_BANK 128 /* Maximum, can be redefined.*/ +#endif + +/* GPIO attributes.*/ +#define AT32_HAS_GPIOA TRUE +#define AT32_HAS_GPIOB TRUE +#define AT32_HAS_GPIOC TRUE +#define AT32_HAS_GPIOD TRUE +#define AT32_HAS_GPIOE FALSE +#define AT32_HAS_GPIOF TRUE +#define AT32_HAS_GPIOG FALSE +#define AT32_HAS_GPIOH FALSE +#define AT32_HAS_GPIOI FALSE +#define AT32_HAS_GPIOJ FALSE +#define AT32_HAS_GPIOK FALSE + +#define AT32_GPIO_EN_MASK (CRM_AHBEN1_GPIOAEN | \ + CRM_AHBEN1_GPIOBEN | \ + CRM_AHBEN1_GPIOCEN | \ + CRM_AHBEN1_GPIODEN | \ + CRM_AHBEN1_GPIOFEN) + +/* I2C attributes.*/ +#define AT32_HAS_I2C1 TRUE +#define AT32_HAS_I2C2 TRUE +#define AT32_HAS_I2C3 TRUE + +/* RTC attributes.*/ +#define AT32_HAS_ERTC TRUE +#define AT32_ERTC_HAS_SUBSECONDS TRUE +#define AT32_ERTC_IS_CALENDAR TRUE +#define AT32_ERTC_HAS_PERIODIC_WAKEUPS TRUE +#define AT32_ERTC_NUM_ALARMS 2 +#define AT32_ERTC_STORAGE_SIZE 80 + +/* SDIO attributes.*/ +#define AT32_HAS_SDIO FALSE + +/* SPI attributes.*/ +#define AT32_HAS_SPI1 TRUE +#define AT32_SPI1_SUPPORTS_I2S TRUE +#define AT32_SPI1_I2S_FULLDUPLEX FALSE + +#define AT32_HAS_SPI2 TRUE +#define AT32_SPI2_SUPPORTS_I2S TRUE +#define AT32_SPI2_I2S_FULLDUPLEX FALSE + +#define AT32_HAS_SPI3 TRUE +#define AT32_SPI3_SUPPORTS_I2S TRUE +#define AT32_SPI3_I2S_FULLDUPLEX FALSE + +/* TMR attributes.*/ +#define AT32_TMR_MAX_CHANNELS 4 + +#define AT32_HAS_TMR1 TRUE +#define AT32_TMR1_IS_32BITS FALSE +#define AT32_TMR1_CHANNELS 4 + +#define AT32_HAS_TMR2 TRUE +#define AT32_TMR2_IS_32BITS TRUE +#define AT32_TMR2_CHANNELS 4 + +#define AT32_HAS_TMR3 TRUE +#define AT32_TMR3_IS_32BITS FALSE +#define AT32_TMR3_CHANNELS 4 + +#define AT32_HAS_TMR4 TRUE +#define AT32_TMR4_IS_32BITS FALSE +#define AT32_TMR4_CHANNELS 4 + +#define AT32_HAS_TMR5 FALSE + +#define AT32_HAS_TMR6 TRUE +#define AT32_TMR6_IS_32BITS FALSE +#define AT32_TMR6_CHANNELS 0 + +#define AT32_HAS_TMR7 TRUE +#define AT32_TMR7_IS_32BITS FALSE +#define AT32_TMR7_CHANNELS 0 + +#define AT32_HAS_TMR8 FALSE + +#define AT32_HAS_TMR9 TRUE +#define AT32_TMR9_IS_32BITS FALSE +#define AT32_TMR9_CHANNELS 2 + +#define AT32_HAS_TMR10 TRUE +#define AT32_TMR10_IS_32BITS FALSE +#define AT32_TMR10_CHANNELS 1 + +#define AT32_HAS_TMR11 TRUE +#define AT32_TMR11_IS_32BITS FALSE +#define AT32_TMR11_CHANNELS 1 + +#define AT32_HAS_TMR12 FALSE + +#define AT32_HAS_TMR13 TRUE +#define AT32_TMR13_IS_32BITS FALSE +#define AT32_TMR13_CHANNELS 1 + +#define AT32_HAS_TMR14 TRUE +#define AT32_TMR14_IS_32BITS FALSE +#define AT32_TMR14_CHANNELS 1 + +/* USART attributes.*/ +#define AT32_HAS_USART1 TRUE +#define AT32_HAS_USART2 TRUE +#define AT32_HAS_USART3 TRUE +#define AT32_HAS_UART4 TRUE +#define AT32_HAS_UART5 TRUE +#define AT32_HAS_USART6 TRUE +#define AT32_HAS_UART7 TRUE +#define AT32_HAS_UART8 TRUE + +/* USB attributes.*/ +#define AT32_OTG_STEPPING 2 +#define AT32_HAS_OTG1 TRUE +#define AT32_OTG1_ENDPOINTS 8 + +#if defined(AT32F405xx) +#define AT32_HAS_OTG2 TRUE +#define AT32_OTG2_ENDPOINTS 8 +#else +#define AT32_HAS_OTG2 FALSE +#endif + +#define AT32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define AT32_HAS_IWDG TRUE +#define AT32_IWDG_IS_WINDOWED TRUE + +/* FSMC attributes.*/ +#define AT32_HAS_FSMC FALSE + +/* CRC attributes.*/ +#define AT32_HAS_CRC TRUE +#define AT32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(AT32F402Rx) || defined(AT32F405Rx) */ + +#endif /* AT32_REGISTRY_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/hal_efl_lld.c b/os/hal/ports/AT32/AT32F405xx/hal_efl_lld.c new file mode 100644 index 0000000000..8020eb3707 --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/hal_efl_lld.c @@ -0,0 +1,486 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/hal_efl_lld.c + * @brief AT32F405xx Embedded Flash subsystem low level driver source. + * + * @addtogroup HAL_EFL + * @{ + */ + +#include + +#include "hal.h" + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define AT32_FLASH_LINE_SIZE 2U +#define AT32_FLASH_LINE_MASK (AT32_FLASH_LINE_SIZE - 1U) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief EFL1 driver identifier. + */ +EFlashDriver EFLD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +static const flash_descriptor_t efl_lld_descriptor = { + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = AT32_FLASH_LINE_SIZE, + .sectors_count = AT32_FLASH_NUMBER_OF_BANKS * + AT32_FLASH_SECTORS_PER_BANK, + .sectors = NULL, + .sectors_size = AT32_FLASH_SECTOR_SIZE, + .address = (uint8_t *)FLASH_BASE, + .size = AT32_FLASH_NUMBER_OF_BANKS * + AT32_FLASH_SECTORS_PER_BANK * + AT32_FLASH_SECTOR_SIZE +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void at32_flash_lock(EFlashDriver *eflp) { + + eflp->flash->CTRL |= FLASH_CTRL_OPLK; +} + +static inline void at32_flash_unlock(EFlashDriver *eflp) { + + eflp->flash->UNLOCK = FLASH_UNLOCK_KEY1; + eflp->flash->UNLOCK = FLASH_UNLOCK_KEY2; +} + +static inline void at32_flash_enable_pgm(EFlashDriver *eflp) { + + eflp->flash->CTRL |= FLASH_CTRL_FPRGM; +} + +static inline void at32_flash_disable_pgm(EFlashDriver *eflp) { + + eflp->flash->CTRL &= ~FLASH_CTRL_FPRGM; +} + +static inline void at32_flash_clear_status(EFlashDriver *eflp) { + + eflp->flash->STS = FLASH_STS_PRGMERR | FLASH_STS_EPPERR; +} + +static inline uint32_t at32_flash_is_busy(EFlashDriver *eflp) { + + return (eflp->flash->STS & FLASH_STS_OBF); +} + +static inline void at32_flash_wait_busy(EFlashDriver *eflp) { + + /* Wait for busy bit clear.*/ + while (at32_flash_is_busy(eflp) != 0U) { + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level Embedded Flash driver initialization. + * + * @notapi + */ +void efl_lld_init(void) { + + /* Driver initialization.*/ + eflObjectInit(&EFLD1); + EFLD1.flash = FLASH; +} + +/** + * @brief Configures and activates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_start(EFlashDriver *eflp) { + + at32_flash_unlock(eflp); + eflp->flash->CTRL = 0x00000000U; +} + +/** + * @brief Deactivates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_stop(EFlashDriver *eflp) { + + at32_flash_lock(eflp); +} + +/** + * @brief Gets the flash descriptor structure. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return A flash device descriptor. + * + * @notapi + */ +const flash_descriptor_t *efl_lld_get_descriptor(void *instance) { + + (void)instance; + + return &efl_lld_descriptor; +} + +/** + * @brief Read operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset flash offset + * @param[in] n number of bytes to be read + * @param[out] rp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_READ if the read operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No reading while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_READY state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Clearing error status bits.*/ + at32_flash_clear_status(devp); + + /* Actual read implementation.*/ + memcpy((void *)rp, (const void *)(efl_lld_descriptor.address + offset), n); + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Program operation. + * @note It is only possible to write erased pages once except + * when writing all zeroes. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset flash offset + * @param[in] n number of bytes to be programmed + * @param[in] pp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_PROGRAM if the program operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size); + + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No programming while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_PGM; + + /* Clearing error status bits.*/ + at32_flash_clear_status(devp); + + /* Enabling PGM mode in the controller.*/ + at32_flash_enable_pgm(devp); + + /* Actual program implementation.*/ + while (n > 0U) { + volatile uint16_t *address; + + union { + uint16_t hw[AT32_FLASH_LINE_SIZE / sizeof (uint16_t)]; + uint8_t b[AT32_FLASH_LINE_SIZE / sizeof (uint8_t)]; + } line; + + /* Unwritten bytes are initialized to all ones.*/ + line.hw[0] = 0xFFFFU; + + /* Programming address aligned to flash lines.*/ + address = (volatile uint16_t *)(efl_lld_descriptor.address + + (offset & ~AT32_FLASH_LINE_MASK)); + + /* Copying data inside the prepared line.*/ + do { + line.b[offset & AT32_FLASH_LINE_MASK] = *pp; + offset++; + n--; + pp++; + } + while ((n > 0U) & ((offset & AT32_FLASH_LINE_MASK) != 0U)); + /* Programming line.*/ + address[0] = line.hw[0]; + at32_flash_wait_busy(devp); + + uint32_t sts = devp->flash->STS; + + /* Clearing error status bits.*/ + at32_flash_clear_status(devp); + + /* Decoding relevant errors.*/ + if ((sts & FLASH_STS_EPPERR) != 0U) { + err = FLASH_ERROR_HW_FAILURE; + break; + } + else if ((sts & FLASH_STS_PRGMERR) != 0U) { + err = FLASH_ERROR_PROGRAM; + break; + } + else if ((sts & FLASH_STS_ODF) == 0U) { + err = FLASH_ERROR_PROGRAM; + break; + } + + /* Check for flash error.*/ + if (address[0] != line.hw[0]) { + err = FLASH_ERROR_PROGRAM; + break; + } + } + + /* Disabling PGM mode in the controller.*/ + at32_flash_disable_pgm(devp); + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Starts a whole-device erase operation. + * @note This function does nothing, the flash memory is where the program + * is running on. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_all(void *instance) { + (void) instance; + + return FLASH_ERROR_UNIMPLEMENTED; +} + +/** + * @brief Starts an sector erase operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be erased + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < efl_lld_descriptor.sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No erasing while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_ERASE; + + /* Clearing error status bits.*/ + at32_flash_clear_status(devp); + + /* Enable page erase.*/ + devp->flash->CTRL |= FLASH_CTRL_SECERS; + + /* Set the page.*/ + devp->flash->ADDR = (uint32_t)(efl_lld_descriptor.address + + flashGetSectorOffset(getBaseFlash(devp), sector)); + + /* Start the erase.*/ + devp->flash->CTRL |= FLASH_CTRL_ERSTR; + + return FLASH_NO_ERROR; +} + +/** + * @brief Queries the driver for erase operation progress. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[out] wait_time recommended time, in milliseconds, that + * should be spent before calling this + * function again, can be @p NULL + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_ERASE if the erase operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @api + */ +flash_error_t efl_lld_query_erase(void *instance, uint32_t *wait_time) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err; + + /* If there is an erase in progress then the device must be checked.*/ + if (devp->state == FLASH_ERASE) { + + /* Checking for operation in progress.*/ + if (at32_flash_is_busy(devp) == 0U) { + + /* Disabling the various erase control bits.*/ + devp->flash->CTRL &= ~(FLASH_CTRL_USDERS | FLASH_CTRL_USDPRGM | + FLASH_CTRL_BANKERS | FLASH_CTRL_SECERS); + + /* Back to ready state.*/ + devp->state = FLASH_READY; + + err = FLASH_NO_ERROR; + } + else { + /* Recommended time before polling again, this is a simplified + implementation.*/ + if (wait_time != NULL) { + *wait_time = (uint32_t)AT32_FLASH_WAIT_TIME_MS; + } + + err = FLASH_BUSY_ERASING; + } + } + else { + err = FLASH_NO_ERROR; + } + + return err; +} + +/** + * @brief Returns the erase state of a sector. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be verified + * @return An error code. + * @retval FLASH_NO_ERROR if the sector is erased. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_VERIFY if the verify operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + uint32_t *address; + flash_error_t err = FLASH_NO_ERROR; + unsigned i; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < efl_lld_descriptor.sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No verifying while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* Address of the sector.*/ + address = (uint32_t *)(efl_lld_descriptor.address + + flashGetSectorOffset(getBaseFlash(devp), sector)); + + /* FLASH_READY state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Scanning the sector space.*/ + for (i = 0U; i < AT32_FLASH_SECTOR_SIZE / sizeof(uint32_t); i++) { + if (*address != 0xFFFFFFFFU) { + err = FLASH_ERROR_VERIFY; + break; + } + address++; + } + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +#endif /* HAL_USE_EFL == TRUE */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/hal_efl_lld.h b/os/hal/ports/AT32/AT32F405xx/hal_efl_lld.h new file mode 100644 index 0000000000..40cd178c6e --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/hal_efl_lld.h @@ -0,0 +1,121 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/hal_efl_lld.h + * @brief AT32F405xx Embedded Flash subsystem low level driver header. + * + * @addtogroup HAL_EFL + * @{ + */ + +#ifndef HAL_EFL_LLD_H +#define HAL_EFL_LLD_H + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name AT32F402_5xx configuration options + * @{ + */ +/** + * @brief Suggested wait time during erase operations polling. + */ +#if !defined(AT32_FLASH_WAIT_TIME_MS) || defined(__DOXYGEN__) +#define AT32_FLASH_WAIT_TIME_MS 10 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !defined(AT32_FLASH_SECTOR_SIZE) +#error "AT32_FLASH_SECTOR_SIZE not defined in registry" +#endif + +#if !defined(AT32_FLASH_NUMBER_OF_BANKS) +#error "AT32_FLASH_NUMBER_OF_BANKS not defined in registry" +#endif + +#if !defined(AT32_FLASH_SECTORS_PER_BANK) +#error "AT32_FLASH_SECTORS_PER_BANK not defined in registry" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Low level fields of the embedded flash driver structure. + */ +#define efl_lld_driver_fields \ + /* Flash registers.*/ \ + FLASH_TypeDef *flash + +/** + * @brief Low level fields of the embedded flash configuration structure. + */ +#define efl_lld_config_fields \ + /* Dummy configuration, it is not needed.*/ \ + uint32_t dummy + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern EFlashDriver EFLD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void efl_lld_init(void); + void efl_lld_start(EFlashDriver *eflp); + void efl_lld_stop(EFlashDriver *eflp); + const flash_descriptor_t *efl_lld_get_descriptor(void *instance); + flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); + flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp); + flash_error_t efl_lld_start_erase_all(void *instance); + flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector); + flash_error_t efl_lld_query_erase(void *instance, uint32_t *wait_time); + flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EFL == TRUE */ + +#endif /* HAL_EFL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/hal_lld.c b/os/hal/ports/AT32/AT32F405xx/hal_lld.c new file mode 100644 index 0000000000..5fae394718 --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/hal_lld.c @@ -0,0 +1,320 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/hal_lld.c + * @brief AT32F405xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_at32f405xx.h. + */ +uint32_t SystemCoreClock = AT32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWC->CTRL |= PWC_CTRL_BPWEN; + + /* Reset BKP domain if different clock source selected.*/ + if ((CRM->BPDC & AT32_ERTCSEL_MASK) != AT32_ERTCSEL) { + /* Backup domain reset.*/ + CRM->BPDC = CRM_BPDC_BPDRST; + CRM->BPDC = 0; + } + + /* If enabled then the LEXT is started.*/ +#if AT32_LEXT_ENABLED +#if defined(AT32_LEXT_BYPASS) + /* LEXT Bypass.*/ + CRM->BPDC |= CRM_BPDC_LEXTEN | CRM_BPDC_LEXTBYPS; +#else + /* No LEXT Bypass.*/ + CRM->BPDC |= CRM_BPDC_LEXTEN; +#endif + while ((CRM->BPDC & CRM_BPDC_LEXTSTBL) == 0); /* Waits until LEXT is stable. */ +#endif /* AT32_LEXT_ENABLED */ + +#if AT32_ERTCSEL != AT32_ERTCSEL_NOCLOCK + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((CRM->BPDC & CRM_BPDC_ERTCEN) == 0) { + /* Selects clock source.*/ + CRM->BPDC |= AT32_ERTCSEL; + + /* ERTC clock enabled.*/ + CRM->BPDC |= CRM_BPDC_ERTCEN; + } +#endif /* AT32_ERTCSEL != AT32_ERTCSEL_NOCLOCK */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. AHB3 is not reseted because it could have + been initialized in the board initialization file (board.c). + Note, GPIOs are not reset because initialized before this point in + board files.*/ + crmResetAHB1(~AT32_GPIO_EN_MASK); + crmResetAHB2(~0); + crmResetAPB1(~CRM_APB1RST_PWCRST); + crmResetAPB2(~0); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(AT32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if AT32_PVM_ENABLE + PWC->CTRL |= PWC_CTRL_PVMEN | (AT32_PVM & AT32_PVMSEL_MASK); +#endif /* AT32_PVM_ENABLE */ +} + +/* + * hick divider selection for all sub-families. + */ +static void at32_hick_divider_select(uint32_t div) +{ + volatile uint32_t misc1 = CRM->MISC1; + volatile uint32_t misc2 = CRM->MISC2; + + CRM->MISC2 &= ~AT32_HICK_TO_SCLK_DIV_MASK; + CRM->MISC2 |= AT32_HICK_TO_SCLK_DIV_DIV16; + /* delay */ + { + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + } + + CRM->MISC1 = (AT32_HICK_TO_SCLK_HICKOUT | div); + CRM->MISC1 &= ~AT32_HICK_TO_SCLK_MASK; + CRM->MISC1 |= (misc1 & AT32_HICK_TO_SCLK_MASK); + + CRM->MISC2 &= ~AT32_HICK_TO_SCLK_DIV_MASK; + CRM->MISC2 |= (misc2 & AT32_HICK_TO_SCLK_DIV_MASK); +} + +/* + * hick as system clock frequency selection for all sub-families. + */ +static void at32_hick_frequency_select(uint32_t value) +{ + volatile uint32_t misc1 = CRM->MISC1; + volatile uint32_t misc2 = CRM->MISC2; + + CRM->MISC2 &= ~AT32_HICK_TO_SCLK_DIV_MASK; + CRM->MISC2 |= AT32_HICK_TO_SCLK_DIV_DIV16; + /* delay */ + { + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); + } + + CRM->MISC1 = (AT32_HICK_TO_SCLK_HICKOUT | (misc1 & AT32_HICKDIV_MASK)); + CRM->MISC1 &= ~AT32_HICK_TO_SCLK_MASK; + CRM->MISC1 |= value; + + CRM->MISC2 &= ~AT32_HICK_TO_SCLK_DIV_MASK; + CRM->MISC2 |= (misc2 & AT32_HICK_TO_SCLK_DIV_MASK); +} + +/* + * Clocks deinitialization for all sub-families. + */ +void at32_clock_reset(void) +{ + /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv, clkout bits */ + CRM->CFG = (0x40000000U); + + /* reset hexten, hextbyps, cfden and pllen bits */ + CRM->CTRL &= ~(0x010D0000U); + + /* reset pllms pllns pllfr pllrcs bits */ + CRM->PLLCFG = 0x000007C1U; + + /* reset clkout_sel, clkoutdiv, pllclk_to_adc, hick_to_usb */ + CRM->MISC1 &= 0x00005000U; + CRM->MISC1 |= 0x000F0000U; + + /* disable all interrupts enable and clear pending bits */ + CRM->CLKINT = 0x009F0000; +} + +/* + * Clocks initialization for all sub-families. + */ +void at32_clock_init(void) { +#if !AT32_NO_INIT + /* HICK setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + + /* clock reset. */ + at32_clock_reset(); + + CRM->MISC2 |= CRM_MISC2_AUTO_STEP_EN; + + CRM->CTRL |= CRM_CTRL_HICKEN; /* Make sure HICK is ON. */ + while((CRM->CTRL & CRM_CTRL_HICKSTBL) == 0); /* Wait until HICK is stable. */ + + CRM->CTRL &= CRM_CTRL_HICKTRIM | CRM_CTRL_HICKEN; /* CTRL Reset value. */ + + at32_hick_divider_select(AT32_HICKDIV); + at32_hick_frequency_select(AT32_HICK_TO_SCLK); + CRM->MISC2 |= AT32_HICK_TO_SCLK_DIV; + CRM->CFG |= CRM_CFG_SCLK_HICK; /* CFG reset value. */ + while ((CRM->CFG & CRM_CFG_SCLKSTS) != CRM_CFG_SCLKSTS_HICK); /* Waits until HICK is selected.*/ + + CRM->MISC2 &= ~CRM_MISC2_AUTO_STEP_EN; + + /* Flash setup and final clock selection.*/ + FLASH->PSR = AT32_FLASHBITS; + CRM->APB1EN |= CRM_APB1EN_PWCEN; + + /* PWR initialization.*/ + PWC->LDOOV = AT32_LDOOVSEL; + +#if AT32_HEXT_ENABLED + /* HEXT activation.*/ +#if defined(AT32_HEXT_BYPASS) + /* HEXT Bypass.*/ + CRM->CTRL |= CRM_CTRL_HEXTEN | CRM_CTRL_HEXTBYPS; +#else + /* No HEXT Bypass.*/ + CRM->CTRL |= CRM_CTRL_HEXTEN; +#endif + while (!(CRM->CTRL & CRM_CTRL_HEXTSTBL)); /* Waits until HEXT is stable. */ +#endif + +#if AT32_LICK_ENABLED + /* LICK activation.*/ + CRM->CTRLSTS |= CRM_CTRLSTS_LICKEN; + while ((CRM->CTRLSTS & CRM_CTRLSTS_LICKSTBL) == 0); /* Waits until LICK is stable. */ +#endif + +#if AT32_ACTIVATE_PLL + /* PLL activation.*/ +#if AT32_PLLRCS == AT32_PLLRCS_HICK + at32_hick_divider_select(AT32_HICKDIV_DIV1); +#endif + CRM->PLLCFG = AT32_PLL_MS | AT32_PLL_NS | AT32_PLL_FP | AT32_PLL_FU | + AT32_PLLRCS; + CRM->CTRL |= CRM_CTRL_PLLEN; + while (!(CRM->CTRL & CRM_CTRL_PLLSTBL)); /* Waits until PLL is stable. */ +#if AT32_PLLU_ENABLED + CRM->PLLCFG |= CRM_PLLCFG_PLLUEN; + while (!(CRM->CTRL & CRM_CTRL_PLLUSTBL)); /* Waits until PLLU is stable. */ +#endif +#endif + + /* Clock settings.*/ + CRM->CFG |= (AT32_CLKOUT_SEL & AT32_CLKOUT_SEL_CFG_MASK) | AT32_APB2DIV | + AT32_APB1DIV | AT32_AHBDIV | AT32_ETRCDIV | AT32_I2SF5CLKSEL | + AT32_CLKOUTDIV1; + CRM->MISC1 |= (AT32_CLKOUT_SEL & AT32_CLKOUT_SEL_MISC1_MASK) | AT32_CLKOUTDIV2; + + /* PLL Auto Step activation.*/ + CRM->MISC2 |= CRM_MISC2_AUTO_STEP_EN; + + /* Switching to the configured clock source if it is different from HICK.*/ +#if AT32_SCLKSEL != AT32_SCLKSEL_HICK +#if AT32_SCLKSEL == AT32_SCLKSEL_HEXT + CRM->MISC2 |= AT32_HEXT_TO_SCLK_DIV; +#endif + /* Switches clock source.*/ + CRM->CFG |= AT32_SCLKSEL; + while ((CRM->CFG & CRM_CFG_SCLKSTS) != (AT32_SCLKSEL << 2)); /* Waits selection complete. */ +#endif + + /* PLL Auto Step inactivation.*/ + CRM->MISC2 &= ~CRM_MISC2_AUTO_STEP_EN; + +#if !AT32_HICK_ENABLED + CRM->CTRL &= ~CRM_CTRL_HICKEN; +#endif + +#if AT32_PLLU_USB48_SEL == AT32_PLLU_USB48_SEL_HICK + at32_hick_divider_select(AT32_HICKDIV_DIV1); + at32_hick_frequency_select(AT32_HICK_TO_SCLK_HICKOUT); +#endif + CRM->MISC2 &= ~AT32_PLLU_USB48_SEL_MASK; + CRM->MISC2 |= AT32_PLLU_USB48_SEL; + +#if AT32_SYSTICK_CLKSRC == AT32_SYSTICK_CLKSRC_HCLKDIV1 + SysTick->CTRL |= AT32_SYSTICK_CLKSRC_HCLKDIV1; +#else + SysTick->CTRL &= ~AT32_SYSTICK_CLKSRC_HCLKDIV1; +#endif + +#endif /* !AT32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + CRM->APB2EN |= CRM_APB2EN_SCFGEN; + CRM->APB2LPEN |= CRM_APB2LPEN_SCFGLPEN; +} + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/hal_lld.h b/os/hal/ports/AT32/AT32F405xx/hal_lld.h new file mode 100644 index 0000000000..de7eebd51c --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/hal_lld.h @@ -0,0 +1,1203 @@ +/* + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file AT32F405xx/hal_lld.h + * @brief AT32F405xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - AT32_LEXTCLK. + * - AT32_LEXT_BYPASS (optionally). + * - AT32_HEXTCLK. + * - AT32_HEXT_BYPASS (optionally). + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "at32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Requires use of SPIv2 driver model. + */ +#define HAL_LLD_SELECT_SPI_V2 TRUE + +/** + * @name Platform identification + * @{ + */ +#define PLATFORM_NAME "AT32F405xx" + +/** + * @brief Sub-family identifier. + */ +#if !defined(AT32F405xx) || defined(__DOXYGEN__) +#define AT32F405xx +#endif +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum system clock frequency. + */ +#define AT32_SYSCLK_MAX 216000000 + +/** + * @brief Maximum HEXT clock frequency. + */ +#define AT32_HEXTCLK_MAX 25000000 + +/** + * @brief Maximum HEXT clock frequency using an external source. + */ +#define AT32_HEXTCLK_BYP_MAX 25000000 + +/** + * @brief Minimum HEXT clock frequency. + */ +#define AT32_HEXTCLK_MIN 4000000 + +/** + * @brief Minimum HEXT clock frequency. + */ +#define AT32_HEXTCLK_BYP_MIN 4000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define AT32_LEXTCLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency. + */ +#define AT32_LEXTCLK_BYP_MAX 1000000 + +/** + * @brief Minimum LEXT clock frequency. + */ +#define AT32_LEXTCLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define AT32_PLLIN_MAX 16000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define AT32_PLLIN_MIN 2000000 + +/** + * @brief Maximum PLLs VCO clock frequency. + */ +#define AT32_PLLVCO_MAX 1000000000 + +/** + * @brief Minimum PLLs VCO clock frequency. + */ +#define AT32_PLLVCO_MIN 500000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define AT32_PLLOUT_MAX 216000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define AT32_PLLOUT_MIN 4000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define AT32_PCLK1_MAX 120000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define AT32_PCLK2_MAX 216000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define AT32_ADCCLK_MAX 28000000 +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define AT32_HICKCLK 48000000 /**< High speed internal clock. */ +#define AT32_LICKCLK 40000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWC_CTRL register bits definitions + * @{ + */ +#define AT32_PVMSEL_MASK (7 << 5) /**< PVMSEL bits mask. */ +#define AT32_PVMSEL_LEV0 (0 << 5) /**< PVM level 0. */ +#define AT32_PVMSEL_LEV1 (1 << 5) /**< PVM level 1. */ +#define AT32_PVMSEL_LEV2 (2 << 5) /**< PVM level 2. */ +#define AT32_PVMSEL_LEV3 (3 << 5) /**< PVM level 3. */ +#define AT32_PVMSEL_LEV4 (4 << 5) /**< PVM level 4. */ +#define AT32_PVMSEL_LEV5 (5 << 5) /**< PVM level 5. */ +#define AT32_PVMSEL_LEV6 (6 << 5) /**< PVM level 6. */ +#define AT32_PVMSEL_LEV7 (7 << 5) /**< PVM level 7. */ +/** @} */ + +/** + * @name PWC_LDOOV register bits definitions + * @{ + */ +#define AT32_LDOOVSEL_MASK (3 << 0) /**< LDOOVSEL bits mask. */ +#define AT32_LDOOVSEL_1P0V (0 << 0) /**< LDOOVSEL 1.0V. */ +#define AT32_LDOOVSEL_1P1V (1 << 0) /**< LDOOVSEL 1.1V. */ +#define AT32_LDOOVSEL_1P2V (2 << 0) /**< LDOOVSEL 1.2V. */ +#define AT32_LDOOVSEL_1P3V (3 << 0) /**< LDOOVSEL 1.3V. */ +/** @} */ + +/** + * @name CRM_PLLCFG register bits definitions + * @{ + */ +#define AT32_PLL_FP_MASK (15 << 16) /**< PLL_FP mask. */ +#define AT32_PLL_FP_DIV1 (0 << 16) /**< PLL clock divided by 1. */ +#define AT32_PLL_FP_DIV2 (1 << 16) /**< PLL clock divided by 2. */ +#define AT32_PLL_FP_DIV4 (2 << 16) /**< PLL clock divided by 4. */ +#define AT32_PLL_FP_DIV6 (3 << 16) /**< PLL clock divided by 6. */ +#define AT32_PLL_FP_DIV8 (4 << 16) /**< PLL clock divided by 8. */ +#define AT32_PLL_FP_DIV10 (5 << 16) /**< PLL clock divided by 10. */ +#define AT32_PLL_FP_DIV12 (6 << 16) /**< PLL clock divided by 12. */ +#define AT32_PLL_FP_DIV14 (7 << 16) /**< PLL clock divided by 14. */ +#define AT32_PLL_FP_DIV16 (8 << 16) /**< PLL clock divided by 16. */ +#define AT32_PLL_FP_DIV18 (9 << 16) /**< PLL clock divided by 18. */ +#define AT32_PLL_FP_DIV20 (10 << 16) /**< PLL clock divided by 20. */ +#define AT32_PLL_FP_DIV22 (11 << 16) /**< PLL clock divided by 22. */ +#define AT32_PLL_FP_DIV24 (12 << 16) /**< PLL clock divided by 24. */ +#define AT32_PLL_FP_DIV26 (13 << 16) /**< PLL clock divided by 26. */ +#define AT32_PLL_FP_DIV28 (14 << 16) /**< PLL clock divided by 28. */ +#define AT32_PLL_FP_DIV30 (15 << 16) /**< PLL clock divided by 30. */ + +#define AT32_PLL_FU_MASK (7 << 20) /**< PLL_FU mask. */ +#define AT32_PLL_FU_DIV11 (0 << 20) /**< PLLU clock divided by 11. */ +#define AT32_PLL_FU_DIV13 (1 << 20) /**< PLLU clock divided by 13. */ +#define AT32_PLL_FU_DIV12 (2 << 20) /**< PLLU clock divided by 12. */ +#define AT32_PLL_FU_DIV14 (3 << 20) /**< PLLU clock divided by 14. */ +#define AT32_PLL_FU_DIV16 (4 << 20) /**< PLLU clock divided by 16. */ +#define AT32_PLL_FU_DIV18 (5 << 20) /**< PLLU clock divided by 18. */ +#define AT32_PLL_FU_DIV20 (6 << 20) /**< PLLU clock divided by 20. */ + +#define AT32_PLLRCS_HICK (0 << 30) /**< PLL clock source is HICK. */ +#define AT32_PLLRCS_HEXT (1 << 30) /**< PLL clock source is HEXT. */ +/** @} */ + +/** + * @name CRM_CFG register bits definitions + * @{ + */ +#define AT32_SCLKSEL_MASK (3 << 0) /**< SCLKSEL mask. */ +#define AT32_SCLKSEL_HICK (0 << 0) /**< SYSCLK source is HICK. */ +#define AT32_SCLKSEL_HEXT (1 << 0) /**< SYSCLK source is HEXT. */ +#define AT32_SCLKSEL_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define AT32_SCLKSTS_MASK (3 << 2) /**< SCLKSTS mask. */ +#define AT32_SCLKSTS_HICK (0 << 2) /**< SYSCLK use HICK. */ +#define AT32_SCLKSTS_HEXT (1 << 2) /**< SYSCLK use HEXT. */ +#define AT32_SCLKSTS_PLL (2 << 2) /**< SYSCLK use PLL. */ + +#define AT32_AHBDIV_MASK (15 << 4) /**< AHBDIV mask. */ +#define AT32_AHBDIV_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define AT32_AHBDIV_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define AT32_AHBDIV_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define AT32_AHBDIV_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define AT32_AHBDIV_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define AT32_AHBDIV_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define AT32_AHBDIV_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define AT32_AHBDIV_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define AT32_AHBDIV_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define AT32_APB1DIV_MASK (7 << 10) /**< APB1DIV mask. */ +#define AT32_APB1DIV_DIV1 (0 << 10) /**< HCLK divided by 1. */ +#define AT32_APB1DIV_DIV2 (4 << 10) /**< HCLK divided by 2. */ +#define AT32_APB1DIV_DIV4 (5 << 10) /**< HCLK divided by 4. */ +#define AT32_APB1DIV_DIV8 (6 << 10) /**< HCLK divided by 8. */ +#define AT32_APB1DIV_DIV16 (7 << 10) /**< HCLK divided by 16. */ + +#define AT32_APB2DIV_MASK (7 << 13) /**< APB2DIV mask. */ +#define AT32_APB2DIV_DIV1 (0 << 13) /**< HCLK divided by 1. */ +#define AT32_APB2DIV_DIV2 (4 << 13) /**< HCLK divided by 2. */ +#define AT32_APB2DIV_DIV4 (5 << 13) /**< HCLK divided by 4. */ +#define AT32_APB2DIV_DIV8 (6 << 13) /**< HCLK divided by 8. */ +#define AT32_APB2DIV_DIV16 (7 << 13) /**< HCLK divided by 16. */ + +#define AT32_ERTCDIV_MASK (31 << 16) /**< ERTCDIV mask. */ + +#define AT32_I2SF5CLKSEL_MASK (3 << 22) /**< I2SF5CLKSEL mask. */ +#define AT32_I2SF5CLKSEL_SCLK (0 << 22) /**< I2SF5CLKSEL is SYSCLK. */ +#define AT32_I2SF5CLKSEL_PLL (1 << 22) /**< I2SF5CLKSEL is PLL. */ +#define AT32_I2SF5CLKSEL_HICK (2 << 22) /**< I2SF5CLKSEL is HICK. */ +#define AT32_I2SF5CLKSEL_EXCLK (3 << 22) /**< I2SF5CLKSEL is EXCLK. */ + +#define AT32_CLKOUTDIV1_MASK (7 << 27) /**< CLKOUTDIV1 mask. */ +#define AT32_CLKOUTDIV1_DIV1 (0 << 27) /**< CLKOUT divided by 1. */ +#define AT32_CLKOUTDIV1_DIV2 (4 << 27) /**< CLKOUT divided by 2. */ +#define AT32_CLKOUTDIV1_DIV3 (5 << 27) /**< CLKOUT divided by 3. */ +#define AT32_CLKOUTDIV1_DIV4 (6 << 27) /**< CLKOUT divided by 4. */ +#define AT32_CLKOUTDIV1_DIV5 (7 << 27) /**< CLKOUT divided by 5. */ + +#define AT32_CLKOUT_SEL_CFG_MASK (3 << 30) /**< CLKOUT_SEL CFG mask. */ +#define AT32_CLKOUT_SEL_MISC1_MASK (15 << 16) /**< CLKOUT_SEL MISC1 mask. */ +#define AT32_CLKOUT_SEL_SCLK (0 << 30) /**< CLKOUT_SEL SYSCLK. */ +#define AT32_CLKOUT_SEL_HEXT (2 << 30) /**< CLKOUT_SEL HEXT. */ +#define AT32_CLKOUT_SEL_PLL (3 << 30) /**< CLKOUT_SEL PLL. */ +#define AT32_CLKOUT_SEL_USBFS ((1 << 30) | \ + (0 << 16)) /**< CLKOUT_SEL USBFS. */ +#define AT32_CLKOUT_SEL_ADC ((1 << 30) | \ + (1 << 16)) /**< CLKOUT_SEL ADC. */ +#define AT32_CLKOUT_SEL_HICK ((1 << 30) | \ + (2 << 16)) /**< CLKOUT_SEL HICK. */ +#define AT32_CLKOUT_SEL_LICK ((1 << 30) | \ + (3 << 16)) /**< CLKOUT_SEL LICK. */ +#define AT32_CLKOUT_SEL_LEXT ((1 << 30) | \ + (4 << 16)) /**< CLKOUT_SEL LEXT. */ +#define AT32_CLKOUT_SEL_USBHS ((1 << 30) | \ + (5 << 16)) /**< CLKOUT_SEL USBHS. */ +/** @} */ + +/** + * @name CRM_BPDC register bits definitions + * @{ + */ +#define AT32_ERTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ +#define AT32_ERTCSEL_NOCLOCK (0 << 8) /**< No clock. */ +#define AT32_ERTCSEL_LEXT (1 << 8) /**< LEXT used as RTC clock. */ +#define AT32_ERTCSEL_LICK (2 << 8) /**< LICK used as RTC clock. */ +#define AT32_ERTCSEL_HEXTDIV (3 << 8) /**< HEXT divided used as + RTC clock. */ +/** @} */ + +/** + * @name CRM_MISC1 register bits definitions + * @{ + */ +#define AT32_HICKDIV_MASK (1 << 12) /**< HICKDIV mask. */ +#define AT32_HICKDIV_DIV6 (0 << 12) /**< HICK divided by 6. */ +#define AT32_HICKDIV_DIV1 (1 << 12) /**< HICK divided by 1. */ + +#define AT32_HICK_TO_SCLK_MASK (1 << 14) /**< HICK_TO_SCLK mask. */ +#define AT32_HICK_TO_SCLK_8M (0 << 14) /**< SCLK is 8MHz if SCLK + is HICK. */ +#define AT32_HICK_TO_SCLK_HICKOUT (1 << 14) /**< SCLK is HICKOUT if SCLK + is HICK. */ + +#define AT32_CLKOUTDIV2_MASK (15 << 28) /**< CLKOUTDIV2 mask. */ +#define AT32_CLKOUTDIV2_DIV1 (0 << 28) /**< CLKOUT divided by 1. */ +#define AT32_CLKOUTDIV2_DIV2 (8 << 28) /**< CLKOUT divided by 2. */ +#define AT32_CLKOUTDIV2_DIV4 (9 << 28) /**< CLKOUT divided by 4. */ +#define AT32_CLKOUTDIV2_DIV8 (10 << 28) /**< CLKOUT divided by 8. */ +#define AT32_CLKOUTDIV2_DIV16 (11 << 28) /**< CLKOUT divided by 16. */ +#define AT32_CLKOUTDIV2_DIV64 (12 << 28) /**< CLKOUT divided by 64. */ +#define AT32_CLKOUTDIV2_DIV128 (13 << 28) /**< CLKOUT divided by 128. */ +#define AT32_CLKOUTDIV2_DIV256 (14 << 28) /**< CLKOUT divided by 256. */ +#define AT32_CLKOUTDIV2_DIV512 (15 << 28) /**< CLKOUT divided by 512. */ +/** @} */ + +/** + * @name CRM_MISC2 register bits definitions + * @{ + */ +#define AT32_PLLU_USB48_SEL_MASK (1 << 10) /**< PLLU_USB48_SEL mask. */ +#define AT32_PLLU_USB48_SEL_PLLU (0 << 10) /**< PLLU_USB48_SEL PLLU. */ +#define AT32_PLLU_USB48_SEL_HICK (1 << 10) /**< PLLU_USB48_SEL HICK. */ + +#define AT32_HICK_TO_SCLK_DIV_MASK (7 << 16) /**< HICK_TO_SCLK_DIV mask. */ +#define AT32_HICK_TO_SCLK_DIV_DIV1 (0 << 16) /**< HICK divided by 1. */ +#define AT32_HICK_TO_SCLK_DIV_DIV2 (1 << 16) /**< HICK divided by 2. */ +#define AT32_HICK_TO_SCLK_DIV_DIV4 (2 << 16) /**< HICK divided by 4. */ +#define AT32_HICK_TO_SCLK_DIV_DIV8 (3 << 16) /**< HICK divided by 8. */ +#define AT32_HICK_TO_SCLK_DIV_DIV16 (4 << 16) /**< HICK divided by 16. */ + +#define AT32_HEXT_TO_SCLK_DIV_MASK (7 << 19) /**< HEXT_TO_SCLK_DIV mask. */ +#define AT32_HEXT_TO_SCLK_DIV_DIV1 (0 << 19) /**< HEXT divided by 1. */ +#define AT32_HEXT_TO_SCLK_DIV_DIV2 (1 << 19) /**< HEXT divided by 2. */ +#define AT32_HEXT_TO_SCLK_DIV_DIV4 (2 << 19) /**< HEXT divided by 4. */ +#define AT32_HEXT_TO_SCLK_DIV_DIV8 (3 << 19) /**< HEXT divided by 8. */ +#define AT32_HEXT_TO_SCLK_DIV_DIV16 (4 << 19) /**< HEXT divided by 16. */ +#define AT32_HEXT_TO_SCLK_DIV_DIV32 (5 << 19) /**< HEXT divided by 32. */ +/** @} */ + +/** + * @name SYSTICK_CTRL register bits definitions + * @{ + */ +#define AT32_SYSTICK_CLKSRC_HCLKDIV8 (0 << 0) /**< Systick clk is hclk/8 */ +#define AT32_SYSTICK_CLKSRC_HCLKDIV1 (4 << 0) /**< Systick clk is hclk. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/CRM initialization in the HAL. + */ +#if !defined(AT32_NO_INIT) || defined(__DOXYGEN__) +#define AT32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(AT32_PVM_ENABLE) || defined(__DOXYGEN__) +#define AT32_PVM_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(AT32_PVM) || defined(__DOXYGEN__) +#define AT32_PVM AT32_PVMSEL_LEV0 +#endif + +/** + * @brief Enables or disables the HICK clock source. + */ +#if !defined(AT32_HICK_ENABLED) || defined(__DOXYGEN__) +#define AT32_HICK_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LICK clock source. + */ +#if !defined(AT32_LICK_ENABLED) || defined(__DOXYGEN__) +#define AT32_LICK_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HEXT clock source. + */ +#if !defined(AT32_HEXT_ENABLED) || defined(__DOXYGEN__) +#define AT32_HEXT_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LEXT clock source. + */ +#if !defined(AT32_LEXT_ENABLED) || defined(__DOXYGEN__) +#define AT32_LEXT_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the PLLU clock source. + */ +#if !defined(AT32_PLLU_ENABLED) || defined(__DOXYGEN__) +#define AT32_PLLU_ENABLED TRUE +#endif + +/** + * @brief USB clock setting. + */ +#if !defined(AT32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) +#define AT32_CLOCK48_REQUIRED TRUE +#endif + +/** + * @brief USB clock source selection. + */ +#if !defined(AT32_PLLU_USB48_SEL) || defined(__DOXYGEN__) +#define AT32_PLLU_USB48_SEL AT32_PLLU_USB48_SEL_PLLU +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 216MHz system clock from + * a 12MHz crystal using the PLL. + */ +#if !defined(AT32_SCLKSEL) || defined(__DOXYGEN__) +#define AT32_SCLKSEL AT32_SCLKSEL_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 216MHz system clock from + * a 12MHz crystal using the PLL. + */ +#if !defined(AT32_PLLRCS) || defined(__DOXYGEN__) +#define AT32_PLLRCS AT32_PLLRCS_HEXT +#endif + +/** + * @brief PLL_MS divider value. + * @note The allowed values are 1..15. + * @note The default value is calculated for a 216MHz system clock from + * a 12MHz crystal using the PLL. + */ +#if !defined(AT32_PLL_MS_VALUE) || defined(__DOXYGEN__) +#define AT32_PLL_MS_VALUE 1 +#endif + +/** + * @brief PLL_NS multiplier value. + * @note The allowed values are 31..500. + * @note The default value is calculated for a 216MHz system clock from + * a 12MHz crystal using the PLL. + */ +#if !defined(AT32_PLL_NS_VALUE) || defined(__DOXYGEN__) +#define AT32_PLL_NS_VALUE 72 +#endif + +/** + * @brief PLL_FP divider value. + * @note The allowed values are 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, + * 22, 24, 26, 28, 30. + * @note The default value is calculated for a 216MHz system clock from + * a 12MHz crystal using the PLL. + */ +#if !defined(AT32_PLL_FP_VALUE) || defined(__DOXYGEN__) +#define AT32_PLL_FP_VALUE 4 +#endif + +/** + * @brief PLL_FU divider value. + * @note The allowed values are 11, 12, 13, 14, 16, 18, 20. + * @note The default value is calculated for a 216MHz system clock from + * a 12MHz crystal using the PLL. + */ +#if !defined(AT32_PLL_FU_VALUE) || defined(__DOXYGEN__) +#define AT32_PLL_FU_VALUE 18 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 216MHz system clock from + * a 12MHz crystal using the PLL. + */ +#if !defined(AT32_AHBDIV) || defined(__DOXYGEN__) +#define AT32_AHBDIV AT32_AHBDIV_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(AT32_APB1DIV) || defined(__DOXYGEN__) +#define AT32_APB1DIV AT32_APB1DIV_DIV2 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(AT32_APB2DIV) || defined(__DOXYGEN__) +#define AT32_APB2DIV AT32_APB2DIV_DIV1 +#endif + +/** + * @brief HICK source selection if SCLK is HICK. + */ +#if !defined(AT32_HICK_TO_SCLK) || defined(__DOXYGEN__) +#define AT32_HICK_TO_SCLK AT32_HICK_TO_SCLK_HICKOUT +#endif + +/** + * @brief HICK prescaler selection. + */ +#if !defined(AT32_HICKDIV) || defined(__DOXYGEN__) +#define AT32_HICKDIV AT32_HICKDIV_DIV1 +#endif + +/** + * @brief HICK prescaler value when SCLK is HICK. + */ +#if !defined(AT32_HICK_TO_SCLK_DIV) || defined(__DOXYGEN__) +#define AT32_HICK_TO_SCLK_DIV AT32_HICK_TO_SCLK_DIV_DIV1 +#endif + +/** + * @brief HEXT prescaler value when SCLK is HEXT. + */ +#if !defined(AT32_HEXT_TO_SCLK_DIV) || defined(__DOXYGEN__) +#define AT32_HEXT_TO_SCLK_DIV AT32_HEXT_TO_SCLK_DIV_DIV1 +#endif + +/** + * @brief ERTC clock source. + */ +#if !defined(AT32_ERTCSEL) || defined(__DOXYGEN__) +#define AT32_ERTCSEL AT32_ERTCSEL_NOCLOCK +#endif + +/** + * @brief ERTC HEXT prescaler value. + * @note The allowed values are 2..31. + */ +#if !defined(AT32_ERTCDIV_VALUE) || defined(__DOXYGEN__) +#define AT32_ERTCDIV_VALUE 12 +#endif + +/** + * @brief I2SF5 clock source. + */ +#if !defined(AT32_I2SF5CLKSEL) || defined(__DOXYGEN__) +#define AT32_I2SF5CLKSEL AT32_I2SF5CLKSEL_SCLK +#endif + +/** + * @brief CLKOUT pin setting. + */ +#if !defined(AT32_CLKOUT_SEL) || defined(__DOXYGEN__) +#define AT32_CLKOUT_SEL AT32_CLKOUT_SEL_HICK +#endif + +/** + * @brief CLKOUT prescaler value 1. + */ +#if !defined(AT32_CLKOUTDIV1) || defined(__DOXYGEN__) +#define AT32_CLKOUTDIV1 AT32_CLKOUTDIV1_DIV1 +#endif + +/** + * @brief CLKOUT prescaler value 2. + */ +#if !defined(AT32_CLKOUTDIV2) || defined(__DOXYGEN__) +#define AT32_CLKOUTDIV2 AT32_CLKOUTDIV2_DIV1 +#endif + +/** + * @brief LDOOVSEL setting. + */ +#if !defined(AT32_LDOOVSEL) || defined(__DOXYGEN__) +#define AT32_LDOOVSEL AT32_LDOOVSEL_1P3V +#endif + +/** + * @brief Systick clock source setting. + */ +#if !defined(AT32_SYSTICK_CLKSRC) || defined(__DOXYGEN__) +#define AT32_SYSTICK_CLKSRC AT32_SYSTICK_CLKSRC_HCLKDIV1 +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(AT32F405xx_MCUCONF) +#error "Using a wrong mcuconf.h file, AT32F405xx_MCUCONF not defined" +#endif + +/* + * Board files sanity checks. + */ +#if !defined(AT32_LEXTCLK) +#error "AT32_LEXTCLK not defined in board.h" +#endif + +#if !defined(AT32_HEXTCLK) +#error "AT32_HEXTCLK not defined in board.h" +#endif + +/* + * HICK related checks. + */ +#if AT32_HICK_ENABLED +#else /* !AT32_HICK_ENABLED */ + +#if AT32_SCLKSEL == AT32_SCLKSEL_HICK +#error "HICK not enabled, required by AT32_SCLKSEL" +#endif + +#if ((AT32_SCLKSEL == AT32_SCLKSEL_HICK) && \ + (AT32_PLLRCS == AT32_PLLRCS_HICK)) +#error "HICK not enabled, required by AT32_SCLKSEL and AT32_PLLRCS" +#endif + +#if (AT32_CLKOUT_SEL == AT32_CLKOUT_SEL_HICK) || \ + ((AT32_CLKOUT_SEL == AT32_CLKOUT_SEL_PLL) && \ + (AT32_PLLRCS == AT32_PLLRCS_HICK)) +#error "HICK not enabled, required by AT32_CLKOUT_SEL" +#endif + +#if (AT32_PLLU_USB48_SEL == AT32_PLLU_USB48_SEL_HICK) || \ + ((AT32_PLLU_USB48_SEL == AT32_PLLU_USB48_SEL_PLLU) && \ + (AT32_PLLRCS == AT32_PLLRCS_HICK)) +#error "HICK not enabled, required by AT32_PLLU_USB48_SEL" +#endif + +#if (AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_HICK) || \ + ((AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_PLL) && \ + (AT32_PLLRCS == AT32_PLLRCS_HICK)) || \ + ((AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_SCLK) && \ + (AT32_SCLKSEL == AT32_SCLKSEL_HICK)) || \ + ((AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_SCLK) && \ + (AT32_SCLKSEL == AT32_SCLKSEL_PLL) && \ + (AT32_PLLRCS == AT32_PLLRCS_HICK)) +#error "HICK not enabled, required by AT32_I2SF5CLKSEL" +#endif + +#endif /* !AT32_HICK_ENABLED */ + +/* + * HEXT related checks. + */ +#if AT32_HEXT_ENABLED + +#if AT32_HEXTCLK == 0 +#error "HEXT frequency not defined" +#else /* AT32_HEXTCLK != 0 */ +#if defined(AT32_HEXT_BYPASS) +#if (AT32_HEXTCLK < AT32_HEXTCLK_BYP_MIN) || (AT32_HEXTCLK > AT32_HEXTCLK_BYP_MAX) +#error "AT32_HEXTCLK outside acceptable range (AT32_HEXTCLK_MIN...AT32_HEXTCLK_BYP_MAX)" +#endif +#else /* !defined(AT32_HEXT_BYPASS) */ +#if (AT32_HEXTCLK < AT32_HEXTCLK_MIN) || (AT32_HEXTCLK > AT32_HEXTCLK_MAX) +#error "AT32_HEXTCLK outside acceptable range (AT32_HEXTCLK_MIN...AT32_HEXTCLK_MAX)" +#endif +#endif /* !defined(AT32_HEXT_BYPASS) */ +#endif /* AT32_HEXTCLK != 0 */ + +#else /* !AT32_HEXT_ENABLED */ + +#if AT32_SCLKSEL == AT32_SCLKSEL_HEXT +#error "HEXT not enabled, required by AT32_SCLKSEL" +#endif + +#if (AT32_SCLKSEL == AT32_SCLKSEL_PLL) && (AT32_PLLRCS == AT32_PLLRCS_HEXT) +#error "HEXT not enabled, required by AT32_SCLKSEL and AT32_PLLRCS" +#endif + +#if (AT32_CLKOUT_SEL == AT32_CLKOUT_SEL_HEXT) || \ + ((AT32_CLKOUT_SEL == AT32_CLKOUT_SEL_PLL) && \ + (AT32_PLLRCS == AT32_PLLRCS_HEXT)) +#error "HEXT not enabled, required by AT32_CLKOUT_SEL" +#endif + +#if AT32_ERTCSEL == AT32_ERTCSEL_HEXTDIV +#error "HEXT not enabled, required by AT32_ERTCSEL" +#endif + +#if ((AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_PLL) && \ + (AT32_PLLRCS == AT32_PLLRCS_HEXT)) || \ + ((AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_SCLK) && \ + (AT32_SCLKSEL == AT32_SCLKSEL_HEXT)) || \ + ((AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_SCLK) && \ + (AT32_SCLKSEL == AT32_SCLKSEL_PLL) && \ + (AT32_PLLRCS == AT32_PLLRCS_HEXT)) +#error "HICK not enabled, required by AT32_I2SF5CLKSEL" +#endif + +#endif /* !AT32_HEXT_ENABLED */ + +#if AT32_LICK_ENABLED +#else /* !AT32_LICK_ENABLED */ + +#if AT32_CLKOUT_SEL == AT32_CLKOUT_SEL_LICK +#error "LICK not enabled, required by AT32_CLKOUT_SEL" +#endif +#if HAL_USE_RTC && (AT32_ERTCSEL == AT32_ERTCSEL_LICK) +#error "LICK not enabled, required by AT32_ERTCSEL" +#endif +#endif /* !AT32_LICK_ENABLED */ + +/* LEXT related checks.*/ +#if AT32_LEXT_ENABLED +#if (AT32_LEXTCLK == 0) +#error "impossible to activate LEXT, frequency is zero" +#endif + +#if (AT32_LEXTCLK < AT32_LEXTCLK_MIN) || (AT32_LEXTCLK > AT32_LEXTCLK_MAX) +#error "AT32_LEXTCLK outside acceptable range (AT32_LEXTCLK_MIN...AT32_LEXTCLK_MAX)" +#endif + +#else /* !AT32_LEXT_ENABLED */ + +#if AT32_CLKOUT_SEL == AT32_CLKOUT_SEL_LEXT +#error "LEXT not enabled, required by AT32_CLKOUT_SEL" +#endif +#if AT32_ERTCSEL == AT32_ERTCSEL_LEXT +#error "LEXT not enabled, required by AT32_ERTCSEL" +#endif +#endif /* !AT32_LEXT_ENABLED */ + +#if AT32_PLLU_ENABLED +#else /* !AT32_PLLU_ENABLED */ + +#if AT32_PLLU_USB48_SEL == AT32_PLLU_USB48_SEL_PLLU +#error "PLLU not enabled, required by AT32_PLLU_USB48_SEL" +#endif +#endif /* !AT32_PLLU_ENABLED */ + +/** + * @brief AT32_PLL_MS field. + */ +#if ((AT32_PLL_MS_VALUE >= 1) && (AT32_PLL_MS_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define AT32_PLL_MS (AT32_PLL_MS_VALUE << 0) +#else +#error "invalid AT32_PLL_MS_VALUE value specified" +#endif + +/** + * @brief HICK output clock frequency. + */ +#if (AT32_HICKDIV == AT32_HICKDIV_DIV1) || defined(__DOXYGEN__) +#define AT32_HICKCLKOUT (AT32_HICKCLK / 1) +#elif (AT32_HICKDIV == AT32_HICKDIV_DIV6) +#define AT32_HICKCLKOUT (AT32_HICKCLK / 6) +#else +#error "invalid AT32_HICKDIV value specified" +#endif + +/** + * @brief PLLs input clock frequency. + */ +#if (AT32_PLLRCS == AT32_PLLRCS_HEXT) || defined(__DOXYGEN__) +#define AT32_PLLCLKIN (AT32_HEXTCLK / AT32_PLL_MS_VALUE) +#elif AT32_PLLRCS == AT32_PLLRCS_HICK +#define AT32_PLLCLKIN ((AT32_HICKCLK / 6) / AT32_PLL_MS_VALUE) +#else +#error "invalid AT32_PLLRCS value specified" +#endif + +/* + * PLLs input frequency range check. + */ +#if (AT32_PLLCLKIN < AT32_PLLIN_MIN) || (AT32_PLLCLKIN > AT32_PLLIN_MAX) +#error "AT32_PLLCLKIN outside acceptable range (AT32_PLLIN_MIN...AT32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (AT32_CLOCK48_REQUIRED && (AT32_PLLU_USB48_SEL == AT32_PLLU_USB48_SEL_PLLU)) || \ + (AT32_SCLKSEL == AT32_SCLKSEL_PLL) || \ + (AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_PLL) || \ + (AT32_CLKOUT_SEL == AT32_CLKOUT_SEL_PLL) || \ + (AT32_PLLU_ENABLED) || defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define AT32_ACTIVATE_PLL TRUE +#else +#define AT32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief AT32_PLL_NS field. + */ +#if ((AT32_PLL_NS_VALUE >= 31) && (AT32_PLL_NS_VALUE <= 500)) || \ + defined(__DOXYGEN__) +#define AT32_PLL_NS (AT32_PLL_NS_VALUE << 6) +#else +#error "invalid AT32_PLL_NS_VALUE value specified" +#endif + +/** + * @brief AT32_PLL_FP field. + */ +#if (AT32_PLL_FP_VALUE == 1) || defined(__DOXYGEN__) +#define AT32_PLL_FP AT32_PLL_FP_DIV1 +#elif AT32_PLL_FP_VALUE == 2 +#define AT32_PLL_FP AT32_PLL_FP_DIV2 +#elif AT32_PLL_FP_VALUE == 4 +#define AT32_PLL_FP AT32_PLL_FP_DIV4 +#elif AT32_PLL_FP_VALUE == 6 +#define AT32_PLL_FP AT32_PLL_FP_DIV6 +#elif AT32_PLL_FP_VALUE == 8 +#define AT32_PLL_FP AT32_PLL_FP_DIV8 +#elif AT32_PLL_FP_VALUE == 10 +#define AT32_PLL_FP AT32_PLL_FP_DIV10 +#elif AT32_PLL_FP_VALUE == 12 +#define AT32_PLL_FP AT32_PLL_FP_DIV12 +#elif AT32_PLL_FP_VALUE == 14 +#define AT32_PLL_FP AT32_PLL_FP_DIV14 +#elif AT32_PLL_FP_VALUE == 16 +#define AT32_PLL_FP AT32_PLL_FP_DIV16 +#elif AT32_PLL_FP_VALUE == 18 +#define AT32_PLL_FP AT32_PLL_FP_DIV18 +#elif AT32_PLL_FP_VALUE == 20 +#define AT32_PLL_FP AT32_PLL_FP_DIV20 +#else +#error "invalid AT32_PLL_FP_VALUE value specified" +#endif + +/** + * @brief AT32_PLL_FU field. + */ +#if (AT32_PLL_FU_VALUE == 11) || defined(__DOXYGEN__) +#define AT32_PLL_FU AT32_PLL_FU_DIV11 +#elif AT32_PLL_FU_VALUE == 12 +#define AT32_PLL_FU AT32_PLL_FU_DIV12 +#elif AT32_PLL_FU_VALUE == 13 +#define AT32_PLL_FU AT32_PLL_FU_DIV13 +#elif AT32_PLL_FU_VALUE == 14 +#define AT32_PLL_FU AT32_PLL_FU_DIV14 +#elif AT32_PLL_FU_VALUE == 16 +#define AT32_PLL_FU AT32_PLL_FU_DIV16 +#elif AT32_PLL_FU_VALUE == 18 +#define AT32_PLL_FU AT32_PLL_FU_DIV18 +#elif AT32_PLL_FU_VALUE == 20 +#define AT32_PLL_FU AT32_PLL_FU_DIV20 +#else +#error "invalid AT32_PLL_FU_VALUE value specified" +#endif + +/** + * @brief PLL VCO frequency. + */ +#define AT32_PLLVCO (AT32_PLLCLKIN * AT32_PLL_NS_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if (AT32_PLLVCO < AT32_PLLVCO_MIN) || (AT32_PLLVCO > AT32_PLLVCO_MAX) +#error "AT32_PLLVCO outside acceptable range (AT32_PLLVCO_MIN...AT32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL PCLK output clock frequency. + */ +#define AT32_PLLPCLK (AT32_PLLVCO / AT32_PLL_FP_VALUE) + +/* + * PLL PCLK frequency range check. + */ +#if (AT32_PLLPCLK < AT32_PLLOUT_MIN) || (AT32_PLLPCLK > AT32_PLLOUT_MAX) +#error "AT32_PLLPCLK outside acceptable range (AT32_PLLOUT_MIN...AT32_PLLOUT_MAX)" +#endif + +/** + * @brief PLL UCLK output clock frequency. + */ +#define AT32_PLLUCLK (AT32_PLLVCO / AT32_PLL_FU_VALUE) + +/* + * PLL UCLK frequency range check. + */ +#if (AT32_PLLUCLK < AT32_PLLOUT_MIN) || (AT32_PLLUCLK > AT32_PLLOUT_MAX) +#error "AT32_PLLUCLK outside acceptable range (AT32_PLLOUT_MIN...AT32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if AT32_NO_INIT || (AT32_SCLKSEL == AT32_SCLKSEL_HICK) || \ + defined(__DOXYGEN__) + +#if (AT32_HICK_TO_SCLK == AT32_HICK_TO_SCLK_8M) || defined(__DOXYGEN__) +#define AT32_SYSCLKIN (8000000) +#elif (AT32_HICK_TO_SCLK == AT32_HICK_TO_SCLK_HICKOUT) +#define AT32_SYSCLKIN (AT32_HICKCLKOUT) +#else +#error "invalid AT32_HICK_TO_SCLK value specified" +#endif + +#if (AT32_HICK_TO_SCLK_DIV == AT32_HICK_TO_SCLK_DIV_DIV1) || defined(__DOXYGEN__) +#define AT32_SYSCLK (AT32_SYSCLKIN / 1) +#elif (AT32_HICK_TO_SCLK_DIV == AT32_HICK_TO_SCLK_DIV_DIV2) +#define AT32_SYSCLK (AT32_SYSCLKIN / 2) +#elif (AT32_HICK_TO_SCLK_DIV == AT32_HICK_TO_SCLK_DIV_DIV4) +#define AT32_SYSCLK (AT32_SYSCLKIN / 4) +#elif (AT32_HICK_TO_SCLK_DIV == AT32_HICK_TO_SCLK_DIV_DIV8) +#define AT32_SYSCLK (AT32_SYSCLKIN / 8) +#elif (AT32_HICK_TO_SCLK_DIV == AT32_HICK_TO_SCLK_DIV_DIV16) +#define AT32_SYSCLK (AT32_SYSCLKIN / 16) +#else +#error "invalid AT32_HICK_TO_SCLK_DIV value specified" +#endif + +#elif AT32_SCLKSEL == AT32_SCLKSEL_HEXT + +#if (AT32_HEXT_TO_SCLK_DIV == AT32_HEXT_TO_SCLK_DIV_DIV1) +#define AT32_SYSCLK (AT32_HEXTCLK / 1) +#elif (AT32_HEXT_TO_SCLK_DIV == AT32_HEXT_TO_SCLK_DIV_DIV2) +#define AT32_SYSCLK (AT32_HEXTCLK / 2) +#elif (AT32_HEXT_TO_SCLK_DIV == AT32_HEXT_TO_SCLK_DIV_DIV4) +#define AT32_SYSCLK (AT32_HEXTCLK / 4) +#elif (AT32_HEXT_TO_SCLK_DIV == AT32_HEXT_TO_SCLK_DIV_DIV8) +#define AT32_SYSCLK (AT32_HEXTCLK / 8) +#elif (AT32_HEXT_TO_SCLK_DIV == AT32_HEXT_TO_SCLK_DIV_DIV16) +#define AT32_SYSCLK (AT32_HEXTCLK / 16) +#elif (AT32_HEXT_TO_SCLK_DIV == AT32_HEXT_TO_SCLK_DIV_DIV32) +#define AT32_SYSCLK (AT32_HEXTCLK / 32) +#else +#error "invalid AT32_HEXT_TO_SCLK_DIV value specified" +#endif + +#elif AT32_SCLKSEL == AT32_SCLKSEL_PLL + +#define AT32_SYSCLK AT32_PLLPCLK + +#else +#error "invalid AT32_SCLKSEL value specified" +#endif + +/* Check on the system clock.*/ +#if AT32_SYSCLK > AT32_SYSCLK_MAX +#error "AT32_SYSCLK above maximum rated frequency (AT32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (AT32_AHBDIV == AT32_AHBDIV_DIV1) || defined(__DOXYGEN__) +#define AT32_HCLK (AT32_SYSCLK / 1) +#elif AT32_AHBDIV == AT32_AHBDIV_DIV2 +#define AT32_HCLK (AT32_SYSCLK / 2) +#elif AT32_AHBDIV == AT32_AHBDIV_DIV4 +#define AT32_HCLK (AT32_SYSCLK / 4) +#elif AT32_AHBDIV == AT32_AHBDIV_DIV8 +#define AT32_HCLK (AT32_SYSCLK / 8) +#elif AT32_AHBDIV == AT32_AHBDIV_DIV16 +#define AT32_HCLK (AT32_SYSCLK / 16) +#elif AT32_AHBDIV == AT32_AHBDIV_DIV64 +#define AT32_HCLK (AT32_SYSCLK / 64) +#elif AT32_AHBDIV == AT32_AHBDIV_DIV128 +#define AT32_HCLK (AT32_SYSCLK / 128) +#elif AT32_AHBDIV == AT32_AHBDIV_DIV256 +#define AT32_HCLK (AT32_SYSCLK / 256) +#elif AT32_AHBDIV == AT32_AHBDIV_DIV512 +#define AT32_HCLK (AT32_SYSCLK / 512) +#else +#error "invalid AT32_AHBDIV value specified" +#endif + +/* AHB frequency check.*/ +#if AT32_HCLK > AT32_SYSCLK_MAX +#error "AT32_HCLK exceeding maximum frequency (AT32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (AT32_APB1DIV == AT32_APB1DIV_DIV1) || defined(__DOXYGEN__) +#define AT32_PCLK1 (AT32_HCLK / 1) +#elif AT32_APB1DIV == AT32_APB1DIV_DIV2 +#define AT32_PCLK1 (AT32_HCLK / 2) +#elif AT32_APB1DIV == AT32_APB1DIV_DIV4 +#define AT32_PCLK1 (AT32_HCLK / 4) +#elif AT32_APB1DIV == AT32_APB1DIV_DIV8 +#define AT32_PCLK1 (AT32_HCLK / 8) +#elif AT32_APB1DIV == AT32_APB1DIV_DIV16 +#define AT32_PCLK1 (AT32_HCLK / 16) +#else +#error "invalid AT32_APB1DIV value specified" +#endif + +/* APB1 frequency check.*/ +#if AT32_PCLK1 > AT32_PCLK1_MAX +#error "AT32_PCLK1 exceeding maximum frequency (AT32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (AT32_APB2DIV == AT32_APB2DIV_DIV1) || defined(__DOXYGEN__) +#define AT32_PCLK2 (AT32_HCLK / 1) +#elif AT32_APB2DIV == AT32_APB2DIV_DIV2 +#define AT32_PCLK2 (AT32_HCLK / 2) +#elif AT32_APB2DIV == AT32_APB2DIV_DIV4 +#define AT32_PCLK2 (AT32_HCLK / 4) +#elif AT32_APB2DIV == AT32_APB2DIV_DIV8 +#define AT32_PCLK2 (AT32_HCLK / 8) +#elif AT32_APB2DIV == AT32_APB2DIV_DIV16 +#define AT32_PCLK2 (AT32_HCLK / 16) +#else +#error "invalid AT32_APB2DIV value specified" +#endif + +/* APB2 frequency check.*/ +#if AT32_PCLK2 > AT32_PCLK2_MAX +#error "AT32_PCLK2 exceeding maximum frequency (AT32_PCLK2_MAX)" +#endif + +/* Check on LDOOVSEL value.*/ +#if AT32_LDOOVSEL == AT32_LDOOVSEL_1P3V + +#if (AT32_HCLK > 216000000) || \ + (AT32_PCLK1 > 120000000) || \ + (AT32_PCLK2 > AT32_HCLK) +#error "AT32 bus clock exceeding maximum frequency when LDO is 1.3V" +#endif + +#elif AT32_LDOOVSEL == AT32_LDOOVSEL_1P2V + +#if (AT32_HCLK > 168000000) || \ + (AT32_PCLK1 > 120000000) || \ + (AT32_PCLK2 > AT32_HCLK) +#error "AT32 bus clock exceeding maximum frequency when LDO is 1.2V" +#endif + +#elif ((AT32_LDOOVSEL == AT32_LDOOVSEL_1P1V) || \ + (AT32_LDOOVSEL == AT32_LDOOVSEL_1P0V)) + +#if (AT32_HCLK > 108000000) || \ + (AT32_PCLK1 > AT32_HCLK) || \ + (AT32_PCLK2 > AT32_HCLK) +#error "AT32 bus clock exceeding maximum frequency when LDO is 1.0V" +#endif + +#else +#error "invalid AT32_LDOOVSEL value specified" +#endif + +/** + * @brief USB clock. + */ +#if AT32_PLLU_USB48_SEL == AT32_PLLU_USB48_SEL_PLLU +#define AT32_USBCLK AT32_PLLUCLK +#elif AT32_PLLU_USB48_SEL == AT32_PLLU_USB48_SEL_HICK +#define AT32_USBCLK AT32_HICKCLKOUT +#else +#error "invalid AT32_PLLU_USB48_SEL value specified" +#endif + +/** + * @brief HEXT divider toward ERTC clock. + */ +#if ((AT32_ERTCDIV_VALUE >= 2) && (AT32_ERTCDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define AT32_HEXTDIVCLK (AT32_HEXTCLK / AT32_ERTCDIV_VALUE) +#define AT32_ETRCDIV (AT32_ERTCDIV_VALUE << 16) +#else +#error "invalid AT32_ERTCDIV value specified" +#endif + +/** + * @brief ERTC clock. + */ +#if (AT32_ERTCSEL == AT32_ERTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define AT32_ERTCCLK 0 +#elif AT32_ERTCSEL == AT32_ERTCSEL_LEXT +#define AT32_ERTCCLK AT32_LEXTCLK +#elif AT32_ERTCSEL == AT32_ERTCSEL_LICK +#define AT32_ERTCCLK AT32_LICKCLK +#elif AT32_ERTCSEL == AT32_ERTCSEL_HEXTDIV +#define AT32_ERTCCLK AT32_HEXTDIVCLK +#else +#error "invalid AT32_ERTCSEL value specified" +#endif + +/** + * @brief I2SF5 clock. + */ +#if (AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_SCLK) || defined(__DOXYGEN__) +#define AT32_I2SF5CLK AT32_SYSCLK +#elif AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_PLL +#define AT32_I2SF5CLK AT32_PLLPCLK +#elif AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_HICK +#define AT32_I2SF5CLK AT32_HICKCLKOUT +#elif AT32_I2SF5CLKSEL == AT32_I2SF5CLKSEL_EXCLK +#define AT32_I2SF5CLK 0 +#else +#error "invalid AT32_I2SF5CLKSEL value specified" +#endif + + +/** + * @brief Systick clock. + */ +#if (AT32_SYSTICK_CLKSRC == AT32_SYSTICK_CLKSRC_HCLKDIV1) || defined(__DOXYGEN__) +#define AT32_SYSTICK_CLK AT32_HCLK +#elif AT32_SYSTICK_CLKSRC == AT32_SYSTICK_CLKSRC_HCLKDIV8 +#define AT32_SYSTICK_CLK (AT32_HCLK / 8) +#else +#error "invalid AT32_SYSTICK_CLKSRC value specified" +#endif + +/** + * @brief Timers 2, 3, 4, 6, 7, 13, 14 clock. + */ +#if (AT32_APB1DIV == AT32_APB1DIV_DIV1) || defined(__DOXYGEN__) +#define AT32_TMRCLK1 (AT32_PCLK1 * 1) +#else +#define AT32_TMRCLK1 (AT32_PCLK1 * 2) +#endif + +/** + * @brief Timers 1, 9, 10, 11 clock. + */ +#if (AT32_APB2DIV == AT32_APB2DIV_DIV1) || defined(__DOXYGEN__) +#define AT32_TMRCLK2 (AT32_PCLK2 * 1) +#else +#define AT32_TMRCLK2 (AT32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (AT32_HCLK <= 32000000) || defined(__DOXYGEN__) +#define AT32_FLASHBITS 0x00000150 +#elif (AT32_HCLK <= 64000000) +#define AT32_FLASHBITS 0x00000151 +#elif (AT32_HCLK <= 96000000) +#define AT32_FLASHBITS 0x00000152 +#elif (AT32_HCLK <= 128000000) +#define AT32_FLASHBITS 0x00000153 +#elif (AT32_HCLK <= 160000000) +#define AT32_FLASHBITS 0x00000154 +#elif (AT32_HCLK <= 192000000) +#define AT32_FLASHBITS 0x00000155 +#elif (AT32_HCLK <= 216000000) +#define AT32_FLASHBITS 0x00000156 +#endif + +#define DEBUG_CTRL_TMR2_PAUSE DEBUG_APB1_PAUSE_TMR2_PAUSE +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "at32_crm.h" +#include "at32_dma.h" +#include "at32_exint.h" +#include "at32_isr.h" +#include "at32_tmr.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void at32_clock_init(void); + void at32_clock_reset(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ +/** @} */ diff --git a/os/hal/ports/AT32/AT32F405xx/platform.mk b/os/hal/ports/AT32/AT32F405xx/platform.mk new file mode 100644 index 0000000000..c1d78a6be9 --- /dev/null +++ b/os/hal/ports/AT32/AT32F405xx/platform.mk @@ -0,0 +1,42 @@ +# Required platform files. +PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ + $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/AT32F405xx/hal_lld.c \ + $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/AT32F405xx/at32_isr.c \ + $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/AT32F405xx/hal_efl_lld.c + +# Required include directories. +PLATFORMINC_CONTRIB += $(CHIBIOS)/os/hal/ports/common/ARMCMx \ + $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/AT32F405xx + + +ifeq ($(USE_SMART_BUILD),yes) + +# Configuration files directory +ifeq ($(HALCONFDIR),) + ifeq ($(CONFDIR),) + HALCONFDIR = . + else + HALCONFDIR := $(CONFDIR) + endif +endif + +HALCONF := $(strip $(shell cat $(HALCONFDIR)/halconf.h | egrep -e "\#define")) +endif #ifeq ($(USE_SMART_BUILD), yes) + +# Drivers compatible with the platform. +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/EXINTv1/driver.mk +include ${CHIBIOS_CONTRIB}/os/hal/ports/AT32/LLD/GPIOv2/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/DMAv2/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/RTCv2/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/TMRv1/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/SYSTICKv1/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/OTGv1/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/ADCv2/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv2/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/USARTv2/driver.mk +include $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/SPIv2/driver.mk + + +# Shared variables +ALLCSRC += $(PLATFORMSRC_CONTRIB) +ALLINC += $(PLATFORMINC_CONTRIB) diff --git a/os/hal/ports/AT32/LLD/ADCv2/driver.mk b/os/hal/ports/AT32/LLD/ADCv2/driver.mk new file mode 100644 index 0000000000..de1d275a89 --- /dev/null +++ b/os/hal/ports/AT32/LLD/ADCv2/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),) +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/ADCv2/hal_adc_lld.c +endif +else +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/ADCv2/hal_adc_lld.c +endif + +PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/ADCv2 \ No newline at end of file diff --git a/os/hal/ports/AT32/LLD/ADCv2/hal_adc_lld.c b/os/hal/ports/AT32/LLD/ADCv2/hal_adc_lld.c new file mode 100644 index 0000000000..7f5568e9f6 --- /dev/null +++ b/os/hal/ports/AT32/LLD/ADCv2/hal_adc_lld.c @@ -0,0 +1,538 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file ADCv2/hal_adc_lld.c + * @brief AT32 ADC subsystem low level driver source. + * + * @addtogroup ADC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define ADC1_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_ADC_ADC1_DMA_STREAM, AT32_ADC1_DMA_CHN) + +#define ADC2_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_ADC_ADC2_DMA_STREAM, AT32_ADC2_DMA_CHN) + +#define ADC3_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_ADC_ADC3_DMA_STREAM, AT32_ADC3_DMA_CHN) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief ADC1 driver identifier.*/ +#if AT32_ADC_USE_ADC1 || defined(__DOXYGEN__) +ADCDriver ADCD1; +#endif + +/** @brief ADC2 driver identifier.*/ +#if AT32_ADC_USE_ADC2 || defined(__DOXYGEN__) +ADCDriver ADCD2; +#endif + +/** @brief ADC3 driver identifier.*/ +#if AT32_ADC_USE_ADC3 || defined(__DOXYGEN__) +ADCDriver ADCD3; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief ADC DMA service routine. + * + * @param[in] adcp pointer to the @p ADCDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { + + /* DMA errors handling.*/ + if ((flags & (AT32_DMA_STS_DTERRF | AT32_DMA_STS_DMERRF)) != 0) { + /* DMA, this could help only if the DMA tries to access an unmapped + address space or violates alignment rules.*/ + _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE); + } + else { + /* It is possible that the conversion group has already be reset by the + ADC error handler, in this case this interrupt is spurious.*/ + if (adcp->grpp != NULL) { + + if ((flags & AT32_DMA_STS_FDTF) != 0) { + /* Transfer complete processing.*/ + _adc_isr_full_code(adcp); + } + else if ((flags & AT32_DMA_STS_HDTF) != 0) { + /* Half transfer processing.*/ + _adc_isr_half_code(adcp); + } + } + } +} + +/** + * @brief ADC IRQ service routine. + * + * @param[in] adcp pointer to the @p ADCDriver object + * @param[in] sts content of the STS register + */ +static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t sts) { + + /* It could be a spurious interrupt caused by overflows after DMA disabling, + just ignore it in this case.*/ + if (adcp->grpp != NULL) { + adcerror_t emask = 0U; + + /* Note, an overflow may occur after the conversion ended before the driver + is able to stop the ADC, this is why the state is checked too.*/ + if ((sts & ADC_STS_OCCS) && (adcp->state == ADC_ACTIVE)) { + /* ADC overflow condition, this could happen only if the DMA is unable + to read data fast enough.*/ + emask |= ADC_ERR_OVERFLOW; + } + if (sts & ADC_STS_VMOR) { + /* Analog watchdog 1 error.*/ + emask |= ADC_ERR_VM; + } + if (emask != 0U) { + _adc_isr_error_code(adcp, emask); + } + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if AT32_ADC_USE_ADC1 || AT32_ADC_USE_ADC2 || AT32_ADC_USE_ADC3 || \ + defined(__DOXYGEN__) +/** + * @brief ADC interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_ADC_HANDLER) { + uint32_t sts; + + OSAL_IRQ_PROLOGUE(); + +#if AT32_ADC_USE_ADC1 + sts = ADC1->STS; + ADC1->STS = 0; +#if defined(AT32_ADC_ADC1_IRQ_HOOK) + AT32_ADC_ADC1_IRQ_HOOK +#endif + adc_lld_serve_interrupt(&ADCD1, sts); +#endif /* AT32_ADC_USE_ADC1 */ + +#if AT32_ADC_USE_ADC2 + sts = ADC2->STS; + ADC2->STS = 0; +#if defined(AT32_ADC_ADC2_IRQ_HOOK) + AT32_ADC_ADC2_IRQ_HOOK +#endif + adc_lld_serve_interrupt(&ADCD2, sts); +#endif /* AT32_ADC_USE_ADC2 */ + +#if AT32_ADC_USE_ADC3 + sts = ADC3->STS; + ADC3->STS = 0; +#if defined(AT32_ADC_ADC3_IRQ_HOOK) + AT32_ADC_ADC3_IRQ_HOOK +#endif + adc_lld_serve_interrupt(&ADCD3, sts); +#endif /* AT32_ADC_USE_ADC3 */ + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level ADC driver initialization. + * + * @notapi + */ +void adc_lld_init(void) { + +#if AT32_ADC_USE_ADC1 + /* Driver initialization.*/ + adcObjectInit(&ADCD1); + ADCD1.adc = ADC1; + ADCD1.dmastp = NULL; + ADCD1.dmamode = AT32_DMA_CTRL_CHSEL(ADC1_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_ADC_ADC1_DMA_PRIORITY) | + AT32_DMA_CTRL_DTD_P2M | + AT32_DMA_CTRL_MWIDTH_HWORD | AT32_DMA_CTRL_PWIDTH_HWORD | + AT32_DMA_CTRL_MINCM | AT32_DMA_CTRL_FDTIEN | + AT32_DMA_CTRL_DMERRIEN | AT32_DMA_CTRL_DTERRIEN; + crmEnableADC1(true); + ADC1->CTRL1 = 0; + ADC1->CTRL2 = ADC_CTRL2_ADCEN; + + /* Reset calibration just to be safe.*/ + ADC1->CTRL2 = ADC_CTRL2_ADCEN | ADC_CTRL2_ADCALINIT; + while ((ADC1->CTRL2 & ADC_CTRL2_ADCALINIT) != 0); + + /* Calibration.*/ + ADC1->CTRL2 = ADC_CTRL2_ADCEN | ADC_CTRL2_ADCAL; + while ((ADC1->CTRL2 & ADC_CTRL2_ADCAL) != 0); + + /* Return the ADC in low power mode.*/ + ADC1->CTRL2 = 0; + crmDisableADC1(); +#endif + +#if AT32_ADC_USE_ADC2 + /* Driver initialization.*/ + adcObjectInit(&ADCD2); + ADCD2.adc = ADC2; + ADCD2.dmastp = NULL; + ADCD2.dmamode = AT32_DMA_CTRL_CHSEL(ADC2_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_ADC_ADC2_DMA_PRIORITY) | + AT32_DMA_CTRL_DTD_P2M | + AT32_DMA_CTRL_MWIDTH_HWORD | AT32_DMA_CTRL_PWIDTH_HWORD | + AT32_DMA_CTRL_MINCM | AT32_DMA_CTRL_FDTIEN | + AT32_DMA_CTRL_DMERRIEN | AT32_DMA_CTRL_DTERRIEN; + crmEnableADC2(true); + ADC2->CTRL1 = 0; + ADC2->CTRL2 = ADC_CTRL2_ADCEN; + + /* Reset calibration just to be safe.*/ + ADC2->CTRL2 = ADC_CTRL2_ADCEN | ADC_CTRL2_ADCALINIT; + while ((ADC2->CTRL2 & ADC_CTRL2_ADCALINIT) != 0); + + /* Calibration.*/ + ADC2->CTRL2 = ADC_CTRL2_ADCEN | ADC_CTRL2_ADCAL; + while ((ADC2->CTRL2 & ADC_CTRL2_ADCAL) != 0); + + /* Return the ADC in low power mode.*/ + ADC2->CTRL2 = 0; + crmDisableADC2(); +#endif + +#if AT32_ADC_USE_ADC3 + /* Driver initialization.*/ + adcObjectInit(&ADCD3); + ADCD3.adc = ADC3; + ADCD3.dmastp = NULL; + ADCD3.dmamode = AT32_DMA_CTRL_CHSEL(ADC3_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_ADC_ADC3_DMA_PRIORITY) | + AT32_DMA_CTRL_DTD_P2M | + AT32_DMA_CTRL_MWIDTH_HWORD | AT32_DMA_CTRL_PWIDTH_HWORD | + AT32_DMA_CTRL_MINCM | AT32_DMA_CTRL_FDTIEN | + AT32_DMA_CTRL_DMERRIEN | AT32_DMA_CTRL_DTERRIEN; + crmEnableADC3(true); + ADC3->CTRL1 = 0; + ADC3->CTRL2 = ADC_CTRL2_ADCEN; + + /* Reset calibration just to be safe.*/ + ADC3->CTRL2 = ADC_CTRL2_ADCEN | ADC_CTRL2_ADCALINIT; + while ((ADC3->CTRL2 & ADC_CTRL2_ADCALINIT) != 0); + + /* Calibration.*/ + ADC3->CTRL2 = ADC_CTRL2_ADCEN | ADC_CTRL2_ADCAL; + while ((ADC3->CTRL2 & ADC_CTRL2_ADCAL) != 0); + + /* Return the ADC in low power mode.*/ + ADC3->CTRL2 = 0; + crmDisableADC3(); +#endif + + /* The shared vector is initialized on driver initialization and never + disabled because sharing.*/ + nvicEnableVector(AT32_ADC_NUMBER, AT32_ADC_IRQ_PRIORITY); +} + +/** + * @brief Configures and activates the ADC peripheral. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_start(ADCDriver *adcp) { + + /* If in stopped state then enables the ADC and DMA clocks.*/ + if (adcp->state == ADC_STOP) { +#if AT32_ADC_USE_ADC1 + if (&ADCD1 == adcp) { + adcp->dmastp = dmaStreamAllocI(AT32_ADC_ADC1_DMA_STREAM, + AT32_ADC_ADC1_DMA_IRQ_PRIORITY, + (at32_dmasts_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC1->ODT); +#if AT32_USE_DMA_V1 && AT32_DMA_USE_DMAMUX + dmaSetRequestSource(adcp->dmastp, AT32_ADC_ADC1_DMAMUX_CHANNEL, AT32_DMAMUX_ADC1); +#elif AT32_USE_DMA_V2 || AT32_USE_DMA_V3 + dmaSetRequestSource(adcp->dmastp, AT32_DMAMUX_ADC1); +#endif + crmEnableADC1(true); + } +#endif /* AT32_ADC_USE_ADC1 */ + +#if AT32_ADC_USE_ADC2 + if (&ADCD2 == adcp) { + adcp->dmastp = dmaStreamAllocI(AT32_ADC_ADC2_DMA_STREAM, + AT32_ADC_ADC2_DMA_IRQ_PRIORITY, + (at32_dmasts_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC2->ODT); +#if AT32_USE_DMA_V1 && AT32_DMA_USE_DMAMUX + dmaSetRequestSource(adcp->dmastp, AT32_ADC_ADC2_DMAMUX_CHANNEL, AT32_DMAMUX_ADC2); +#elif AT32_USE_DMA_V2 || AT32_USE_DMA_V3 + dmaSetRequestSource(adcp->dmastp, AT32_DMAMUX_ADC2); +#endif + crmEnableADC2(true); + } +#endif /* AT32_ADC_USE_ADC2 */ + +#if AT32_ADC_USE_ADC3 + if (&ADCD3 == adcp) { + adcp->dmastp = dmaStreamAllocI(AT32_ADC_ADC3_DMA_STREAM, + AT32_ADC_ADC3_DMA_IRQ_PRIORITY, + (at32_dmasts_t)adc_lld_serve_rx_interrupt, + (void *)adcp); + osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream"); + dmaStreamSetPeripheral(adcp->dmastp, &ADC3->ODT); +#if AT32_USE_DMA_V1 && AT32_DMA_USE_DMAMUX + dmaSetRequestSource(adcp->dmastp, AT32_ADC_ADC3_DMAMUX_CHANNEL, AT32_DMAMUX_ADC3); +#elif AT32_USE_DMA_V2 || AT32_USE_DMA_V3 + dmaSetRequestSource(adcp->dmastp, AT32_DMAMUX_ADC3); +#endif + crmEnableADC3(true); + } +#endif /* AT32_ADC_USE_ADC3 */ + + /* This is a common register but apparently it requires that at least one + of the ADCs is clocked in order to allow writing, see bug 3575297.*/ +#if defined(AT32F435_437xx) + ADCCOM->CCTRL = (ADCCOM->CCTRL & (ADC_CCTRL_ITSRVEN | ADC_CCTRL_VBATEN)) | + ((AT32_ADC_ADCDIV - 2) << 16); +#elif defined(AT32F423xx) + ADCCOM->CCTRL = (ADCCOM->CCTRL & ADC_CCTRL_ITSRVEN) | + ((AT32_ADC_ADCDIV - 2) << 16); +#else + adcp->adc->CTRL2 = ADC_CTRL2_ITSRVEN; + ADCCOM->CCTRL = ((AT32_ADC_ADCDIV - 2) << 16); +#endif + + /* ADC initial setup, starting the analog part here in order to reduce + the latency when starting a conversion.*/ + adcp->adc->CTRL1 = 0; +#if defined(AT32F435_437xx) || defined(AT32F423xx) + adcp->adc->CTRL2 = 0; +#endif + adcp->adc->CTRL2 = ADC_CTRL2_ADCEN; + } +} + +/** + * @brief Deactivates the ADC peripheral. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_stop(ADCDriver *adcp) { + + /* If in ready state then disables the ADC clock.*/ + if (adcp->state == ADC_READY) { + + dmaStreamFreeI(adcp->dmastp); + adcp->dmastp = NULL; + + adcp->adc->CTRL1 = 0; + adcp->adc->CTRL2 = 0; + +#if AT32_ADC_USE_ADC1 + if (&ADCD1 == adcp) + crmDisableADC1(); +#endif + +#if AT32_ADC_USE_ADC2 + if (&ADCD2 == adcp) + crmDisableADC2(); +#endif + +#if AT32_ADC_USE_ADC3 + if (&ADCD3 == adcp) + crmDisableADC3(); +#endif + } +} + +/** + * @brief Starts an ADC conversion. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_start_conversion(ADCDriver *adcp) { + uint32_t mode; + uint32_t ctrl2; + const ADCConversionGroup *grpp = adcp->grpp; + + /* DMA setup.*/ + mode = adcp->dmamode; + if (grpp->circular) { + mode |= AT32_DMA_CTRL_LM; + if (adcp->depth > 1) { + /* If circular buffer depth > 1, then the half transfer interrupt + is enabled in order to allow streaming processing.*/ + mode |= AT32_DMA_CTRL_HDTIEN; + } + } + dmaStreamSetMemory0(adcp->dmastp, adcp->samples); + dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels * + (uint32_t)adcp->depth); + dmaStreamSetMode(adcp->dmastp, mode); + dmaStreamEnable(adcp->dmastp); + + /* ADC setup.*/ + adcp->adc->STS = 0; + adcp->adc->SPT1 = grpp->spt1; + adcp->adc->SPT2 = grpp->spt2; + adcp->adc->VMHB = grpp->vmhb; + adcp->adc->VMLB = grpp->vmlb; + adcp->adc->OSQ1 = grpp->osq1 | ADC_OSQ1_NUM_CH(grpp->num_channels); + adcp->adc->OSQ2 = grpp->osq2; + adcp->adc->OSQ3 = grpp->osq3; +#if AT32_ADC_MAX_CHANNELS >= 20 + adcp->adc->SPT3 = grpp->spt3; + adcp->adc->OSQ4 = grpp->osq4; + adcp->adc->OSQ4 = grpp->osq5; + adcp->adc->OSQ4 = grpp->osq6; +#endif + + /* ADC configuration and start.*/ +#if defined(AT32F435_437xx) || defined(AT32F423xx) + adcp->adc->CTRL1 = grpp->ctrl1 | ADC_CTRL1_OCCOIE | ADC_CTRL1_SQEN; + ctrl2 = grpp->ctrl2 | ADC_CTRL2_OCDMAEN | ADC_CTRL2_OCDRCEN | ADC_CTRL2_ADCEN; +#else + adcp->adc->CTRL1 = grpp->ctrl1 | ADC_CTRL1_OCCOIE | ADC_CTRL1_SQEN; + ctrl2 = grpp->ctrl2 | ADC_CTRL2_OCDMAEN | ADC_CTRL2_ADCEN; +#endif + + /* The start method is different dependign if HW or SW triggered, the + start is performed using the method specified in the CTRL2 configuration.*/ + if ((ctrl2 & ADC_CTRL2_OCSWTRG) != 0) { + /* Initializing CTRL2 while keeping ADC_CTRL2_OCSWTRG at zero.*/ + adcp->adc->CTRL2 = (ctrl2 | ADC_CTRL2_RPEN) & ~ADC_CTRL2_OCSWTRG; + + /* Finally enabling ADC_CTRL2_OCSWTRG.*/ + adcp->adc->CTRL2 = (ctrl2 | ADC_CTRL2_RPEN); + } + else + adcp->adc->CTRL2 = ctrl2; +} + +/** + * @brief Stops an ongoing conversion. + * + * @param[in] adcp pointer to the @p ADCDriver object + * + * @notapi + */ +void adc_lld_stop_conversion(ADCDriver *adcp) { + + dmaStreamDisable(adcp->dmastp); + adcp->adc->CTRL1 = 0; + /* Because ticket #822, preserving injected conversions.*/ + adcp->adc->CTRL2 &= ~(ADC_CTRL2_OCSWTRG); + adcp->adc->CTRL2 = ADC_CTRL2_ADCEN; +} + +/** + * @brief Enables the TSVREFE bit. + * @details The TSVREFE bit is required in order to sample the internal + * temperature sensor and internal reference voltage. + * @note This is an AT32-only functionality. + */ +void adcAT32EnableITSRVEN(void) { + +#if defined(AT32F435_437xx) || defined(AT32F423xx) + ADCCOM->CCTRL |= ADC_CCTRL_ITSRVEN; +#else + ADC1->CTRL2 |= ADC_CTRL2_ITSRVEN; +#endif +} + +/** + * @brief Disables the TSVREFE bit. + * @details The TSVREFE bit is required in order to sample the internal + * temperature sensor and internal reference voltage. + * @note This is an AT32-only functionality. + */ +void adcAT32DisableITSRVEN(void) { + +#if defined(AT32F435_437xx) || defined(AT32F423xx) + ADCCOM->CCTRL &= ~ADC_CCTRL_ITSRVEN; +#else + ADC1->CTRL2 &= ~ADC_CTRL2_ITSRVEN; +#endif +} + +/** + * @brief Enables the VBATE bit. + * @details The VBATE bit is required in order to sample the VBAT channel. + * @note This is an AT32-only functionality. + * @note This function is meant to be called after @p adcStart(). + */ +void adcAT32EnableVBATEN(void) { + +#if defined(AT32F435_437xx) + ADCCOM->CCTRL |= ADC_CCTRL_VBATEN; +#endif +} + +/** + * @brief Disables the VBATE bit. + * @details The VBATE bit is required in order to sample the VBAT channel. + * @note This is an AT32-only functionality. + * @note This function is meant to be called after @p adcStart(). + */ +void adcAT32DisableVBATEN(void) { + +#if defined(AT32F435_437xx) + ADCCOM->CCTRL &= ~ADC_CCTRL_VBATEN; +#endif +} + +#endif /* HAL_USE_ADC */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/ADCv2/hal_adc_lld.h b/os/hal/ports/AT32/LLD/ADCv2/hal_adc_lld.h new file mode 100644 index 0000000000..1143ce59a2 --- /dev/null +++ b/os/hal/ports/AT32/LLD/ADCv2/hal_adc_lld.h @@ -0,0 +1,576 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file ADCv2/hal_adc_lld.h + * @brief AT32 ADC subsystem low level driver header. + * + * @addtogroup ADC + * @{ + */ + +#ifndef HAL_ADC_LLD_H +#define HAL_ADC_LLD_H + +#if HAL_USE_ADC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Possible ADC errors mask bits. + * @{ + */ +#define ADC_ERR_DMAFAILURE 1U /**< DMA operations failure. */ +#define ADC_ERR_OVERFLOW 2U /**< ADC overflow condition. */ +#define ADC_ERR_VM 4U /**< Watchdog triggered. */ +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Minimum ADC clock frequency. + */ +#define AT32_ADCCLK_MIN 600000 + +/** + * @brief Maximum ADC clock frequency. + */ +#if !defined(AT32_ADCCLK_MAX) +#if defined(AT32F435_7xx) || defined(AT32F423xx) +#define AT32_ADCCLK_MAX 80000000 +#else +#define AT32_ADCCLK_MAX 28000000 +#endif +#endif +/** @} */ + +/** + * @name Triggers selection + * @{ + */ +#define ADC_CTRL2_OCETE_MASK (3U << 28U) +#define ADC_CTRL2_OCETE_DISABLED (0U << 28U) +#define ADC_CTRL2_OCETE_RISING (1U << 28U) +#define ADC_CTRL2_OCETE_FALLING (2U << 28U) +#define ADC_CTRL2_OCETE_BOTH (3U << 28U) + +#define ADC_CTRL2_OCTESEL_MASK ((15U << 24U) | (1U << 31)) +#define ADC_CTRL2_OCTESEL_SRC(n) (((n) << 24U) | \ + (((n) >> 4) << 31)) +/** @} */ + +/** + * @name Available analog channels nums + * @{ + */ +#if !defined(AT32_ADC_MAX_CHANNELS) +#define AT32_ADC_MAX_CHANNELS 18 +#endif +/** @} */ + +/** + * @name Available analog channels + * @{ + */ +#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */ +#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */ +#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */ +#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */ +#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */ +#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */ +#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */ +#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */ +#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */ +#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */ +#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */ +#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */ +#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */ +#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */ +#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */ +#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */ +#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor. + @note Available onADC1 only. */ +#define ADC_CHANNEL_VINTRV 17 /**< @brief Internal reference. + @note Available onADC1 only. */ +#define ADC_CHANNEL_VBAT 18 /**< @brief VBAT. + @note Available onADC1 only. */ +#define ADC_CHANNEL_IN20 20 /**< @brief External analog input 20. */ +#define ADC_CHANNEL_IN21 21 /**< @brief External analog input 21. */ +#define ADC_CHANNEL_IN22 22 /**< @brief External analog input 22. */ +#define ADC_CHANNEL_IN23 23 /**< @brief External analog input 23. */ +#define ADC_CHANNEL_IN24 24 /**< @brief External analog input 24. */ +#define ADC_CHANNEL_IN25 25 /**< @brief External analog input 25. */ +#define ADC_CHANNEL_IN26 26 /**< @brief External analog input 26. */ +#define ADC_CHANNEL_IN27 27 /**< @brief External analog input 27. */ +/** @} */ + +/** + * @name Sampling rates + * @{ + */ +#if defined(AT32F435_437xx) || defined(AT32F423xx) || defined(__DOXYGEN__) +#define ADC_SAMPLE_2P5 0 /**< @brief 2.5 cycles sampling time. */ +#define ADC_SAMPLE_6P5 1 /**< @brief 6.5 cycles sampling time. */ +#define ADC_SAMPLE_12P5 2 /**< @brief 12.5 cycles sampling time. */ +#define ADC_SAMPLE_24P5 3 /**< @brief 24.5 cycles sampling time. */ +#define ADC_SAMPLE_47P5 4 /**< @brief 47.5 cycles sampling time. */ +#define ADC_SAMPLE_92P5 5 /**< @brief 92.5 cycles sampling time. */ +#define ADC_SAMPLE_247P5 6 /**< @brief 247.5 cycles sampling time. */ +#define ADC_SAMPLE_640P5 7 /**< @brief 640.5 cycles sampling time. */ +#else +#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */ +#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */ +#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */ +#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */ +#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */ +#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */ +#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */ +#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */ +#endif +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief ADC common clock divider. + * @note This setting is influenced by the VDDA voltage and other + * external conditions, please refer to the datasheet for more + * info. + */ +#if !defined(AT32_ADC_ADCDIV) || defined(__DOXYGEN__) +#define AT32_ADC_ADCDIV 16 +#endif + +/** + * @brief ADC1 driver enable switch. + * @details If set to @p TRUE the support for ADC1 is included. + * @note The default is @p TRUE. + */ +#if !defined(AT32_ADC_USE_ADC1) || defined(__DOXYGEN__) +#define AT32_ADC_USE_ADC1 FALSE +#endif + +/** + * @brief ADC2 driver enable switch. + * @details If set to @p TRUE the support for ADC2 is included. + * @note The default is @p TRUE. + */ +#if !defined(AT32_ADC_USE_ADC2) || defined(__DOXYGEN__) +#define AT32_ADC_USE_ADC2 FALSE +#endif + +/** + * @brief ADC3 driver enable switch. + * @details If set to @p TRUE the support for ADC3 is included. + * @note The default is @p TRUE. + */ +#if !defined(AT32_ADC_USE_ADC3) || defined(__DOXYGEN__) +#define AT32_ADC_USE_ADC3 FALSE +#endif + +/** + * @brief DMA stream used for ADC1 operations. + */ +#if !defined(AT32_ADC_ADC1_DMA_STREAM) || defined(__DOXYGEN__) +#define AT32_ADC_ADC1_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#endif + +/** + * @brief DMA stream used for ADC2 operations. + */ +#if !defined(AT32_ADC_ADC2_DMA_STREAM) || defined(__DOXYGEN__) +#define AT32_ADC_ADC2_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#endif + +/** + * @brief DMA stream used for ADC3 operations. + */ +#if !defined(AT32_ADC_ADC3_DMA_STREAM) || defined(__DOXYGEN__) +#define AT32_ADC_ADC3_DMA_STREAM AT32_DMA_STREAM_ID_ANY +#endif + +/** + * @brief ADC1 DMA priority (0..3|lowest..highest). + */ +#if !defined(AT32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_ADC_ADC1_DMA_PRIORITY 2 +#endif + +/** + * @brief ADC2 DMA priority (0..3|lowest..highest). + */ +#if !defined(AT32_ADC_ADC2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_ADC_ADC2_DMA_PRIORITY 2 +#endif + +/** + * @brief ADC3 DMA priority (0..3|lowest..highest). + */ +#if !defined(AT32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_ADC_ADC3_DMA_PRIORITY 2 +#endif + +/** + * @brief ADC interrupt priority level setting. + * @note This setting is shared among ADC1, ADC2 and ADC3 because + * all ADCs share the same vector. + */ +#if !defined(AT32_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_ADC_IRQ_PRIORITY 5 +#endif + +/** + * @brief ADC1 DMA interrupt priority level setting. + */ +#if !defined(AT32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#endif + +/** + * @brief ADC2 DMA interrupt priority level setting. + */ +#if !defined(AT32_ADC_ADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_ADC_ADC2_DMA_IRQ_PRIORITY 5 +#endif + +/** + * @brief ADC3 DMA interrupt priority level setting. + */ +#if !defined(AT32_ADC_ADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_ADC_ADC3_DMA_IRQ_PRIORITY 5 +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks.*/ +#if !defined(AT32_HAS_ADC1) || !defined(AT32_HAS_ADC2) || \ + !defined(AT32_HAS_ADC3) +#error "AT32_HAS_ADCx not defined in registry" +#endif + +#if !AT32_DMA_SUPPORTS_DMAMUX +#if (AT32_ADC_USE_ADC1 && !defined(AT32_ADC1_DMA_MSK)) || \ + (AT32_ADC_USE_ADC2 && !defined(AT32_ADC2_DMA_MSK)) || \ + (AT32_ADC_USE_ADC3 && !defined(AT32_ADC3_DMA_MSK)) +#error "AT32_ADCx_DMA_MSK not defined in registry" +#endif + +#if (AT32_ADC_USE_ADC1 && !defined(AT32_ADC1_DMA_CHN)) || \ + (AT32_ADC_USE_ADC2 && !defined(AT32_ADC2_DMA_CHN)) || \ + (AT32_ADC_USE_ADC3 && !defined(AT32_ADC3_DMA_CHN)) +#error "AT32_ADCx_DMA_CHN not defined in registry" +#endif +#endif /* !AT32_DMA_SUPPORTS_DMAMUX */ + +#if AT32_ADC_USE_ADC1 && !AT32_HAS_ADC1 +#error "ADC1 not present in the selected device" +#endif + +#if AT32_ADC_USE_ADC2 && !AT32_HAS_ADC2 +#error "ADC2 not present in the selected device" +#endif + +#if AT32_ADC_USE_ADC3 && !AT32_HAS_ADC3 +#error "ADC3 not present in the selected device" +#endif + +#if !AT32_ADC_USE_ADC1 && !AT32_ADC_USE_ADC2 && !AT32_ADC_USE_ADC3 +#error "ADC driver activated but no ADC peripheral assigned" +#endif + +#if !AT32_DMA_SUPPORTS_DMAMUX + +/* Check on the validity of the assigned DMA channels.*/ +#if AT32_ADC_USE_ADC1 && \ + !AT32_DMA_IS_VALID_ID(AT32_ADC_ADC1_DMA_STREAM, AT32_ADC1_DMA_MSK) +#error "invalid DMA stream associated to ADC1" +#endif + +#if AT32_ADC_USE_ADC2 && \ + !AT32_DMA_IS_VALID_ID(AT32_ADC_ADC2_DMA_STREAM, AT32_ADC2_DMA_MSK) +#error "invalid DMA stream associated to ADC2" +#endif + +#if AT32_ADC_USE_ADC3 && \ + !AT32_DMA_IS_VALID_ID(AT32_ADC_ADC3_DMA_STREAM, AT32_ADC3_DMA_MSK) +#error "invalid DMA stream associated to ADC3" +#endif + +#endif /* !AT32_DMA_SUPPORTS_DMAMUX */ + +#if !defined(AT32_ADCCLKIN) +#define AT32_ADCCLKIN AT32_HCLK +#endif + +#if (AT32_ADC_ADCDIV >= 2) || (AT32_ADC_ADCDIV <= 17) +#define AT32_ADCCLK (AT32_ADCCLKIN / AT32_ADC_ADCDIV) +#else +#error "invalid AT32_ADC_ADCDIV value specified" +#endif + +#if (AT32_ADCCLK < AT32_ADCCLK_MIN) || (AT32_ADCCLK > AT32_ADCCLK_MAX) || (AT32_ADCCLK > AT32_PCLK2) +#error "AT32_ADCCLK outside acceptable range (AT32_ADCCLK_MIN...AT32_ADCCLK_MAX)" +#endif + +#if !defined(AT32_DMA_REQUIRED) +#define AT32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief ADC sample data type. + */ +typedef uint16_t adcsample_t; + +/** + * @brief Channels number in a conversion group. + */ +typedef uint16_t adc_channels_num_t; + +/** + * @brief Type of an ADC error mask. + */ +typedef uint32_t adcerror_t; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Low level fields of the ADC driver structure. + */ +#define adc_lld_driver_fields \ + /* Pointer to the ADCx registers block.*/ \ + ADC_TypeDef *adc; \ + /* Pointer to associated DMA channel.*/ \ + const at32_dma_stream_t *dmastp; \ + /* DMA mode bit mask.*/ \ + uint32_t dmamode + +/** + * @brief Low level fields of the ADC configuration structure. + */ +#define adc_lld_config_fields \ + /* Dummy configuration, it is not needed.*/ \ + uint32_t dummy + +/** + * @brief Low level fields of the ADC configuration structure. + */ +#if AT32_ADC_MAX_CHANNELS < 20 +#define adc_lld_configuration_group_fields \ + /* ADC CTRL1 register initialization data.*/ \ + uint32_t ctrl1; \ + /* ADC CTRL2 register initialization data.*/ \ + uint32_t ctrl2; \ + /* ADC SPT1 register initialization data.*/ \ + uint32_t spt1; \ + /* ADC SPT2 register initialization data.*/ \ + uint32_t spt2; \ + /* ADC voltage monitoring high boundary.*/ \ + uint16_t vmhb; \ + /* ADC voltage monitoring low boundary.*/ \ + uint16_t vmlb; \ + /* ADC OSQ1 register initialization data.*/ \ + uint32_t osq1; \ + /* ADC OSQ2 register initialization data.*/ \ + uint32_t osq2; \ + /* ADC OSQ3 register initialization data.*/ \ + uint32_t osq3 +#else +#define adc_lld_configuration_group_fields \ + /* ADC CTRL1 register initialization data.*/ \ + uint32_t ctrl1; \ + /* ADC CTRL2 register initialization data.*/ \ + uint32_t ctrl2; \ + /* ADC SPT1 register initialization data.*/ \ + uint32_t spt1; \ + /* ADC SPT2 register initialization data.*/ \ + uint32_t spt2; \ + /* ADC voltage monitoring high boundary.*/ \ + uint16_t vmhb; \ + /* ADC voltage monitoring low boundary.*/ \ + uint16_t vmlb; \ + /* ADC OSQ1 register initialization data.*/ \ + uint32_t osq1; \ + /* ADC OSQ2 register initialization data.*/ \ + uint32_t osq2; \ + /* ADC OSQ3 register initialization data.*/ \ + uint32_t osq3; \ + /* ADC SPT3 register initialization data.*/ \ + uint32_t spt3; \ + /* ADC OSQ4 register initialization data.*/ \ + uint32_t osq4; \ + /* ADC OSQ5 register initialization data.*/ \ + uint32_t osq5; \ + /* ADC OSQ6 register initialization data.*/ \ + uint32_t osq6 +#endif + +/** + * @name Sequences building helper macros + * @{ + */ +/** + * @brief Number of channels in a conversion sequence. + */ +#define ADC_OSQ1_NUM_CH(n) (((n) - 1) << 20) + +#define ADC_OSQ3_OSN1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */ +#define ADC_OSQ3_OSN2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */ +#define ADC_OSQ3_OSN3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */ +#define ADC_OSQ3_OSN4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */ +#define ADC_OSQ3_OSN5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */ +#define ADC_OSQ3_OSN6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */ + +#define ADC_OSQ2_OSN7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */ +#define ADC_OSQ2_OSN8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */ +#define ADC_OSQ2_OSN9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */ +#define ADC_OSQ2_OSN10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/ +#define ADC_OSQ2_OSN11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/ +#define ADC_OSQ2_OSN12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/ + +#define ADC_OSQ1_OSN13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/ +#define ADC_OSQ1_OSN14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/ +#define ADC_OSQ1_OSN15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/ +#define ADC_OSQ1_OSN16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/ + +#define ADC_OSQ4_OSN17_N(n) ((n) << 0) /**< @brief 17th channel in seq.*/ +#define ADC_OSQ4_OSN18_N(n) ((n) << 5) /**< @brief 18th channel in seq.*/ +#define ADC_OSQ4_OSN19_N(n) ((n) << 10) /**< @brief 19th channel in seq.*/ +#define ADC_OSQ4_OSN20_N(n) ((n) << 15) /**< @brief 20th channel in seq.*/ +#define ADC_OSQ4_OSN21_N(n) ((n) << 20) /**< @brief 21th channel in seq.*/ +#define ADC_OSQ4_OSN22_N(n) ((n) << 25) /**< @brief 22th channel in seq.*/ + +#define ADC_OSQ5_OSN23_N(n) ((n) << 0) /**< @brief 23th channel in seq.*/ +#define ADC_OSQ5_OSN24_N(n) ((n) << 5) /**< @brief 24th channel in seq.*/ +#define ADC_OSQ5_OSN25_N(n) ((n) << 10) /**< @brief 25th channel in seq.*/ +#define ADC_OSQ5_OSN26_N(n) ((n) << 15) /**< @brief 26th channel in seq.*/ +#define ADC_OSQ5_OSN27_N(n) ((n) << 20) /**< @brief 27th channel in seq.*/ +#define ADC_OSQ5_OSN28_N(n) ((n) << 25) /**< @brief 28th channel in seq.*/ + +#define ADC_OSQ6_OSN29_N(n) ((n) << 0) /**< @brief 29th channel in seq.*/ +#define ADC_OSQ6_OSN30_N(n) ((n) << 5) /**< @brief 30th channel in seq.*/ +#define ADC_OSQ6_OSN31_N(n) ((n) << 10) /**< @brief 31th channel in seq.*/ +#define ADC_OSQ6_OSN32_N(n) ((n) << 15) /**< @brief 32th channel in seq.*/ +/** @} */ + +/** + * @name Sampling rate settings helper macros + * @{ + */ +#define ADC_SPT2_CSPT0(n) ((n) << 0) /**< @brief AN0 sampling time. */ +#define ADC_SPT2_CSPT1(n) ((n) << 3) /**< @brief AN1 sampling time. */ +#define ADC_SPT2_CSPT2(n) ((n) << 6) /**< @brief AN2 sampling time. */ +#define ADC_SPT2_CSPT3(n) ((n) << 9) /**< @brief AN3 sampling time. */ +#define ADC_SPT2_CSPT4(n) ((n) << 12) /**< @brief AN4 sampling time. */ +#define ADC_SPT2_CSPT5(n) ((n) << 15) /**< @brief AN5 sampling time. */ +#define ADC_SPT2_CSPT6(n) ((n) << 18) /**< @brief AN6 sampling time. */ +#define ADC_SPT2_CSPT7(n) ((n) << 21) /**< @brief AN7 sampling time. */ +#define ADC_SPT2_CSPT8(n) ((n) << 24) /**< @brief AN8 sampling time. */ +#define ADC_SPT2_CSPT9(n) ((n) << 27) /**< @brief AN9 sampling time. */ + +#define ADC_SPT1_CSPT10(n) ((n) << 0) /**< @brief AN10 sampling time. */ +#define ADC_SPT1_CSPT11(n) ((n) << 3) /**< @brief AN11 sampling time. */ +#define ADC_SPT1_CSPT12(n) ((n) << 6) /**< @brief AN12 sampling time. */ +#define ADC_SPT1_CSPT13(n) ((n) << 9) /**< @brief AN13 sampling time. */ +#define ADC_SPT1_CSPT14(n) ((n) << 12) /**< @brief AN14 sampling time. */ +#define ADC_SPT1_CSPT15(n) ((n) << 15) /**< @brief AN15 sampling time. */ +#define ADC_SPT1_CSPT16(n) ((n) << 18) /**< @brief Temperature Sensor + sampling time. */ +#define ADC_SPT1_CSPT17(n) ((n) << 21) /**< @brief Voltage Reference + sampling time. */ +#define ADC_SPT1_CSPT18(n) ((n) << 24) /**< @brief VBAT sampling time. */ + +#define ADC_SPT3_CSPT20(n) ((n) << 0) /**< @brief AN20 sampling time. */ +#define ADC_SPT3_CSPT21(n) ((n) << 3) /**< @brief AN21 sampling time. */ +#define ADC_SPT3_CSPT22(n) ((n) << 6) /**< @brief AN22 sampling time. */ +#define ADC_SPT3_CSPT23(n) ((n) << 9) /**< @brief AN23 sampling time. */ +#define ADC_SPT3_CSPT24(n) ((n) << 12) /**< @brief AN24 sampling time. */ +#define ADC_SPT3_CSPT25(n) ((n) << 15) /**< @brief AN25 sampling time. */ +#define ADC_SPT3_CSPT26(n) ((n) << 18) /**< @brief AN26 sampling time. */ +#define ADC_SPT3_CSPT27(n) ((n) << 21) /**< @brief AN27 sampling time. */ +/** @} */ + +/** + * @name Threshold settings helper macros + * @{ + */ +/** + * @brief High voltage monitoring boundary. + */ +#define ADC_VMHB(n) ((n > ADC_VMHB_HB) ? ADC_VMHB_HB : n) +/** + * @brief Low voltage monitoring boundary. + */ +#define ADC_VMHL(n) ((n > ADC_VMHL_LB) ? ADC_VMHL_LB : n) +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if AT32_ADC_USE_ADC1 && !defined(__DOXYGEN__) +extern ADCDriver ADCD1; +#endif + +#if AT32_ADC_USE_ADC2 && !defined(__DOXYGEN__) +extern ADCDriver ADCD2; +#endif + +#if AT32_ADC_USE_ADC3 && !defined(__DOXYGEN__) +extern ADCDriver ADCD3; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void adc_lld_init(void); + void adc_lld_start(ADCDriver *adcp); + void adc_lld_stop(ADCDriver *adcp); + void adc_lld_start_conversion(ADCDriver *adcp); + void adc_lld_stop_conversion(ADCDriver *adcp); + void adcAT32EnableITSRVEN(void); + void adcAT32DisableITSRVEN(void); + void adcAT32EnableVBATEN(void); + void adcAT32DisableVBATEN(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_ADC */ + +#endif /* HAL_ADC_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/DMAv2/at32_dma.c b/os/hal/ports/AT32/LLD/DMAv2/at32_dma.c new file mode 100644 index 0000000000..99fbb52a3a --- /dev/null +++ b/os/hal/ports/AT32/LLD/DMAv2/at32_dma.c @@ -0,0 +1,823 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file DMAv1/at32_dma.c + * @brief DMA helper driver code. + * + * @addtogroup AT32_DMA + * @details DMA sharing helper driver. In the AT32 the DMA streams are a + * shared resource, this driver allows to allocate and free DMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The DMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * ISRs when allocating streams. + * @{ + */ + +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(AT32_DMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define AT32_DMA1_STREAMS_MASK ((1U << AT32_DMA1_NUM_CHANNELS) - 1U) + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define AT32_DMA2_STREAMS_MASK (((1U << AT32_DMA2_NUM_CHANNELS) - \ + 1U) << AT32_DMA1_NUM_CHANNELS) + +#if AT32_DMA_SUPPORTS_CSELR == TRUE + +#if defined(DMA1_CSELR) +#define __DMA1_CSELR &DMA1_CSELR->CSELR +#else +#define __DMA1_CSELR &DMA1->CSELR +#endif + +#if defined(DMA2_CSELR) +#define __DMA2_CSELR &DMA2_CSELR->CSELR +#else +#define __DMA2_CSELR &DMA2->CSELR +#endif + +#define DMA1_CH1_VARIANT __DMA1_CSELR +#define DMA1_CH2_VARIANT __DMA1_CSELR +#define DMA1_CH3_VARIANT __DMA1_CSELR +#define DMA1_CH4_VARIANT __DMA1_CSELR +#define DMA1_CH5_VARIANT __DMA1_CSELR +#define DMA1_CH6_VARIANT __DMA1_CSELR +#define DMA1_CH7_VARIANT __DMA1_CSELR +#define DMA1_CH8_VARIANT __DMA1_CSELR +#define DMA2_CH1_VARIANT __DMA2_CSELR +#define DMA2_CH2_VARIANT __DMA2_CSELR +#define DMA2_CH3_VARIANT __DMA2_CSELR +#define DMA2_CH4_VARIANT __DMA2_CSELR +#define DMA2_CH5_VARIANT __DMA2_CSELR +#define DMA2_CH6_VARIANT __DMA2_CSELR +#define DMA2_CH7_VARIANT __DMA2_CSELR +#define DMA2_CH8_VARIANT __DMA2_CSELR + +#elif AT32_DMA_SUPPORTS_DMAMUX == TRUE + +#define DMA1MUX_CHANNEL(id) (DMA1MUX_BASE + ((id) * 4U)) +#define DMA2MUX_CHANNEL(id) (DMA2MUX_BASE + ((id) * 4U)) + +#define DMA1_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMA1MUX_CHANNEL(0)) +#define DMA1_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMA1MUX_CHANNEL(1)) +#define DMA1_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMA1MUX_CHANNEL(2)) +#define DMA1_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMA1MUX_CHANNEL(3)) +#define DMA1_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMA1MUX_CHANNEL(4)) +#define DMA1_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMA1MUX_CHANNEL(5)) +#define DMA1_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMA1MUX_CHANNEL(6)) +#define DMA1_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMA1MUX_CHANNEL(7)) +#define DMA2_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMA2MUX_CHANNEL(0)) +#define DMA2_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMA2MUX_CHANNEL(1)) +#define DMA2_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMA2MUX_CHANNEL(2)) +#define DMA2_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMA2MUX_CHANNEL(3)) +#define DMA2_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMA2MUX_CHANNEL(4)) +#define DMA2_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMA2MUX_CHANNEL(5)) +#define DMA2_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMA2MUX_CHANNEL(6)) +#define DMA2_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMA2MUX_CHANNEL(7)) + +#else /* !(AT32_DMA_SUPPORTS_DMAMUX == TRUE) */ + +#define DMA1_CH1_VARIANT 0 +#define DMA1_CH2_VARIANT 0 +#define DMA1_CH3_VARIANT 0 +#define DMA1_CH4_VARIANT 0 +#define DMA1_CH5_VARIANT 0 +#define DMA1_CH6_VARIANT 0 +#define DMA1_CH7_VARIANT 0 +#define DMA2_CH1_VARIANT 0 +#define DMA2_CH2_VARIANT 0 +#define DMA2_CH3_VARIANT 0 +#define DMA2_CH4_VARIANT 0 +#define DMA2_CH5_VARIANT 0 +#define DMA2_CH6_VARIANT 0 +#define DMA2_CH7_VARIANT 0 + +#endif + +/* + * Default ISR collision masks. + */ +#if !defined(AT32_DMA1_CH1_CMASK) +#define AT32_DMA1_CH1_CMASK (1U << 0U) +#endif + +#if !defined(AT32_DMA1_CH2_CMASK) +#define AT32_DMA1_CH2_CMASK (1U << 1U) +#endif + +#if !defined(AT32_DMA1_CH3_CMASK) +#define AT32_DMA1_CH3_CMASK (1U << 2U) +#endif + +#if !defined(AT32_DMA1_CH4_CMASK) +#define AT32_DMA1_CH4_CMASK (1U << 3U) +#endif + +#if !defined(AT32_DMA1_CH5_CMASK) +#define AT32_DMA1_CH5_CMASK (1U << 4U) +#endif + +#if !defined(AT32_DMA1_CH6_CMASK) +#define AT32_DMA1_CH6_CMASK (1U << 5U) +#endif + +#if !defined(AT32_DMA1_CH7_CMASK) +#define AT32_DMA1_CH7_CMASK (1U << 6U) +#endif + +#if !defined(AT32_DMA1_CH8_CMASK) +#define AT32_DMA1_CH8_CMASK (1U << 7U) +#endif + +#if !defined(AT32_DMA2_CH1_CMASK) +#define AT32_DMA2_CH1_CMASK (1U << (AT32_DMA1_NUM_CHANNELS + 0U)) +#endif + +#if !defined(AT32_DMA2_CH2_CMASK) +#define AT32_DMA2_CH2_CMASK (1U << (AT32_DMA1_NUM_CHANNELS + 1U)) +#endif + +#if !defined(AT32_DMA2_CH3_CMASK) +#define AT32_DMA2_CH3_CMASK (1U << (AT32_DMA1_NUM_CHANNELS + 2U)) +#endif + +#if !defined(AT32_DMA2_CH4_CMASK) +#define AT32_DMA2_CH4_CMASK (1U << (AT32_DMA1_NUM_CHANNELS + 3U)) +#endif + +#if !defined(AT32_DMA2_CH5_CMASK) +#define AT32_DMA2_CH5_CMASK (1U << (AT32_DMA1_NUM_CHANNELS + 4U)) +#endif + +#if !defined(AT32_DMA2_CH6_CMASK) +#define AT32_DMA2_CH6_CMASK (1U << (AT32_DMA1_NUM_CHANNELS + 5U)) +#endif + +#if !defined(AT32_DMA2_CH7_CMASK) +#define AT32_DMA2_CH7_CMASK (1U << (AT32_DMA1_NUM_CHANNELS + 6U)) +#endif + +#if !defined(AT32_DMA2_CH8_CMASK) +#define AT32_DMA2_CH8_CMASK (1U << (AT32_DMA1_NUM_CHANNELS + 7U)) +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief DMA streams descriptors. + * @details This table keeps the association between an unique stream + * identifier and the involved physical registers. + * @note Don't use this array directly, use the appropriate wrapper macros + * instead: @p AT32_DMA1_STREAM1, @p AT32_DMA1_STREAM2 etc. + */ +const at32_dma_stream_t _at32_dma_streams[AT32_DMA_STREAMS] = { +#if AT32_DMA1_NUM_CHANNELS > 0 + {DMA1, DMA1_CHANNEL1, AT32_DMA1_CH1_CMASK, DMA1_CH1_VARIANT, 0, 0, AT32_DMA1_CH1_NUMBER}, +#endif +#if AT32_DMA1_NUM_CHANNELS > 1 + {DMA1, DMA1_CHANNEL2, AT32_DMA1_CH2_CMASK, DMA1_CH2_VARIANT, 4, 1, AT32_DMA1_CH2_NUMBER}, +#endif +#if AT32_DMA1_NUM_CHANNELS > 2 + {DMA1, DMA1_CHANNEL3, AT32_DMA1_CH3_CMASK, DMA1_CH3_VARIANT, 8, 2, AT32_DMA1_CH3_NUMBER}, +#endif +#if AT32_DMA1_NUM_CHANNELS > 3 + {DMA1, DMA1_CHANNEL4, AT32_DMA1_CH4_CMASK, DMA1_CH4_VARIANT, 12, 3, AT32_DMA1_CH4_NUMBER}, +#endif +#if AT32_DMA1_NUM_CHANNELS > 4 + {DMA1, DMA1_CHANNEL5, AT32_DMA1_CH5_CMASK, DMA1_CH5_VARIANT, 16, 4, AT32_DMA1_CH5_NUMBER}, +#endif +#if AT32_DMA1_NUM_CHANNELS > 5 + {DMA1, DMA1_CHANNEL6, AT32_DMA1_CH6_CMASK, DMA1_CH6_VARIANT, 20, 5, AT32_DMA1_CH6_NUMBER}, +#endif +#if AT32_DMA1_NUM_CHANNELS > 6 + {DMA1, DMA1_CHANNEL7, AT32_DMA1_CH7_CMASK, DMA1_CH7_VARIANT, 24, 6, AT32_DMA1_CH7_NUMBER}, +#endif +#if AT32_DMA1_NUM_CHANNELS > 7 + {DMA1, DMA1_CHANNEL8, AT32_DMA1_CH8_CMASK, DMA1_CH8_VARIANT, 28, 7, AT32_DMA1_CH8_NUMBER}, +#endif +#if AT32_DMA2_NUM_CHANNELS > 0 + {DMA2, DMA2_CHANNEL1, AT32_DMA2_CH1_CMASK, DMA2_CH1_VARIANT, 0, 0 + AT32_DMA1_NUM_CHANNELS, AT32_DMA2_CH1_NUMBER}, +#endif +#if AT32_DMA2_NUM_CHANNELS > 1 + {DMA2, DMA2_CHANNEL2, AT32_DMA2_CH2_CMASK, DMA2_CH2_VARIANT, 4, 1 + AT32_DMA1_NUM_CHANNELS, AT32_DMA2_CH2_NUMBER}, +#endif +#if AT32_DMA2_NUM_CHANNELS > 2 + {DMA2, DMA2_CHANNEL3, AT32_DMA2_CH3_CMASK, DMA2_CH3_VARIANT, 8, 2 + AT32_DMA1_NUM_CHANNELS, AT32_DMA2_CH3_NUMBER}, +#endif +#if AT32_DMA2_NUM_CHANNELS > 3 + {DMA2, DMA2_CHANNEL4, AT32_DMA2_CH4_CMASK, DMA2_CH4_VARIANT, 12, 3 + AT32_DMA1_NUM_CHANNELS, AT32_DMA2_CH4_NUMBER}, +#endif +#if AT32_DMA2_NUM_CHANNELS > 4 + {DMA2, DMA2_CHANNEL5, AT32_DMA2_CH5_CMASK, DMA2_CH5_VARIANT, 16, 4 + AT32_DMA1_NUM_CHANNELS, AT32_DMA2_CH5_NUMBER}, +#endif +#if AT32_DMA2_NUM_CHANNELS > 5 + {DMA2, DMA2_CHANNEL6, AT32_DMA2_CH6_CMASK, DMA2_CH6_VARIANT, 20, 5 + AT32_DMA1_NUM_CHANNELS, AT32_DMA2_CH6_NUMBER}, +#endif +#if AT32_DMA2_NUM_CHANNELS > 6 + {DMA2, DMA2_CHANNEL7, AT32_DMA2_CH7_CMASK, DMA2_CH7_VARIANT, 24, 6 + AT32_DMA1_NUM_CHANNELS, AT32_DMA2_CH7_NUMBER}, +#endif +#if AT32_DMA2_NUM_CHANNELS > 7 + {DMA2, DMA2_CHANNEL8, AT32_DMA2_CH8_CMASK, DMA2_CH8_VARIANT, 28, 7 + AT32_DMA1_NUM_CHANNELS, AT32_DMA2_CH8_NUMBER}, +#endif +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief Global DMA-related data structures. + */ +static struct { + /** + * @brief Mask of the allocated streams. + */ + uint32_t allocated_mask; + /** + * @brief Mask of the enabled streams ISRs. + */ + uint32_t sts_mask; + /** + * @brief DMA IRQ redirectors. + */ + struct { + /** + * @brief DMA callback function. + */ + at32_dmasts_t func; + /** + * @brief DMA callback parameter. + */ + void *param; + } streams[AT32_DMA_STREAMS]; +} dma; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_DMA1_CH1_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 stream 1 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA1_CH1_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA1_STREAM1); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA1_CH2_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 stream 2 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA1_CH2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA1_STREAM2); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA1_CH3_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 stream 3 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA1_CH3_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA1_STREAM3); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA1_CH4_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 stream 4 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA1_CH4_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA1_STREAM4); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA1_CH5_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 stream 5 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA1_CH5_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA1_STREAM5); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA1_CH6_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 stream 6 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA1_CH6_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA1_STREAM6); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA1_CH7_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 stream 7 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA1_CH7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA1_STREAM7); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA1_CH8_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 stream 8 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA1_CH8_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA1_STREAM8); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA2_CH1_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 1 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA2_CH1_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA2_STREAM1); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA2_CH2_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 2 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA2_CH2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA2_STREAM2); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA2_CH3_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 3 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA2_CH3_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA2_STREAM3); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA2_CH4_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 4 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA2_CH4_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA2_STREAM4); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA2_CH5_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 5 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA2_CH5_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA2_STREAM5); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA2_CH6_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 6 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA2_CH6_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA2_STREAM6); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA2_CH7_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 7 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA2_CH7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA2_STREAM7); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if defined(AT32_DMA2_CH8_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 stream 8 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_DMA2_CH8_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + dmaServeInterrupt(AT32_DMA2_STREAM8); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief AT32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + int i; + + dma.allocated_mask = 0U; + dma.sts_mask = 0U; + for (i = 0; i < AT32_DMA_STREAMS; i++) { + _at32_dma_streams[i].channel->CTRL = AT32_DMA_CCTRL_RESET_VALUE; + dma.streams[i].func = NULL; + } + DMA1->CLR = 0xFFFFFFFFU; +#if AT32_DMA2_NUM_CHANNELS > 0 + DMA2->CLR = 0xFFFFFFFFU; +#endif +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * + * @param[in] id numeric identifiers of a specific stream or: + * - @p AT32_DMA_STREAM_ID_ANY for any stream. + * - @p AT32_DMA_STREAM_ID_ANY_DMA1 for any stream + * on DMA1. + * - @p AT32_DMA_STREAM_ID_ANY_DMA2 for any stream + * on DMA2. + * . + * @param[in] priority IRQ priority for the DMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return Pointer to the allocated @p at32_dma_stream_t + * structure. + * @retval NULL if a/the stream is not available. + * + * @iclass + */ +const at32_dma_stream_t *dmaStreamAllocI(uint32_t id, + uint32_t priority, + at32_dmasts_t func, + void *param) { + uint32_t i, startid, endid; + + osalDbgCheckClassI(); + + if (id < AT32_DMA_STREAMS) { + startid = id; + endid = id; + } +#if AT32_DMA_SUPPORTS_DMAMUX == TRUE + else if (id == AT32_DMA_STREAM_ID_ANY) { + startid = 0U; + endid = AT32_DMA_STREAMS - 1U; + } + else if (id == AT32_DMA_STREAM_ID_ANY_DMA1) { + startid = 0U; + endid = AT32_DMA1_NUM_CHANNELS - 1U; + } +#if AT32_DMA2_NUM_CHANNELS > 0 + else if (id == AT32_DMA_STREAM_ID_ANY_DMA2) { + startid = AT32_DMA1_NUM_CHANNELS; + endid = AT32_DMA_STREAMS - 1U; + } +#endif +#endif + else { + osalDbgCheck(false); + return NULL; + } + + for (i = startid; i <= endid; i++) { + uint32_t mask = (1U << i); + if ((dma.allocated_mask & mask) == 0U) { + const at32_dma_stream_t *dmastp = AT32_DMA_STREAM(i); + + /* Installs the DMA handler.*/ + dma.streams[i].func = func; + dma.streams[i].param = param; + dma.allocated_mask |= mask; + + /* Enabling DMA clocks required by the current streams set.*/ + if ((AT32_DMA1_STREAMS_MASK & mask) != 0U) { + crmEnableDMA1(true); + } +#if AT32_DMA2_NUM_CHANNELS > 0 + if ((AT32_DMA2_STREAMS_MASK & mask) != 0U) { + crmEnableDMA2(true); + } +#endif + +#if (AT32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(crmEnableDMAMUX) + /* Enabling DMAMUX if present.*/ + if (dma.allocated_mask != 0U) { + crmEnableDMAMUX(true); + } +#endif +#if AT32_DMA_SUPPORTS_DMAMUX == TRUE + DMA1->MUXSEL = DMA_MUXSEL_TBL_SEL; +#if AT32_DMA2_NUM_CHANNELS > 0 + DMA2->MUXSEL = DMA_MUXSEL_TBL_SEL; +#endif +#endif + /* Enables the associated IRQ vector if not already enabled and if a + callback is defined.*/ + if (func != NULL) { + if ((dma.sts_mask & dmastp->cmask) == 0U) { + nvicEnableVector(dmastp->vector, priority); + } + dma.sts_mask |= mask; + } + + /* Putting the stream in a known state.*/ + dmaStreamDisable(dmastp); + dmastp->channel->CTRL = AT32_DMA_CCTRL_RESET_VALUE; + + return dmastp; + } + } + + return NULL; +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * + * @param[in] id numeric identifiers of a specific stream or: + * - @p AT32_DMA_STREAM_ID_ANY for any stream. + * - @p AT32_DMA_STREAM_ID_ANY_DMA1 for any stream + * on DMA1. + * - @p AT32_DMA_STREAM_ID_ANY_DMA2 for any stream + * on DMA2. + * . + * @param[in] priority IRQ priority for the DMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return Pointer to the allocated @p at32_dma_stream_t + * structure. + * @retval NULL if a/the stream is not available. + * + * @api + */ +const at32_dma_stream_t *dmaStreamAlloc(uint32_t id, + uint32_t priority, + at32_dmasts_t func, + void *param) { + const at32_dma_stream_t *dmastp; + + osalSysLock(); + dmastp = dmaStreamAllocI(id, priority, func, param); + osalSysUnlock(); + + return dmastp; +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * + * @iclass + */ +void dmaStreamFreeI(const at32_dma_stream_t *dmastp) { + uint32_t selfindex = (uint32_t)dmastp->selfindex; + + osalDbgCheck(dmastp != NULL); + + /* Check if the streams is not taken.*/ + osalDbgAssert((dma.allocated_mask & (1 << selfindex)) != 0U, + "not allocated"); + + /* Marks the stream as not allocated.*/ + dma.allocated_mask &= ~(1U << selfindex); + dma.sts_mask &= ~(1U << selfindex); + + /* Disables the associated IRQ vector if it is no more in use.*/ + if ((dma.sts_mask & dmastp->cmask) == 0U) { + nvicDisableVector(dmastp->vector); + } + + /* Removes the DMA handler.*/ + dma.streams[selfindex].func = NULL; + dma.streams[selfindex].param = NULL; + + /* Shutting down clocks that are no more required, if any.*/ + if ((dma.allocated_mask & AT32_DMA1_STREAMS_MASK) == 0U) { + crmDisableDMA1(); + } +#if AT32_DMA2_NUM_CHANNELS > 0 + if ((dma.allocated_mask & AT32_DMA2_STREAMS_MASK) == 0U) { + crmDisableDMA2(); + } +#endif + +#if (AT32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(crmDisableDMAMUX) + /* Shutting down DMAMUX if present.*/ + if (dma.allocated_mask == 0U) { + crmDisableDMAMUX(); + } +#endif +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * + * @api + */ +void dmaStreamFree(const at32_dma_stream_t *dmastp) { + + osalSysLock(); + dmaStreamFreeI(dmastp); + osalSysUnlock(); +} + +/** + * @brief Serves a DMA IRQ. + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * + * @special + */ +void dmaServeInterrupt(const at32_dma_stream_t *dmastp) { + uint32_t flags; + uint32_t selfindex = (uint32_t)dmastp->selfindex; + + flags = (dmastp->dma->STS >> dmastp->shift) & AT32_DMA_STS_MASK; + if (flags & dmastp->channel->CTRL) { + dmastp->dma->CLR = flags << dmastp->shift; + if (dma.streams[selfindex].func) { + dma.streams[selfindex].func(dma.streams[selfindex].param, flags); + } + } +} + +#if (AT32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__) +/** + * @brief Associates a peripheral request to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a @p at32_dma_stream_t structure + * @param[in] per peripheral identifier + * + * @special + */ +void dmaSetRequestSource(const at32_dma_stream_t *dmastp, uint32_t per) { + + osalDbgCheck(per < 128U); + + dmastp->mux->MUXCTRL = per; +} +#endif + +#endif /* AT32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/DMAv2/at32_dma.h b/os/hal/ports/AT32/LLD/DMAv2/at32_dma.h new file mode 100644 index 0000000000..a695edf645 --- /dev/null +++ b/os/hal/ports/AT32/LLD/DMAv2/at32_dma.h @@ -0,0 +1,585 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file DMAv2/at32_dma.h + * @brief DMA helper driver header. + * @note This driver uses the new naming convention used for the AT32F4xx + * so the "DMA channels" are referred as "DMA streams". + * + * @addtogroup AT32_DMA + * @{ + */ + +#ifndef AT32_DMA_H +#define AT32_DMA_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Requires use of DMAv2 driver model. + */ +#define AT32_USE_DMA_V2 TRUE + +/** + * @brief DMA capability. + * @details if @p TRUE then the DMA is able of burst transfers, FIFOs, + * scatter gather and other advanced features. + */ +#define AT32_DMA_ADVANCED FALSE + +/** + * @brief Total number of DMA streams. + * @details This is the total number of streams among all the DMA units. + */ +#define AT32_DMA_STREAMS (AT32_DMA1_NUM_CHANNELS + \ + AT32_DMA2_NUM_CHANNELS) + +/** + * @brief Mask of the ISR bits passed to the DMA callback functions. + */ +#define AT32_DMA_STS_MASK 0x0E + +/** + * @brief Returns the request line associated to the specified stream. + * @note In some AT32 manuals the request line is named confusingly + * channel. + * + * @param[in] id the unique numeric stream identifier + * @param[in] c a stream/request association word, one request per + * nibble + * @return Returns the request associated to the stream. + */ +#define AT32_DMA_GETCHANNEL(id, c) \ + (((uint32_t)(c) >> (((uint32_t)(id) % (uint32_t)AT32_DMA1_NUM_CHANNELS) * 4U)) & 15U) + +/** + * @brief Checks if a DMA priority is within the valid range. + * @param[in] prio DMA priority + * + * @retval The check result. + * @retval false invalid DMA priority. + * @retval true correct DMA priority. + */ +#define AT32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U)) + +#if (AT32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(_DOXYGEN__) +/** + * @brief Checks if a DMA stream id is within the valid range. + * + * @param[in] id DMA stream id + * @retval The check result. + * @retval false invalid DMA channel. + * @retval true correct DMA channel. + */ +#define AT32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \ + ((id) < AT32_DMA_STREAMS)) +#else /* AT32_DMA_SUPPORTS_DMAMUX == FALSE */ +#if AT32_DMA2_NUM_CHANNELS > 0 +#define AT32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \ + ((id) <= (AT32_DMA_STREAMS + 2))) +#else +#define AT32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \ + ((id) <= (AT32_DMA_STREAMS + 1))) +#endif +#endif /* AT32_DMA_SUPPORTS_DMAMUX == FALSE */ + +/** + * @brief Returns an unique numeric identifier for a DMA stream. + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return An unique numeric stream identifier. + */ +#define AT32_DMA_STREAM_ID(dma, stream) \ + ((((dma) - 1) * AT32_DMA1_NUM_CHANNELS) + ((stream) - 1)) + +/** + * @brief Returns a DMA stream identifier mask. + * + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return A DMA stream identifier mask. + */ +#define AT32_DMA_STREAM_ID_MSK(dma, stream) \ + (1U << AT32_DMA_STREAM_ID(dma, stream)) + +/** + * @brief Checks if a DMA stream unique identifier belongs to a mask. + * + * @param[in] id the stream numeric identifier + * @param[in] mask the stream numeric identifiers mask + * + * @retval The check result. + * @retval false id does not belong to the mask. + * @retval true id belongs to the mask. + */ +#define AT32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask))) + +#if (AT32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(_DOXYGEN__) +/** + * @name Special stream identifiers + * @{ + */ +#define AT32_DMA_STREAM_ID_ANY AT32_DMA_STREAMS +#define AT32_DMA_STREAM_ID_ANY_DMA1 (AT32_DMA_STREAM_ID_ANY + 1) +#if AT32_DMA2_NUM_CHANNELS > 0 +#define AT32_DMA_STREAM_ID_ANY_DMA2 (AT32_DMA_STREAM_ID_ANY_DMA1 + 1) +#endif +/** @} */ +#endif + +/** + * @name DMA streams identifiers + * @{ + */ +/** + * @brief Returns a pointer to a at32_dma_stream_t structure. + * + * @param[in] id the stream numeric identifier + * @return A pointer to the at32_dma_stream_t constant structure + * associated to the DMA stream. + */ +#define AT32_DMA_STREAM(id) (&_at32_dma_streams[id]) + +#if AT32_DMA1_NUM_CHANNELS > 0 +#define AT32_DMA1_STREAM1 AT32_DMA_STREAM(0) +#endif +#if AT32_DMA1_NUM_CHANNELS > 1 +#define AT32_DMA1_STREAM2 AT32_DMA_STREAM(1) +#endif +#if AT32_DMA1_NUM_CHANNELS > 2 +#define AT32_DMA1_STREAM3 AT32_DMA_STREAM(2) +#endif +#if AT32_DMA1_NUM_CHANNELS > 3 +#define AT32_DMA1_STREAM4 AT32_DMA_STREAM(3) +#endif +#if AT32_DMA1_NUM_CHANNELS > 4 +#define AT32_DMA1_STREAM5 AT32_DMA_STREAM(4) +#endif +#if AT32_DMA1_NUM_CHANNELS > 5 +#define AT32_DMA1_STREAM6 AT32_DMA_STREAM(5) +#endif +#if AT32_DMA1_NUM_CHANNELS > 6 +#define AT32_DMA1_STREAM7 AT32_DMA_STREAM(6) +#endif +#if AT32_DMA1_NUM_CHANNELS > 7 +#define AT32_DMA1_STREAM8 AT32_DMA_STREAM(7) +#endif +#if AT32_DMA2_NUM_CHANNELS > 0 +#define AT32_DMA2_STREAM1 AT32_DMA_STREAM(AT32_DMA1_NUM_CHANNELS + 0) +#endif +#if AT32_DMA2_NUM_CHANNELS > 1 +#define AT32_DMA2_STREAM2 AT32_DMA_STREAM(AT32_DMA1_NUM_CHANNELS + 1) +#endif +#if AT32_DMA2_NUM_CHANNELS > 2 +#define AT32_DMA2_STREAM3 AT32_DMA_STREAM(AT32_DMA1_NUM_CHANNELS + 2) +#endif +#if AT32_DMA2_NUM_CHANNELS > 3 +#define AT32_DMA2_STREAM4 AT32_DMA_STREAM(AT32_DMA1_NUM_CHANNELS + 3) +#endif +#if AT32_DMA2_NUM_CHANNELS > 4 +#define AT32_DMA2_STREAM5 AT32_DMA_STREAM(AT32_DMA1_NUM_CHANNELS + 4) +#endif +#if AT32_DMA2_NUM_CHANNELS > 5 +#define AT32_DMA2_STREAM6 AT32_DMA_STREAM(AT32_DMA1_NUM_CHANNELS + 5) +#endif +#if AT32_DMA2_NUM_CHANNELS > 6 +#define AT32_DMA2_STREAM7 AT32_DMA_STREAM(AT32_DMA1_NUM_CHANNELS + 6) +#endif +#if AT32_DMA2_NUM_CHANNELS > 7 +#define AT32_DMA2_STREAM8 AT32_DMA_STREAM(AT32_DMA1_NUM_CHANNELS + 7) +#endif +/** @} */ + +/** + * @name CTRL register constants common to all DMA types + * @{ + */ +#define AT32_DMA_CCTRL_RESET_VALUE 0x00000000U +#define AT32_DMA_CTRL_CHEN DMA_CTRL_CHEN +#define AT32_DMA_CTRL_DTERRIEN DMA_CTRL_DTERRIEN +#define AT32_DMA_CTRL_HDTIEN DMA_CTRL_HDTIEN +#define AT32_DMA_CTRL_FDTIEN DMA_CTRL_FDTIEN +#define AT32_DMA_CTRL_DTD_MASK (DMA_CTRL_DTD | DMA_CTRL_M2M) +#define AT32_DMA_CTRL_DTD_P2M 0U +#define AT32_DMA_CTRL_DTD_M2P DMA_CTRL_DTD +#define AT32_DMA_CTRL_DTD_M2M DMA_CTRL_M2M +#define AT32_DMA_CTRL_LM DMA_CTRL_LM +#define AT32_DMA_CTRL_PINCM DMA_CTRL_PINCM +#define AT32_DMA_CTRL_MINCM DMA_CTRL_MINCM +#define AT32_DMA_CTRL_PWIDTH_MASK DMA_CTRL_PWIDTH +#define AT32_DMA_CTRL_PWIDTH_BYTE 0U +#define AT32_DMA_CTRL_PWIDTH_HWORD DMA_CTRL_PWIDTH_16BITS +#define AT32_DMA_CTRL_PWIDTH_WORD DMA_CTRL_PWIDTH_32BITS +#define AT32_DMA_CTRL_MWIDTH_MASK DMA_CTRL_MWIDTH +#define AT32_DMA_CTRL_MWIDTH_BYTE 0U +#define AT32_DMA_CTRL_MWIDTH_HWORD DMA_CTRL_MWIDTH_16BITS +#define AT32_DMA_CTRL_MWIDTH_WORD DMA_CTRL_MWIDTH_32BITS +#define AT32_DMA_CTRL_WIDTH_MASK (AT32_DMA_CTRL_PWIDTH_MASK | \ + AT32_DMA_CTRL_MWIDTH_MASK) +#define AT32_DMA_CTRL_CHPL_MASK DMA_CTRL_CHPL +#define AT32_DMA_CTRL_CHPL(n) ((n) << 12U) + +#define AT32_DMA_CCTRL_RESET_VALUE 0x00000000U +#define AT32_DMA_CCTRL_CHEN DMA_CTRL_CHEN +#define AT32_DMA_CCTRL_DTERRIEN DMA_CTRL_DTERRIEN +#define AT32_DMA_CCTRL_HDTIEN DMA_CTRL_HDTIEN +#define AT32_DMA_CCTRL_FDTIEN DMA_CTRL_FDTIEN +#define AT32_DMA_CCTRL_DTD_MASK (DMA_CTRL_DTD | DMA_CCTRL_M2M) +#define AT32_DMA_CCTRL_DTD_P2M 0U +#define AT32_DMA_CCTRL_DTD_M2P DMA_CTRL_DTD +#define AT32_DMA_CCTRL_DTD_M2M DMA_CTRL_M2M +#define AT32_DMA_CCTRL_LM DMA_CTRL_LM +#define AT32_DMA_CCTRL_PINCM DMA_CTRL_PINCM +#define AT32_DMA_CCTRL_MINCM DMA_CTRL_MINCM +#define AT32_DMA_CCTRL_PWIDTH_MASK DMA_CTRL_PWIDTH +#define AT32_DMA_CCTRL_PWIDTH_BYTE 0U +#define AT32_DMA_CCTRL_PWIDTH_HWORD DMA_CTRL_PWIDTH_16BITS +#define AT32_DMA_CCTRL_PWIDTH_WORD DMA_CTRL_PWIDTH_32BITS +#define AT32_DMA_CCTRL_MWIDTH_MASK DMA_CCTRL_MWIDTH +#define AT32_DMA_CCTRL_MWIDTH_BYTE 0U +#define AT32_DMA_CCTRL_MWIDTH_HWORD DMA_CTRL_MWIDTH_16BITS +#define AT32_DMA_CCTRL_MWIDTH_WORD DMA_CTRL_MWIDTH_32BITS +#define AT32_DMA_CCTRL_SIZE_MASK (AT32_DMA_CTRL_PWIDTH_MASK | \ + AT32_DMA_CTRL_MWIDTH_MASK) +#define AT32_DMA_CCTRL_CHPL_MASK DMA_CTRL_CHPL +#define AT32_DMA_CCTRL_CHPL(n) ((n) << 12U) +/** @} */ + +/** + * @name Request line selector macro + * @{ + */ +#if AT32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__) +#define AT32_DMA_CTRL_CHSEL_MASK (15U << 16U) +#define AT32_DMA_CTRL_CHSEL(n) ((n) << 16U) +#else +#define AT32_DMA_CTRL_CHSEL_MASK 0U +#define AT32_DMA_CTRL_CHSEL(n) 0U +#endif +/** @} */ + +/** + * @name CTRL register constants only found in enhanced DMA + * @{ + */ +#define AT32_DMA_CTRL_DMERRIEN 0U /**< @brief Ignored by normal DMA. */ +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + * @{ + */ +#define AT32_DMA_STS_FERRF 0U +#define AT32_DMA_STS_DMERRF 0U +#define AT32_DMA_STS_DTERRF (0x1U << 3) +#define AT32_DMA_STS_HDTF (0x1U << 2) +#define AT32_DMA_STS_FDTF (0x1U << 1) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !defined(AT32_DMA_SUPPORTS_DMAMUX) +#error "AT32_DMA_SUPPORTS_DMAMUX not defined in registry" +#endif + +#if !defined(AT32_DMA_SUPPORTS_CSELR) +#error "AT32_DMA_SUPPORTS_CSELR not defined in registry" +#endif + +#if AT32_DMA_SUPPORTS_DMAMUX && AT32_DMA_SUPPORTS_CSELR +#error "AT32_DMA_SUPPORTS_DMAMUX and AT32_DMA_SUPPORTS_CSELR both TRUE" +#endif + +#if !defined(AT32_DMA1_NUM_CHANNELS) +#error "AT32_DMA1_NUM_CHANNELS not defined in registry" +#endif + +#if !defined(AT32_DMA2_NUM_CHANNELS) +#error "AT32_DMA2_NUM_CHANNELS not defined in registry" +#endif + +#if (AT32_DMA1_NUM_CHANNELS < 0) || (AT32_DMA1_NUM_CHANNELS > 8) +#error "unsupported channels configuration" +#endif + +#if (AT32_DMA2_NUM_CHANNELS < 0) || (AT32_DMA2_NUM_CHANNELS > 8) +#error "unsupported channels configuration" +#endif + +#if (AT32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__) +#include "at32_dmamux.h" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a DMA callback. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the STS register, the bits + * are aligned to bit zero + */ +typedef void (*at32_dmasts_t)(void *p, uint32_t flags); + +/** + * @brief AT32 DMA stream descriptor structure. + */ +typedef struct { + DMA_TypeDef *dma; /**< @brief Associated DMA. */ + DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ + uint32_t cmask; /**< @brief Mask of streams sharing + the same ISR. */ +#if (AT32_DMA_SUPPORTS_CSELR == TRUE) || defined(__DOXYGEN__) + volatile uint32_t *cselr; /**< @brief Associated CSELR reg. */ +#elif AT32_DMA_SUPPORTS_DMAMUX == TRUE + DMAMUX_Channel_TypeDef *mux; /**< @brief Associated DMA mux. */ +#else + uint8_t dummy; /**< @brief Filler. */ +#endif + uint8_t shift; /**< @brief Bit offset in STS, CLR + and CSELR registers. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ +} at32_dma_stream_t; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Macro Functions + * @{ + */ +/** + * @brief Associates a peripheral data register to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * @param[in] addr value to be written in the PADDR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->channel->PADDR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * @param[in] addr value to be written in the MADDR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->channel->MADDR = (uint32_t)(addr); \ +} + +/** + * @brief Sets the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * @param[in] size value to be written in the DTCNT register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->channel->DTCNT = (uint32_t)(size); \ +} + +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->DTCNT)) + +/** + * @brief Programs the stream mode settings. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register + * + * @special + */ +#if AT32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__) +#define dmaStreamSetMode(dmastp, mode) { \ + uint32_t cselr = *(dmastp)->cselr; \ + cselr &= ~(0x0000000FU << (dmastp)->shift); \ + cselr |= (((uint32_t)(mode) >> 16U) << (dmastp)->shift); \ + *(dmastp)->cselr = cselr; \ + (dmastp)->channel->CTRL = (uint32_t)(mode); \ +} +#else +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->channel->CTRL = (uint32_t)(mode); \ +} +#endif + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmastp) { \ + (dmastp)->channel->CTRL |= AT32_DMA_CTRL_CHEN; \ +} + +/** + * @brief DMA stream disable. + * @details The function disables the specified stream and then clears any + * pending interrupt. + * @note This function can be invoked in both ISR or thread context. + * @note Interrupts enabling flags are set to zero after this call, see + * bug 3607518. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->channel->CTRL &= ~(AT32_DMA_CTRL_FDTIEN | AT32_DMA_CTRL_HDTIEN | \ + AT32_DMA_CTRL_DTERRIEN | AT32_DMA_CTRL_CHEN); \ + dmaStreamClearInterrupt(dmastp); \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + (dmastp)->dma->CLR = AT32_DMA_STS_MASK << (dmastp)->shift; \ +} + +/** + * @brief Starts a memory to memory operation using the specified stream. + * @note The default transfer data mode is "byte to byte" but it can be + * changed by specifying extra options in the @p mode parameter. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register, this value + * is implicitly ORed with: + * - @p AT32_DMA_CTRL_MINCM + * - @p AT32_DMA_CTRL_PINCM + * - @p AT32_DMA_CTRL_DTD_M2M + * - @p AT32_DMA_CTRL_CHEN + * . + * @param[in] src source address + * @param[in] dst destination address + * @param[in] n number of data units to copy + */ +#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ + dmaStreamSetPeripheral(dmastp, src); \ + dmaStreamSetMemory0(dmastp, dst); \ + dmaStreamSetTransactionSize(dmastp, n); \ + dmaStreamSetMode(dmastp, (mode) | \ + AT32_DMA_CTRL_MINCM | AT32_DMA_CTRL_PINCM | \ + AT32_DMA_CTRL_DTD_M2M | AT32_DMA_CTRL_CHEN); \ +} + +/** + * @brief Polled wait for DMA transfer end. + * @pre The stream must have been allocated using @p dmaStreamAlloc(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a at32_dma_stream_t structure + */ +#define dmaWaitCompletion(dmastp) { \ + while ((dmastp)->channel->DTCNT > 0U) \ + ; \ + dmaStreamDisable(dmastp); \ +} +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern const at32_dma_stream_t _at32_dma_streams[AT32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + const at32_dma_stream_t *dmaStreamAllocI(uint32_t id, + uint32_t priority, + at32_dmasts_t func, + void *param); + const at32_dma_stream_t *dmaStreamAlloc(uint32_t id, + uint32_t priority, + at32_dmasts_t func, + void *param); + void dmaStreamFreeI(const at32_dma_stream_t *dmastp); + void dmaStreamFree(const at32_dma_stream_t *dmastp); + void dmaServeInterrupt(const at32_dma_stream_t *dmastp); +#if AT32_DMA_SUPPORTS_DMAMUX == TRUE + void dmaSetRequestSource(const at32_dma_stream_t *dmastp, uint32_t per); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* AT32_DMA_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/DMAv2/driver.mk b/os/hal/ports/AT32/LLD/DMAv2/driver.mk new file mode 100644 index 0000000000..4f01edf899 --- /dev/null +++ b/os/hal/ports/AT32/LLD/DMAv2/driver.mk @@ -0,0 +1,2 @@ +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/DMAv2/at32_dma.c +PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/DMAv2 diff --git a/os/hal/ports/AT32/LLD/EXINTv1/at32_exint.h b/os/hal/ports/AT32/LLD/EXINTv1/at32_exint.h index 138f14fdbc..95c2e2037d 100644 --- a/os/hal/ports/AT32/LLD/EXINTv1/at32_exint.h +++ b/os/hal/ports/AT32/LLD/EXINTv1/at32_exint.h @@ -112,11 +112,11 @@ typedef uint32_t exintmode_t; * @special */ #define exintGetAndClearGroup1(mask, out) do { \ - uint32_t intsts; \ + uint32_t intsts1; \ \ - intsts = EXINT->INTSTS & (mask); \ - (out) = intsts; \ - EXINT->INTSTS = intsts; \ + intsts1 = EXINT->INTSTS & (mask); \ + (out) = intsts1; \ + EXINT->INTSTS = intsts1; \ } while (false) /*===========================================================================*/ diff --git a/os/hal/ports/AT32/LLD/GPIOv2/at32_gpio.h b/os/hal/ports/AT32/LLD/GPIOv2/at32_gpio.h new file mode 100644 index 0000000000..99f905c661 --- /dev/null +++ b/os/hal/ports/AT32/LLD/GPIOv2/at32_gpio.h @@ -0,0 +1,126 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file GPIOv2/at32_gpio.h + * @brief AT32 GPIO units common header. + * @note This file requires definitions from the AT32 header file. + * + * @addtogroup AT32_GPIOv2 + * @{ + */ + +#ifndef AT32_GPIO_H +#define AT32_GPIO_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/* Discarded definitions from the AT headers, the PAL driver uses its own + definitions in order to have an unified handling for all devices. + Unfortunately the AT headers have no uniform definitions for the same + objects across the various sub-families.*/ +#undef GPIOA +#undef GPIOB +#undef GPIOC +#undef GPIOD +#undef GPIOE +#undef GPIOF +#undef GPIOG +#undef GPIOH +#undef GPIOI +#undef GPIOJ +#undef GPIOK + +/** + * @name GPIO ports definitions + * @{ + */ +#define GPIOA ((at32_gpio_t *)GPIOA_BASE) +#define GPIOB ((at32_gpio_t *)GPIOB_BASE) +#define GPIOC ((at32_gpio_t *)GPIOC_BASE) +#define GPIOD ((at32_gpio_t *)GPIOD_BASE) +#define GPIOE ((at32_gpio_t *)GPIOE_BASE) +#define GPIOF ((at32_gpio_t *)GPIOF_BASE) +#if AT32_HAS_GPIOG +#define GPIOG ((at32_gpio_t *)GPIOG_BASE) +#endif +#if AT32_HAS_GPIOH +#define GPIOH ((at32_gpio_t *)GPIOH_BASE) +#endif +#if AT32_HAS_GPIOI +#define GPIOI ((at32_gpio_t *)GPIOI_BASE) +#endif +#if AT32_HAS_GPIOJ +#define GPIOJ ((at32_gpio_t *)GPIOJ_BASE) +#endif +#if AT32_HAS_GPIOK +#define GPIOK ((at32_gpio_t *)GPIOK_BASE) +#endif +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief AT32 GPIO registers block. + */ +typedef struct { + + volatile uint32_t CFGR; + volatile uint32_t OMODE; + volatile uint32_t ODRVR; + volatile uint32_t PULL; + volatile uint32_t IDT; + volatile uint32_t ODT; + volatile union { + uint32_t W; + struct { + uint16_t set; + uint16_t clear; + } H; + } SCR; + volatile uint32_t WPR; + volatile uint32_t MUXL; + volatile uint32_t MUXH; + volatile uint32_t CLR; + volatile uint32_t TOGR; + volatile uint32_t resvd30[3]; + volatile uint32_t HDRV; +} at32_gpio_t; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#endif /* AT32_GPIO_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/GPIOv2/driver.mk b/os/hal/ports/AT32/LLD/GPIOv2/driver.mk new file mode 100644 index 0000000000..19c2f5d7f5 --- /dev/null +++ b/os/hal/ports/AT32/LLD/GPIOv2/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),) +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/GPIOv2/hal_pal_lld.c +endif +else +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/GPIOv2/hal_pal_lld.c +endif + +PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/GPIOv2 diff --git a/os/hal/ports/AT32/LLD/GPIOv2/hal_pal_lld.c b/os/hal/ports/AT32/LLD/GPIOv2/hal_pal_lld.c new file mode 100644 index 0000000000..7415a5376a --- /dev/null +++ b/os/hal/ports/AT32/LLD/GPIOv2/hal_pal_lld.c @@ -0,0 +1,249 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file GPIOv2/hal_pal_lld.c + * @brief AT32 PAL low level driver code. + * + * @addtogroup PAL + * @{ + */ + +#include "hal.h" + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__) +/** + * @brief Event records for the 16 GPIO EXINT channels. + */ +palevent_t _pal_events[16]; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief PAL driver initialization. + * + * @notapi + */ +void _pal_lld_init(void) { + +#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__) + unsigned i; + + for (i = 0; i < 16; i++) { + _pal_init_event(i); + } +#endif + crmEnableAHB1(AT32_GPIO_EN_MASK, false); +} + +/** + * @brief Pads mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * @note @p PAL_MODE_UNCONNECTED is implemented as push pull at minimum + * speed. + * + * @param[in] port the port identifier + * @param[in] mask the group mask + * @param[in] mode the mode + * + * @notapi + */ +void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + iomode_t mode) { + + uint32_t cfgr = (mode & PAL_AT32_MODE_MASK) >> 0; + uint32_t omode = (mode & PAL_AT32_OMODE_MASK) >> 2; + uint32_t odrvr = (mode & PAL_AT32_ODRV_MASK) >> 3; + uint32_t pull = (mode & PAL_AT32_PULL_MASK) >> 5; + uint32_t muxr = (mode & PAL_AT32_ALTERNATE_MASK) >> 7; + uint32_t hdrv = (mode & PAL_AT32_HDRV_MASK) >> 11; + uint32_t bit = 0; + + while (true) { + if ((mask & 1) != 0) { + uint32_t muxrmask, m1, m2, m4; + + muxrmask = muxr << ((bit & 7) * 4); + m1 = 1 << bit; + m2 = 3 << (bit * 2); + m4 = 15 << ((bit & 7) * 4); + port->OMODE = (port->OMODE & ~m1) | omode; + port->ODRVR = (port->ODRVR & ~m2) | odrvr; + port->PULL = (port->PULL & ~m2) | pull; + port->HDRV = (port->HDRV & ~m1) | hdrv; + if ((mode & PAL_AT32_MODE_MASK) == PAL_AT32_MODE_ALTERNATE) { + /* If going in alternate mode then the alternate number is set + before switching mode in order to avoid glitches.*/ + if (bit < 8) + port->MUXL = (port->MUXL & ~m4) | muxrmask; + else + port->MUXH = (port->MUXH & ~m4) | muxrmask; + port->CFGR = (port->CFGR & ~m2) | cfgr; + } + else { + /* If going into a non-alternate mode then the mode is switched + before setting the alternate mode in order to avoid glitches.*/ + port->CFGR = (port->CFGR & ~m2) | cfgr; + if (bit < 8) + port->MUXL = (port->MUXL & ~m4) | muxrmask; + else + port->MUXH = (port->MUXH & ~m4) | muxrmask; + } + } + mask >>= 1; + if (!mask) + return; + omode <<= 1; + odrvr <<= 2; + pull <<= 2; + cfgr <<= 2; + bit++; + } +} + +#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__) +/** + * @brief Pad event enable. + * @note Programming an unknown or unsupported mode is silently ignored. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * @param[in] mode pad event mode + * + * @notapi + */ +void _pal_lld_enablepadevent(ioportid_t port, + iopadid_t pad, + ioeventmode_t mode) { + + uint32_t padmask, cidx, coff, cmask, portidx; + + /* Enable SCFG clock. */ + crmEnableSCFG(false); + + /* Mask of the pad.*/ + padmask = 1U << (uint32_t)pad; + + /* Multiple channel setting of the same channel not allowed, first disable + it. This is done because on AT32 the same channel cannot be mapped on + multiple ports.*/ + osalDbgAssert(((EXINT->POLCFG1 & padmask) == 0U) && + ((EXINT->POLCFG2 & padmask) == 0U), "channel already in use"); + + /* Port index is obtained assuming that GPIO ports are placed at regular + 0x400 intervals in memory space. So far this is true for all devices.*/ + portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU; + + /* Index and mask of the EXINTC register to be used.*/ + cidx = (uint32_t)pad >> 2U; + coff = ((uint32_t)pad & 3U) * 4U; + cmask = ~(0xFU << coff); + SCFG->EXINTC[cidx] = (SCFG->EXINTC[cidx] & cmask) | (portidx << coff); + + /* Programming edge registers.*/ + if (mode & PAL_EVENT_MODE_RISING_EDGE) + EXINT->POLCFG1 |= padmask; + else + EXINT->POLCFG1 &= ~padmask; + if (mode & PAL_EVENT_MODE_FALLING_EDGE) + EXINT->POLCFG2 |= padmask; + else + EXINT->POLCFG2 &= ~padmask; + + /* Programming interrupt and event registers.*/ + EXINT->INTEN |= padmask; + EXINT->EVTEN &= ~padmask; +} + +/** + * @brief Pad event disable. + * @details This function disables previously programmed event callbacks. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * + * @notapi + */ +void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) { + uint32_t padmask, polcfg1, polcfg2; + + polcfg1 = EXINT->POLCFG1; + polcfg2 = EXINT->POLCFG2; + + /* Mask of the pad.*/ + padmask = 1U << (uint32_t)pad; + + /* If either RTRS1 or POLCFG2 is enabled then the channel is in use.*/ + if (((polcfg1 | polcfg2) & padmask) != 0U) { + uint32_t cidx, coff, cport, portidx; + + /* Port index is obtained assuming that GPIO ports are placed at regular + 0x400 intervals in memory space. So far this is true for all devices.*/ + portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU; + + /* Index and mask of the EXINTC register to be used.*/ + cidx = (uint32_t)pad >> 2U; + coff = ((uint32_t)pad & 3U) * 4U; + cport = (SCFG->EXINTC[cidx] >> coff) & 0xFU; + + osalDbgAssert(cport == portidx, "channel mapped on different port"); + + /* Disabling channel.*/ + EXINT->INTEN &= ~padmask; + EXINT->EVTEN &= ~padmask; + EXINT->POLCFG1 = polcfg1 & ~padmask; + EXINT->POLCFG2 = polcfg2 & ~padmask; + EXINT->INTSTS = padmask; + +#if PAL_USE_CALLBACKS || PAL_USE_WAIT + /* Callback cleared and/or thread reset.*/ + _pal_clear_event(pad); +#endif + } +} +#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */ + +#endif /* HAL_USE_PAL */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/GPIOv2/hal_pal_lld.h b/os/hal/ports/AT32/LLD/GPIOv2/hal_pal_lld.h new file mode 100644 index 0000000000..2194f7cf4f --- /dev/null +++ b/os/hal/ports/AT32/LLD/GPIOv2/hal_pal_lld.h @@ -0,0 +1,525 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file GPIOv2/hal_pal_lld.h + * @brief AT32 PAL low level driver header. + * + * @addtogroup PAL + * @{ + */ + +#ifndef HAL_PAL_LLD_H +#define HAL_PAL_LLD_H + +#include "at32_gpio.h" + +#if HAL_USE_PAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Unsupported modes and specific modes */ +/*===========================================================================*/ + +/* Specifies palInit() without parameter, required until all platforms will + be updated to the new style.*/ +#define PAL_NEW_INIT + +#undef PAL_MODE_RESET +#undef PAL_MODE_UNCONNECTED +#undef PAL_MODE_INPUT +#undef PAL_MODE_INPUT_PULLUP +#undef PAL_MODE_INPUT_PULLDOWN +#undef PAL_MODE_INPUT_ANALOG +#undef PAL_MODE_OUTPUT_PUSHPULL +#undef PAL_MODE_OUTPUT_OPENDRAIN + +/** + * @name AT32-specific I/O mode flags + * @{ + */ +#define PAL_AT32_MODE_MASK (3U << 0U) +#define PAL_AT32_MODE_INPUT (0U << 0U) +#define PAL_AT32_MODE_OUTPUT (1U << 0U) +#define PAL_AT32_MODE_ALTERNATE (2U << 0U) +#define PAL_AT32_MODE_ANALOG (3U << 0U) + +#define PAL_AT32_OMODE_MASK (1U << 2U) +#define PAL_AT32_OMODE_PUSHPULL (0U << 2U) +#define PAL_AT32_OMODE_OPENDRAIN (1U << 2U) + +#define PAL_AT32_ODRV_MASK (3U << 3U) +#define PAL_AT32_ODRV_STRONGER (1U << 3U) +#define PAL_AT32_ODRV_MODERATE (2U << 3U) + +#define PAL_AT32_PULL_MASK (3U << 5U) +#define PAL_AT32_PULL_FLOATING (0U << 5U) +#define PAL_AT32_PULL_PULLUP (1U << 5U) +#define PAL_AT32_PULL_PULLDOWN (2U << 5U) + +#define PAL_AT32_ALTERNATE_MASK (15U << 7U) +#define PAL_AT32_ALTERNATE(n) ((n) << 7U) + +#define PAL_AT32_HDRV_MASK (1U << 11U) +#define PAL_AT32_HDRV_NORMAL (0U << 11U) +#define PAL_AT32_HDRV_HUGE (1U << 11U) + +/** + * @brief Alternate function. + * + * @param[in] n alternate function selector + */ +#define PAL_MODE_ALTERNATE(n) (PAL_AT32_MODE_ALTERNATE | \ + PAL_AT32_ALTERNATE(n)) +/** @} */ + +/** + * @name Standard I/O mode flags + * @{ + */ +/** + * @brief Implemented as input. + */ +#define PAL_MODE_RESET PAL_AT32_MODE_INPUT + +/** + * @brief Implemented as input with pull-up. + */ +#define PAL_MODE_UNCONNECTED PAL_MODE_INPUT_PULLUP + +/** + * @brief Regular input high-Z pad. + */ +#define PAL_MODE_INPUT PAL_AT32_MODE_INPUT + +/** + * @brief Input pad with weak pull up resistor. + */ +#define PAL_MODE_INPUT_PULLUP (PAL_AT32_MODE_INPUT | \ + PAL_AT32_PULL_PULLUP) + +/** + * @brief Input pad with weak pull down resistor. + */ +#define PAL_MODE_INPUT_PULLDOWN (PAL_AT32_MODE_INPUT | \ + PAL_AT32_PULL_PULLDOWN) + +/** + * @brief Analog input mode. + */ +#define PAL_MODE_INPUT_ANALOG PAL_AT32_MODE_ANALOG + +/** + * @brief Push-pull output pad. + */ +#define PAL_MODE_OUTPUT_PUSHPULL (PAL_AT32_MODE_OUTPUT | \ + PAL_AT32_OMODE_PUSHPULL) + +/** + * @brief Open-drain output pad. + */ +#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_AT32_MODE_OUTPUT | \ + PAL_AT32_OMODE_OPENDRAIN) +/** @} */ + +/*===========================================================================*/ +/* I/O Ports Types and constants. */ +/*===========================================================================*/ + +/** + * @name Port related definitions + * @{ + */ +/** + * @brief Width, in bits, of an I/O port. + */ +#define PAL_IOPORTS_WIDTH 16 + +/** + * @brief Whole port mask. + * @details This macro specifies all the valid bits into a port. + */ +#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF) +/** @} */ + +/** + * @name Line handling macros + * @{ + */ +/** + * @brief Forms a line identifier. + * @details A port/pad pair are encoded into an @p ioline_t type. The encoding + * of this type is platform-dependent. + * @note In this driver the pad number is encoded in the lower 4 bits of + * the GPIO address which are guaranteed to be zero. + */ +#define PAL_LINE(port, pad) \ + ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad))) + +/** + * @brief Decodes a port identifier from a line identifier. + */ +#define PAL_PORT(line) \ + ((at32_gpio_t *)(((uint32_t)(line)) & 0xFFFFFFF0U)) + +/** + * @brief Decodes a pad identifier from a line identifier. + */ +#define PAL_PAD(line) \ + ((uint32_t)((uint32_t)(line) & 0x0000000FU)) + +/** + * @brief Value identifying an invalid line. + */ +#define PAL_NOLINE 0U +/** @} */ + +/** + * @brief Type of digital I/O port sized unsigned integer. + */ +typedef uint32_t ioportmask_t; + +/** + * @brief Type of digital I/O modes. + */ +typedef uint32_t iomode_t; + +/** + * @brief Type of an I/O line. + */ +typedef uint32_t ioline_t; + +/** + * @brief Type of an event mode. + */ +typedef uint32_t ioeventmode_t; + +/** + * @brief Type of a port Identifier. + * @details This type can be a scalar or some kind of pointer, do not make + * any assumption about it, use the provided macros when populating + * variables of this type. + */ +typedef at32_gpio_t * ioportid_t; + +/** + * @brief Type of an pad identifier. + */ +typedef uint32_t iopadid_t; + +/*===========================================================================*/ +/* I/O Ports Identifiers. */ +/* The low level driver wraps the definitions already present in the AT32 */ +/* firmware library. */ +/*===========================================================================*/ + +/** + * @brief GPIO port A identifier. + */ +#if AT32_HAS_GPIOA || defined(__DOXYGEN__) +#define IOPORT1 GPIOA +#endif + +/** + * @brief GPIO port B identifier. + */ +#if AT32_HAS_GPIOB || defined(__DOXYGEN__) +#define IOPORT2 GPIOB +#endif + +/** + * @brief GPIO port C identifier. + */ +#if AT32_HAS_GPIOC || defined(__DOXYGEN__) +#define IOPORT3 GPIOC +#endif + +/** + * @brief GPIO port D identifier. + */ +#if AT32_HAS_GPIOD || defined(__DOXYGEN__) +#define IOPORT4 GPIOD +#endif + +/** + * @brief GPIO port E identifier. + */ +#if AT32_HAS_GPIOE || defined(__DOXYGEN__) +#define IOPORT5 GPIOE +#endif + +/** + * @brief GPIO port F identifier. + */ +#if AT32_HAS_GPIOF || defined(__DOXYGEN__) +#define IOPORT6 GPIOF +#endif + +/** + * @brief GPIO port G identifier. + */ +#if AT32_HAS_GPIOG || defined(__DOXYGEN__) +#define IOPORT7 GPIOG +#endif + +/** + * @brief GPIO port H identifier. + */ +#if AT32_HAS_GPIOH || defined(__DOXYGEN__) +#define IOPORT8 GPIOH +#endif + +/** + * @brief GPIO port I identifier. + */ +#if AT32_HAS_GPIOI || defined(__DOXYGEN__) +#define IOPORT9 GPIOI +#endif + +/** + * @brief GPIO port J identifier. + */ +#if AT32_HAS_GPIOJ || defined(__DOXYGEN__) +#define IOPORT10 GPIOJ +#endif + +/** + * @brief GPIO port K identifier. + */ +#if AT32_HAS_GPIOK || defined(__DOXYGEN__) +#define IOPORT11 GPIOK +#endif + +/*===========================================================================*/ +/* Implementation, some of the following macros could be implemented as */ +/* functions, if so please put them in pal_lld.c. */ +/*===========================================================================*/ + +/** + * @brief GPIO ports subsystem initialization. + * + * @notapi + */ +#define pal_lld_init() _pal_lld_init() + +/** + * @brief Reads an I/O port. + * @details This function is implemented by reading the GPIO IDT register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the application + * code. + * + * @param[in] port port identifier + * @return The port bits. + * + * @notapi + */ +#define pal_lld_readport(port) ((ioportmask_t)((port)->IDT)) + +/** + * @brief Reads the output latch. + * @details This function is implemented by reading the GPIO ODT register, the + * implementation has no side effects. + * @note This function is not meant to be invoked directly by the application + * code. + * + * @param[in] port port identifier + * @return The latched logical states. + * + * @notapi + */ +#define pal_lld_readlatch(port) ((ioportmask_t)((port)->ODT)) + +/** + * @brief Writes on a I/O port. + * @details This function is implemented by writing the GPIO ODT register, the + * implementation has no side effects. + * + * @param[in] port port identifier + * @param[in] bits bits to be written on the specified port + * + * @notapi + */ +#define pal_lld_writeport(port, bits) ((port)->ODT = (uint32_t)(bits)) + +/** + * @brief Sets a bits mask on a I/O port. + * @details This function is implemented by writing the GPIO SCR register, the + * implementation has no side effects. + * + * @param[in] port port identifier + * @param[in] bits bits to be ORed on the specified port + * + * @notapi + */ +#define pal_lld_setport(port, bits) ((port)->SCR.H.set = (uint16_t)(bits)) + +/** + * @brief Clears a bits mask on a I/O port. + * @details This function is implemented by writing the GPIO SCR register, the + * implementation has no side effects. + * + * @param[in] port port identifier + * @param[in] bits bits to be cleared on the specified port + * + * @notapi + */ +#define pal_lld_clearport(port, bits) ((port)->SCR.H.clear = (uint16_t)(bits)) + +/** + * @brief Toggles a bits mask on a I/O port. + * @details This function is implemented by writing the GPIO TOGR register, the + * implementation has no side effects. + * + * @param[in] port port identifier + * @param[in] bits bits to be toggled on the specified port + * + * @notapi + */ +#define pal_lld_toggleport(port, bits) ((port)->TOGR = (uint16_t)(bits)) + +/** + * @brief Writes a group of bits. + * @details This function is implemented by writing the GPIO SCR register, the + * implementation has no side effects. + * + * @param[in] port port identifier + * @param[in] mask group mask + * @param[in] offset the group bit offset within the port + * @param[in] bits bits to be written. Values exceeding the group + * width are masked. + * + * @notapi + */ +#define pal_lld_writegroup(port, mask, offset, bits) { \ + uint32_t w = ((~(uint32_t)(bits) & (uint32_t)(mask)) << (16U + (offset))) | \ + ((uint32_t)(bits) & (uint32_t)(mask)) << (offset); \ + (port)->SCR.W = w; \ +} + +/** + * @brief Pads group mode setup. + * @details This function programs a pads group belonging to the same port + * with the specified mode. + * + * @param[in] port port identifier + * @param[in] mask group mask + * @param[in] offset group bit offset within the port + * @param[in] mode group mode + * + * @notapi + */ +#define pal_lld_setgroupmode(port, mask, offset, mode) \ + _pal_lld_setgroupmode(port, mask << offset, mode) + +/** + * @brief Writes a logical state on an output pad. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * @param[in] bit logical value, the value must be @p PAL_LOW or + * @p PAL_HIGH + * + * @notapi + */ +#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit) + +/** + * @brief Pad event enable. + * @note Programming an unknown or unsupported mode is silently ignored. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * @param[in] mode pad event mode + * + * @notapi + */ +#define pal_lld_enablepadevent(port, pad, mode) \ + _pal_lld_enablepadevent(port, pad, mode) + +/** + * @brief Pad event disable. + * @details This function disables previously programmed event callbacks. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * + * @notapi + */ +#define pal_lld_disablepadevent(port, pad) \ + _pal_lld_disablepadevent(port, pad) + +/** + * @brief Returns a PAL event structure associated to a pad. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * + * @notapi + */ +#define pal_lld_get_pad_event(port, pad) \ + &_pal_events[pad]; (void)(port) + +/** + * @brief Returns a PAL event structure associated to a line. + * + * @param[in] line line identifier + * + * @notapi + */ +#define pal_lld_get_line_event(line) \ + &_pal_events[PAL_PAD(line)] + +/** + * @brief Pad event enable check. + * + * @param[in] port port identifier + * @param[in] pad pad number within the port + * @return Pad event status. + * @retval false if the pad event is disabled. + * @retval true if the pad event is enabled. + * + * @notapi + */ +#define pal_lld_ispadeventenabled(port, pad) \ + (bool)((EXINT->INTEN & (1U << (uint32_t)pad)) != 0U) + +#if !defined(__DOXYGEN__) +#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) +extern palevent_t _pal_events[16]; +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void _pal_lld_init(void); + void _pal_lld_setgroupmode(ioportid_t port, + ioportmask_t mask, + iomode_t mode); + void _pal_lld_enablepadevent(ioportid_t port, + iopadid_t pad, + ioeventmode_t mode); + void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_PAL */ + +#endif /* HAL_PAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/I2Cv2/driver.mk b/os/hal/ports/AT32/LLD/I2Cv2/driver.mk new file mode 100644 index 0000000000..ea3344b51c --- /dev/null +++ b/os/hal/ports/AT32/LLD/I2Cv2/driver.mk @@ -0,0 +1,21 @@ +ifeq ($(USE_HAL_I2C_FALLBACK),yes) + # Fallback SW driver. + ifeq ($(USE_SMART_BUILD),yes) + ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) + PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + endif + else + PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + endif + PLATFORMINC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C +else + # Default HW driver. + ifeq ($(USE_SMART_BUILD),yes) + ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) + PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv2/hal_i2c_lld.c + endif + else + PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv2/hal_i2c_lld.c + endif + PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/I2Cv2 +endif diff --git a/os/hal/ports/AT32/LLD/I2Cv2/hal_i2c_lld.c b/os/hal/ports/AT32/LLD/I2Cv2/hal_i2c_lld.c new file mode 100644 index 0000000000..501f9b7d1a --- /dev/null +++ b/os/hal/ports/AT32/LLD/I2Cv2/hal_i2c_lld.c @@ -0,0 +1,1189 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file I2Cv2/hal_i2c_lld.c + * @brief AT32 I2C subsystem low level driver source. + * + * @addtogroup I2C + * @{ + */ + +#include "hal.h" + +#if HAL_USE_I2C || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#if AT32_I2C_USE_DMA == TRUE +#define DMAMODE_COMMON \ + (AT32_DMA_CTRL_PWIDTH_BYTE | AT32_DMA_CTRL_MWIDTH_BYTE | \ + AT32_DMA_CTRL_MINCM | AT32_DMA_CTRL_DMERRIEN | \ + AT32_DMA_CTRL_DTERRIEN | AT32_DMA_CTRL_FDTIEN) + +#define I2C1_RX_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_I2C_I2C1_RX_DMA_STREAM, \ + AT32_I2C1_RX_DMA_CHN) + +#define I2C1_TX_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_I2C_I2C1_TX_DMA_STREAM, \ + AT32_I2C1_TX_DMA_CHN) + +#define I2C2_RX_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_I2C_I2C2_RX_DMA_STREAM, \ + AT32_I2C2_RX_DMA_CHN) + +#define I2C2_TX_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_I2C_I2C2_TX_DMA_STREAM, \ + AT32_I2C2_TX_DMA_CHN) + +#define I2C3_RX_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_I2C_I2C3_RX_DMA_STREAM, \ + AT32_I2C3_RX_DMA_CHN) + +#define I2C3_TX_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_I2C_I2C3_TX_DMA_STREAM, \ + AT32_I2C3_TX_DMA_CHN) + +#define I2C4_RX_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_I2C_I2C4_RX_DMA_STREAM, \ + AT32_I2C4_RX_DMA_CHN) + +#define I2C4_TX_DMA_CHANNEL \ + AT32_DMA_GETCHANNEL(AT32_I2C_I2C4_TX_DMA_STREAM, \ + AT32_I2C4_TX_DMA_CHN) +#endif /* AT32_I2C_USE_DMA == TRUE */ + +#if AT32_I2C_USE_DMA == TRUE +#define i2c_lld_get_rxbytes(i2cp) dmaStreamGetTransactionSize((i2cp)->dmarx) +#define i2c_lld_get_txbytes(i2cp) dmaStreamGetTransactionSize((i2cp)->dmatx) +#else +#define i2c_lld_get_rxbytes(i2cp) (i2cp)->rxbytes +#define i2c_lld_get_txbytes(i2cp) (i2cp)->txbytes +#endif + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +#define I2C_ERROR_MASK \ + ((uint32_t)(I2C_STS_BUSERR | I2C_STS_ARLOST | I2C_STS_OUF | I2C_STS_PECERR | \ + I2C_STS_TMOUT | I2C_STS_ALERTF)) + +#define I2C_INT_MASK \ + ((uint32_t)(I2C_STS_TCRLD | I2C_STS_TDC | I2C_STS_STOPF | I2C_STS_ACKFAILF | \ + I2C_STS_ADDRF | I2C_STS_RDBF | I2C_STS_TDIS)) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief I2C1 driver identifier.*/ +#if AT32_I2C_USE_I2C1 || defined(__DOXYGEN__) +I2CDriver I2CD1; +#endif + +/** @brief I2C2 driver identifier.*/ +#if AT32_I2C_USE_I2C2 || defined(__DOXYGEN__) +I2CDriver I2CD2; +#endif + +/** @brief I2C3 driver identifier.*/ +#if AT32_I2C_USE_I2C3 || defined(__DOXYGEN__) +I2CDriver I2CD3; +#endif + +/** @brief I2C4 driver identifier.*/ +#if AT32_I2C_USE_I2C4 || defined(__DOXYGEN__) +I2CDriver I2CD4; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Slave address setup. + * @note The RW bit is set to zero internally. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] addr slave device address + * + * @notapi + */ +static void i2c_lld_set_address(I2CDriver *i2cp, i2caddr_t addr) { + I2C_TypeDef *dp = i2cp->i2c; + + /* Address alignment depends on the addressing mode selected.*/ + if ((i2cp->config->ctrl2 & I2C_CTRL2_ADDR10) == 0U) + dp->CTRL2 = (uint32_t)addr << 1U; + else + dp->CTRL2 = (uint32_t)addr; +} + +/** + * @brief I2C RX transfer setup. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +static void i2c_lld_setup_rx_transfer(I2CDriver *i2cp) { + I2C_TypeDef *dp = i2cp->i2c; + uint32_t rlden; + size_t n; + + /* The unit can transfer 255 bytes maximum in a single operation.*/ + n = i2c_lld_get_rxbytes(i2cp); + if (n > 255U) { + n = 255U; + rlden = I2C_CTRL2_RLDEN; + } + else { + rlden = 0U; + } + + /* Configures the CTRL2 registers with both the calculated and static + settings.*/ + dp->CTRL2 = (dp->CTRL2 & ~(I2C_CTRL2_CNT_MASK | I2C_CTRL2_RLDEN)) | i2cp->config->ctrl2 | + I2C_CTRL2_DIR | (n << 16U) | rlden; +} + +/** + * @brief I2C TX transfer setup. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +static void i2c_lld_setup_tx_transfer(I2CDriver *i2cp) { + I2C_TypeDef *dp = i2cp->i2c; + uint32_t rlden; + size_t n; + + /* The unit can transfer 255 bytes maximum in a single operation.*/ + n = i2c_lld_get_txbytes(i2cp); + if (n > 255U) { + n = 255U; + rlden = I2C_CTRL2_RLDEN; + } else { + rlden = 0U; + } + + /* Configures the CTRL2 registers with both the calculated and static + settings.*/ + dp->CTRL2 = (dp->CTRL2 & ~(I2C_CTRL2_CNT_MASK | I2C_CTRL2_RLDEN)) | i2cp->config->ctrl2 | + (n << 16U) | rlden; +} + +/** + * @brief Aborts an I2C transaction. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +static void i2c_lld_abort_operation(I2CDriver *i2cp) { + I2C_TypeDef *dp = i2cp->i2c; + + if (dp->CTRL1 & I2C_CTRL1_I2CEN) { + /* Stops the I2C peripheral.*/ + dp->CTRL1 &= ~I2C_CTRL1_I2CEN; + while (dp->CTRL1 & I2C_CTRL1_I2CEN) + dp->CTRL1 &= ~I2C_CTRL1_I2CEN; + dp->CTRL1 |= I2C_CTRL1_I2CEN; + } + +#if AT32_I2C_USE_DMA == TRUE + /* Stops the associated DMA streams.*/ + dmaStreamDisable(i2cp->dmatx); + dmaStreamDisable(i2cp->dmarx); +#else + dp->CTRL1 &= ~(I2C_CTRL1_TDIEN | I2C_CTRL1_RDIEN); +#endif +} + +/** + * @brief I2C shared ISR code. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] sts content of the STS register to be decoded + * + * @notapi + */ +static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t sts) { + I2C_TypeDef *dp = i2cp->i2c; + + /* Special case of a received NACK, the transfer is aborted.*/ + if ((sts & I2C_STS_ACKFAILF) != 0U) { +#if AT32_I2C_USE_DMA == TRUE + /* Stops the associated DMA streams.*/ + dmaStreamDisable(i2cp->dmatx); + dmaStreamDisable(i2cp->dmarx); +#endif + + /* Error flag.*/ + i2cp->errors |= I2C_ACK_FAILURE; + + /* Transaction finished sending the STOP.*/ + dp->CTRL2 |= I2C_CTRL2_GENSTOP; + + /* Make sure no more interrupts.*/ + dp->CTRL1 &= ~(I2C_CTRL1_TDCIEN | I2C_CTRL1_TDIEN | I2C_CTRL1_RDIEN); + + /* Errors are signaled to the upper layer.*/ + _i2c_wakeup_error_isr(i2cp); + + return; + } + +#if AT32_I2C_USE_DMA == FALSE + /* Handling of data transfer if the DMA mode is disabled.*/ + { + uint32_t ctrl1 = dp->CTRL1; + + if (i2cp->state == I2C_ACTIVE_TX) { + /* Transmission phase.*/ + if (((ctrl1 & I2C_CTRL1_TDIEN) != 0U) && ((sts & I2C_STS_TDIS) != 0U)) { + dp->TXDT = (uint32_t)*i2cp->txptr; + i2cp->txptr++; + i2cp->txbytes--; + if (i2cp->txbytes == 0U) { + dp->CTRL1 &= ~I2C_CTRL1_TDIEN; + } + } + } + else { + /* Receive phase.*/ + if (((ctrl1 & I2C_CTRL1_RDIEN) != 0U) && ((sts & I2C_STS_RDBF) != 0U)) { + *i2cp->rxptr = (uint8_t)dp->RXDT; + i2cp->rxptr++; + i2cp->rxbytes--; + if (i2cp->rxbytes == 0U) { + dp->CTRL1 &= ~I2C_CTRL1_RDIEN; + } + } + } + } +#endif + + /* Partial transfer handling, restarting the transfer and returning.*/ + if ((sts & I2C_STS_TCRLD) != 0U) { + if (i2cp->state == I2C_ACTIVE_TX) { + i2c_lld_setup_tx_transfer(i2cp); + } + else { + i2c_lld_setup_rx_transfer(i2cp); + } + return; + } + + /* The following condition is true if a transfer phase has been completed.*/ + if ((sts & I2C_STS_TDC) != 0U) { + if (i2cp->state == I2C_ACTIVE_TX) { + /* End of the transmit phase.*/ + +#if AT32_I2C_USE_DMA == TRUE + /* Disabling TX DMA channel.*/ + dmaStreamDisable(i2cp->dmatx); +#endif + + /* Starting receive phase if necessary.*/ + if (i2c_lld_get_rxbytes(i2cp) > 0U) { + /* Setting up the peripheral.*/ + i2c_lld_setup_rx_transfer(i2cp); + +#if AT32_I2C_USE_DMA == TRUE + /* Enabling RX DMA.*/ + dmaStreamEnable(i2cp->dmarx); +#else + /* RX interrupt enabled.*/ + dp->CTRL1 |= I2C_CTRL1_RDIEN; +#endif + + /* Starts the read operation.*/ + dp->CTRL2 |= I2C_CTRL2_GENSTART; + + /* State change.*/ + i2cp->state = I2C_ACTIVE_RX; + + /* Note, returning because the transaction is not over yet.*/ + return; + } + } + else { + /* End of the receive phase.*/ +#if AT32_I2C_USE_DMA == TRUE + /* Disabling RX DMA channel.*/ + dmaStreamDisable(i2cp->dmarx); +#endif + } + + /* Transaction finished sending the STOP.*/ + dp->CTRL2 |= I2C_CTRL2_GENSTOP; + + /* Make sure no more 'Transfer Complete' interrupts.*/ + dp->CTRL1 &= ~I2C_CTRL1_TDCIEN; + + /* Normal transaction end.*/ + _i2c_wakeup_isr(i2cp); + } +} + +/** + * @brief I2C error handler. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] sts content of the STS register to be decoded + * + * @notapi + */ +static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint32_t sts) { + +#if AT32_I2C_USE_DMA == TRUE + /* Clears DMA interrupt flags just to be safe.*/ + dmaStreamDisable(i2cp->dmatx); + dmaStreamDisable(i2cp->dmarx); +#else + /* Disabling RX and TX interrupts.*/ + i2cp->i2c->CTRL1 &= ~(I2C_CTRL1_TDIEN | I2C_CTRL1_RDIEN); +#endif + + if (sts & I2C_STS_BUSERR) + i2cp->errors |= I2C_BUS_ERROR; + + if (sts & I2C_STS_ARLOST) + i2cp->errors |= I2C_ARBITRATION_LOST; + + if (sts & I2C_STS_OUF) + i2cp->errors |= I2C_OVERRUN; + + if (sts & I2C_STS_TMOUT) + i2cp->errors |= I2C_TIMEOUT; + + /* If some error has been identified then sends wakes the waiting thread.*/ + if (i2cp->errors != I2C_NO_ERROR) + _i2c_wakeup_error_isr(i2cp); +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if AT32_I2C_USE_I2C1 || defined(__DOXYGEN__) +#if defined(AT32_I2C1_GLOBAL_HANDLER) || defined(__DOXYGEN__) +/** + * @brief I2C1 event interrupt handler. + * + * @notapi + */ +OSAL_IRQ_HANDLER(AT32_I2C1_GLOBAL_HANDLER) { + uint32_t sts = I2CD1.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD1.i2c->CLR = sts; + + if (sts & I2C_ERROR_MASK) + i2c_lld_serve_error_interrupt(&I2CD1, sts); + else if (sts & I2C_INT_MASK) + i2c_lld_serve_interrupt(&I2CD1, sts); + + OSAL_IRQ_EPILOGUE(); +} + +#elif defined(AT32_I2C1_EVENT_HANDLER) && defined(AT32_I2C1_ERROR_HANDLER) +OSAL_IRQ_HANDLER(AT32_I2C1_EVENT_HANDLER) { + uint32_t sts = I2CD1.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD1.i2c->CLR = sts & I2C_INT_MASK; + + i2c_lld_serve_interrupt(&I2CD1, sts); + + OSAL_IRQ_EPILOGUE(); +} + +OSAL_IRQ_HANDLER(AT32_I2C1_ERROR_HANDLER) { + uint32_t sts = I2CD1.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD1.i2c->CLR = sts & I2C_ERROR_MASK; + + i2c_lld_serve_error_interrupt(&I2CD1, sts); + + OSAL_IRQ_EPILOGUE(); +} + +#else +#error "I2C1 interrupt handlers not defined" +#endif +#endif /* AT32_I2C_USE_I2C1 */ + +#if AT32_I2C_USE_I2C2 || defined(__DOXYGEN__) +#if defined(AT32_I2C2_GLOBAL_HANDLER) || defined(__DOXYGEN__) +/** + * @brief I2C2 event interrupt handler. + * + * @notapi + */ +OSAL_IRQ_HANDLER(AT32_I2C2_GLOBAL_HANDLER) { + uint32_t sts = I2CD2.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD2.i2c->CLR = sts; + + if (sts & I2C_ERROR_MASK) + i2c_lld_serve_error_interrupt(&I2CD2, sts); + else if (sts & I2C_INT_MASK) + i2c_lld_serve_interrupt(&I2CD2, sts); + + OSAL_IRQ_EPILOGUE(); +} + +#elif defined(AT32_I2C2_EVENT_HANDLER) && defined(AT32_I2C2_ERROR_HANDLER) +OSAL_IRQ_HANDLER(AT32_I2C2_EVENT_HANDLER) { + uint32_t sts = I2CD2.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD2.i2c->CLR = sts & I2C_INT_MASK; + + i2c_lld_serve_interrupt(&I2CD2, sts); + + OSAL_IRQ_EPILOGUE(); +} + +OSAL_IRQ_HANDLER(AT32_I2C2_ERROR_HANDLER) { + uint32_t sts = I2CD2.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD2.i2c->CLR = sts & I2C_ERROR_MASK; + + i2c_lld_serve_error_interrupt(&I2CD2, sts); + + OSAL_IRQ_EPILOGUE(); +} + +#else +#error "I2C2 interrupt handlers not defined" +#endif +#endif /* AT32_I2C_USE_I2C2 */ + +#if AT32_I2C_USE_I2C3 || defined(__DOXYGEN__) +#if defined(AT32_I2C3_GLOBAL_HANDLER) || defined(__DOXYGEN__) +/** + * @brief I2C3 event interrupt handler. + * + * @notapi + */ +OSAL_IRQ_HANDLER(AT32_I2C3_GLOBAL_HANDLER) { + uint32_t sts = I2CD3.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD3.i2c->CLR = sts; + + if (sts & I2C_ERROR_MASK) + i2c_lld_serve_error_interrupt(&I2CD3, sts); + else if (sts & I2C_INT_MASK) + i2c_lld_serve_interrupt(&I2CD3, sts); + + OSAL_IRQ_EPILOGUE(); +} + +#elif defined(AT32_I2C3_EVENT_HANDLER) && defined(AT32_I2C3_ERROR_HANDLER) +OSAL_IRQ_HANDLER(AT32_I2C3_EVENT_HANDLER) { + uint32_t sts = I2CD3.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD3.i2c->CLR = sts & I2C_INT_MASK; + + i2c_lld_serve_interrupt(&I2CD3, sts); + + OSAL_IRQ_EPILOGUE(); +} + +OSAL_IRQ_HANDLER(AT32_I2C3_ERROR_HANDLER) { + uint32_t sts = I2CD3.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD3.i2c->CLR = sts & I2C_ERROR_MASK; + + i2c_lld_serve_error_interrupt(&I2CD3, sts); + + OSAL_IRQ_EPILOGUE(); +} + +#else +#error "I2C3 interrupt handlers not defined" +#endif +#endif /* AT32_I2C_USE_I2C3 */ + +#if AT32_I2C_USE_I2C4 || defined(__DOXYGEN__) +#if defined(AT32_I2C4_GLOBAL_HANDLER) || defined(__DOXYGEN__) +/** + * @brief I2C4 event interrupt handler. + * + * @notapi + */ +OSAL_IRQ_HANDLER(AT32_I2C4_GLOBAL_HANDLER) { + uint32_t sts = I2CD4.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD4.i2c->CLR = sts; + + if (sts & I2C_ERROR_MASK) + i2c_lld_serve_error_interrupt(&I2CD4, sts); + else if (sts & I2C_INT_MASK) + i2c_lld_serve_interrupt(&I2CD4, sts); + + OSAL_IRQ_EPILOGUE(); +} + +#elif defined(AT32_I2C4_EVENT_HANDLER) && defined(AT32_I2C4_ERROR_HANDLER) +OSAL_IRQ_HANDLER(AT32_I2C4_EVENT_HANDLER) { + uint32_t sts = I2CD4.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD4.i2c->CLR = sts & I2C_INT_MASK; + + i2c_lld_serve_interrupt(&I2CD4, sts); + + OSAL_IRQ_EPILOGUE(); +} + +OSAL_IRQ_HANDLER(AT32_I2C4_ERROR_HANDLER) { + uint32_t sts = I2CD4.i2c->STS; + + OSAL_IRQ_PROLOGUE(); + + /* Clearing IRQ bits.*/ + I2CD4.i2c->CLR = sts & I2C_ERROR_MASK; + + i2c_lld_serve_error_interrupt(&I2CD4, sts); + + OSAL_IRQ_EPILOGUE(); +} + +#else +#error "I2C4 interrupt handlers not defined" +#endif +#endif /* AT32_I2C_USE_I2C4 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level I2C driver initialization. + * + * @notapi + */ +void i2c_lld_init(void) { + +#if AT32_I2C_USE_I2C1 + i2cObjectInit(&I2CD1); + I2CD1.thread = NULL; + I2CD1.i2c = I2C1; +#if AT32_I2C_USE_DMA == TRUE + I2CD1.dmarx = NULL; + I2CD1.dmatx = NULL; +#endif +#endif /* AT32_I2C_USE_I2C1 */ + +#if AT32_I2C_USE_I2C2 + i2cObjectInit(&I2CD2); + I2CD2.thread = NULL; + I2CD2.i2c = I2C2; +#if AT32_I2C_USE_DMA == TRUE + I2CD2.dmarx = NULL; + I2CD2.dmatx = NULL; +#endif +#endif /* AT32_I2C_USE_I2C2 */ + +#if AT32_I2C_USE_I2C3 + i2cObjectInit(&I2CD3); + I2CD3.thread = NULL; + I2CD3.i2c = I2C3; +#if AT32_I2C_USE_DMA == TRUE + I2CD3.dmarx = NULL; + I2CD3.dmatx = NULL; +#endif +#endif /* AT32_I2C_USE_I2C3 */ + +#if AT32_I2C_USE_I2C4 + i2cObjectInit(&I2CD4); + I2CD4.thread = NULL; + I2CD4.i2c = I2C4; +#if AT32_I2C_USE_DMA == TRUE + I2CD4.dmarx = NULL; + I2CD4.dmatx = NULL; +#endif +#endif /* AT32_I2C_USE_I2C4 */ +} + +/** + * @brief Configures and activates the I2C peripheral. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +void i2c_lld_start(I2CDriver *i2cp) { + I2C_TypeDef *dp = i2cp->i2c; + + /* Make sure I2C peripheral is disabled */ + dp->CTRL1 &= ~I2C_CTRL1_I2CEN; + + /* If in stopped state then enables the I2C and DMA clocks.*/ + if (i2cp->state == I2C_STOP) { + +#if AT32_I2C_USE_DMA == TRUE + /* Common DMA modes.*/ + i2cp->txdmamode = DMAMODE_COMMON | AT32_DMA_CTRL_DTD_M2P; + i2cp->rxdmamode = DMAMODE_COMMON | AT32_DMA_CTRL_DTD_P2M; +#endif + +#if AT32_I2C_USE_I2C1 + if (&I2CD1 == i2cp) { + + crmResetI2C1(); + crmEnableI2C1(true); +#if AT32_I2C_USE_DMA == TRUE + { + i2cp->dmarx = dmaStreamAllocI(AT32_I2C_I2C1_RX_DMA_STREAM, + AT32_I2C_I2C1_IRQ_PRIORITY, + NULL, + (void *)i2cp); + osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream"); + i2cp->dmatx = dmaStreamAllocI(AT32_I2C_I2C1_TX_DMA_STREAM, + AT32_I2C_I2C1_IRQ_PRIORITY, + NULL, + (void *)i2cp); + osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); + + i2cp->rxdmamode |= AT32_DMA_CTRL_CHSEL(I2C1_RX_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_I2C_I2C1_DMA_PRIORITY); + i2cp->txdmamode |= AT32_DMA_CTRL_CHSEL(I2C1_TX_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_I2C_I2C1_DMA_PRIORITY); +#if AT32_DMA_SUPPORTS_DMAMUX +#if AT32_USE_DMA_V1 && AT32_DMA_USE_DMAMUX + dmaSetRequestSource(i2cp->dmarx, AT32_I2C_I2C1_RX_DMAMUX_CHANNEL, AT32_DMAMUX_I2C1_RX); + dmaSetRequestSource(i2cp->dmatx, AT32_I2C_I2C1_TX_DMAMUX_CHANNEL, AT32_DMAMUX_I2C1_TX); +#elif AT32_USE_DMA_V2 || AT32_USE_DMA_V3 + dmaSetRequestSource(i2cp->dmarx, AT32_DMAMUX_I2C1_RX); + dmaSetRequestSource(i2cp->dmatx, AT32_DMAMUX_I2C1_TX); +#endif +#endif + } +#endif /* AT32_I2C_USE_DMA == TRUE */ + +#if defined(AT32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__) + nvicEnableVector(AT32_I2C1_GLOBAL_NUMBER, AT32_I2C_I2C1_IRQ_PRIORITY); +#elif defined(AT32_I2C1_EVENT_NUMBER) && defined(AT32_I2C1_ERROR_NUMBER) + nvicEnableVector(AT32_I2C1_EVENT_NUMBER, AT32_I2C_I2C1_IRQ_PRIORITY); + nvicEnableVector(AT32_I2C1_ERROR_NUMBER, AT32_I2C_I2C1_IRQ_PRIORITY); +#else +#error "I2C1 interrupt numbers not defined" +#endif + } +#endif /* AT32_I2C_USE_I2C1 */ + +#if AT32_I2C_USE_I2C2 + if (&I2CD2 == i2cp) { + + crmResetI2C2(); + crmEnableI2C2(true); +#if AT32_I2C_USE_DMA == TRUE + { + i2cp->dmarx = dmaStreamAllocI(AT32_I2C_I2C2_RX_DMA_STREAM, + AT32_I2C_I2C2_IRQ_PRIORITY, + NULL, + (void *)i2cp); + osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream"); + i2cp->dmatx = dmaStreamAllocI(AT32_I2C_I2C2_TX_DMA_STREAM, + AT32_I2C_I2C2_IRQ_PRIORITY, + NULL, + (void *)i2cp); + osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); + + i2cp->rxdmamode |= AT32_DMA_CTRL_CHSEL(I2C2_RX_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_I2C_I2C2_DMA_PRIORITY); + i2cp->txdmamode |= AT32_DMA_CTRL_CHSEL(I2C2_TX_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_I2C_I2C2_DMA_PRIORITY); +#if AT32_DMA_SUPPORTS_DMAMUX +#if AT32_USE_DMA_V1 && AT32_DMA_USE_DMAMUX + dmaSetRequestSource(i2cp->dmarx, AT32_I2C_I2C2_RX_DMAMUX_CHANNEL, AT32_DMAMUX_I2C2_RX); + dmaSetRequestSource(i2cp->dmatx, AT32_I2C_I2C2_TX_DMAMUX_CHANNEL, AT32_DMAMUX_I2C2_TX); +#elif AT32_USE_DMA_V2 || AT32_USE_DMA_V3 + dmaSetRequestSource(i2cp->dmarx, AT32_DMAMUX_I2C2_RX); + dmaSetRequestSource(i2cp->dmatx, AT32_DMAMUX_I2C2_TX); +#endif +#endif + } +#endif /* AT32_I2C_USE_DMA == TRUE */ + +#if defined(AT32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__) + nvicEnableVector(AT32_I2C2_GLOBAL_NUMBER, AT32_I2C_I2C2_IRQ_PRIORITY); +#elif defined(AT32_I2C2_EVENT_NUMBER) && defined(AT32_I2C2_ERROR_NUMBER) + nvicEnableVector(AT32_I2C2_EVENT_NUMBER, AT32_I2C_I2C2_IRQ_PRIORITY); + nvicEnableVector(AT32_I2C2_ERROR_NUMBER, AT32_I2C_I2C2_IRQ_PRIORITY); +#else +#error "I2C2 interrupt numbers not defined" +#endif + } +#endif /* AT32_I2C_USE_I2C2 */ + +#if AT32_I2C_USE_I2C3 + if (&I2CD3 == i2cp) { + + crmResetI2C3(); + crmEnableI2C3(true); +#if AT32_I2C_USE_DMA == TRUE + { + i2cp->dmarx = dmaStreamAllocI(AT32_I2C_I2C3_RX_DMA_STREAM, + AT32_I2C_I2C3_IRQ_PRIORITY, + NULL, + (void *)i2cp); + osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream"); + i2cp->dmatx = dmaStreamAllocI(AT32_I2C_I2C3_TX_DMA_STREAM, + AT32_I2C_I2C3_IRQ_PRIORITY, + NULL, + (void *)i2cp); + osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); + + i2cp->rxdmamode |= AT32_DMA_CTRL_CHSEL(I2C3_RX_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_I2C_I2C3_DMA_PRIORITY); + i2cp->txdmamode |= AT32_DMA_CTRL_CHSEL(I2C3_TX_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_I2C_I2C3_DMA_PRIORITY); +#if AT32_DMA_SUPPORTS_DMAMUX +#if AT32_USE_DMA_V1 && AT32_DMA_USE_DMAMUX + dmaSetRequestSource(i2cp->dmarx, AT32_I2C_I2C3_RX_DMAMUX_CHANNEL, AT32_DMAMUX_I2C3_RX); + dmaSetRequestSource(i2cp->dmatx, AT32_I2C_I2C3_TX_DMAMUX_CHANNEL, AT32_DMAMUX_I2C3_TX); +#elif AT32_USE_DMA_V2 || AT32_USE_DMA_V3 + dmaSetRequestSource(i2cp->dmarx, AT32_DMAMUX_I2C3_RX); + dmaSetRequestSource(i2cp->dmatx, AT32_DMAMUX_I2C3_TX); +#endif +#endif + } +#endif /* AT32_I2C_USE_DMA == TRUE */ + +#if defined(AT32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__) + nvicEnableVector(AT32_I2C3_GLOBAL_NUMBER, AT32_I2C_I2C3_IRQ_PRIORITY); +#elif defined(AT32_I2C3_EVENT_NUMBER) && defined(AT32_I2C3_ERROR_NUMBER) + nvicEnableVector(AT32_I2C3_EVENT_NUMBER, AT32_I2C_I2C3_IRQ_PRIORITY); + nvicEnableVector(AT32_I2C3_ERROR_NUMBER, AT32_I2C_I2C3_IRQ_PRIORITY); +#else +#error "I2C3 interrupt numbers not defined" +#endif + } +#endif /* AT32_I2C_USE_I2C3 */ + +#if AT32_I2C_USE_I2C4 + if (&I2CD4 == i2cp) { + + crmResetI2C4(); + crmEnableI2C4(true); +#if AT32_I2C_USE_DMA == TRUE + { + i2cp->dmarx = dmaStreamAllocI(AT32_I2C_I2C4_RX_DMA_STREAM, + AT32_I2C_I2C4_IRQ_PRIORITY, + NULL, + (void *)i2cp); + osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream"); + i2cp->dmatx = dmaStreamAllocI(AT32_I2C_I2C4_TX_DMA_STREAM, + AT32_I2C_I2C4_IRQ_PRIORITY, + NULL, + (void *)i2cp); + osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); + + i2cp->rxdmamode |= AT32_DMA_CTRL_CHSEL(I2C4_RX_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_I2C_I2C4_DMA_PRIORITY); + i2cp->txdmamode |= AT32_DMA_CTRL_CHSEL(I2C4_TX_DMA_CHANNEL) | + AT32_DMA_CTRL_CHPL(AT32_I2C_I2C4_DMA_PRIORITY); +#if AT32_DMA_SUPPORTS_DMAMUX +#if AT32_USE_DMA_V1 && AT32_DMA_USE_DMAMUX + dmaSetRequestSource(i2cp->dmarx, AT32_I2C_I2C4_RX_DMAMUX_CHANNEL, AT32_DMAMUX_I2C4_RX); + dmaSetRequestSource(i2cp->dmatx, AT32_I2C_I2C4_TX_DMAMUX_CHANNEL, AT32_DMAMUX_I2C4_TX); +#elif AT32_USE_DMA_V2 || AT32_USE_DMA_V3 + dmaSetRequestSource(i2cp->dmarx, AT32_DMAMUX_I2C4_RX); + dmaSetRequestSource(i2cp->dmatx, AT32_DMAMUX_I2C4_TX); +#endif +#endif + } +#endif /* AT32_I2C_USE_DMA == TRUE */ + +#if defined(AT32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__) + nvicEnableVector(AT32_I2C4_GLOBAL_NUMBER, AT32_I2C_I2C4_IRQ_PRIORITY); +#elif defined(AT32_I2C4_EVENT_NUMBER) && defined(AT32_I2C4_ERROR_NUMBER) + nvicEnableVector(AT32_I2C4_EVENT_NUMBER, AT32_I2C_I2C4_IRQ_PRIORITY); + nvicEnableVector(AT32_I2C4_ERROR_NUMBER, AT32_I2C_I2C4_IRQ_PRIORITY); +#else +#error "I2C4 interrupt numbers not defined" +#endif + } +#endif /* AT32_I2C_USE_I2C4 */ + } + +#if AT32_I2C_USE_DMA == TRUE + /* I2C registers pointed by the DMA.*/ + dmaStreamSetPeripheral(i2cp->dmarx, &dp->RXDT); + dmaStreamSetPeripheral(i2cp->dmatx, &dp->TXDT); +#endif + + /* Reset i2c peripheral, the TCIE bit will be handled separately.*/ + dp->CTRL1 = i2cp->config->ctrl1 | +#if AT32_I2C_USE_DMA == TRUE + I2C_CTRL1_DMATEN | I2C_CTRL1_DMAREN | /* Enable only if using DMA */ +#endif + I2C_CTRL1_ERRIEN | I2C_CTRL1_ACKFAILIEN; + + /* Setup I2C parameters.*/ + dp->CLKCTRL = i2cp->config->clkctrl; + + /* Ready to go.*/ + dp->CTRL1 |= I2C_CTRL1_I2CEN; +} + +/** + * @brief Deactivates the I2C peripheral. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +void i2c_lld_stop(I2CDriver *i2cp) { + + /* If not in stopped state then disables the I2C clock.*/ + if (i2cp->state != I2C_STOP) { + + /* I2C disable.*/ + i2c_lld_abort_operation(i2cp); +#if AT32_I2C_USE_DMA == TRUE + dmaStreamFreeI(i2cp->dmatx); + dmaStreamFreeI(i2cp->dmarx); + i2cp->dmatx = NULL; + i2cp->dmarx = NULL; +#endif + +#if AT32_I2C_USE_I2C1 + if (&I2CD1 == i2cp) { +#if defined(AT32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__) + nvicDisableVector(AT32_I2C1_GLOBAL_NUMBER); +#elif defined(AT32_I2C1_EVENT_NUMBER) && defined(AT32_I2C1_ERROR_NUMBER) + nvicDisableVector(AT32_I2C1_EVENT_NUMBER); + nvicDisableVector(AT32_I2C1_ERROR_NUMBER); +#else +#error "I2C1 interrupt numbers not defined" +#endif + + crmDisableI2C1(); + } +#endif + +#if AT32_I2C_USE_I2C2 + if (&I2CD2 == i2cp) { +#if defined(AT32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__) + nvicDisableVector(AT32_I2C2_GLOBAL_NUMBER); +#elif defined(AT32_I2C2_EVENT_NUMBER) && defined(AT32_I2C2_ERROR_NUMBER) + nvicDisableVector(AT32_I2C2_EVENT_NUMBER); + nvicDisableVector(AT32_I2C2_ERROR_NUMBER); +#else +#error "I2C2 interrupt numbers not defined" +#endif + + crmDisableI2C2(); + } +#endif + +#if AT32_I2C_USE_I2C3 + if (&I2CD3 == i2cp) { +#if defined(AT32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__) + nvicDisableVector(AT32_I2C3_GLOBAL_NUMBER); +#elif defined(AT32_I2C3_EVENT_NUMBER) && defined(AT32_I2C3_ERROR_NUMBER) + nvicDisableVector(AT32_I2C3_EVENT_NUMBER); + nvicDisableVector(AT32_I2C3_ERROR_NUMBER); +#else +#error "I2C3 interrupt numbers not defined" +#endif + + crmDisableI2C3(); + } +#endif + +#if AT32_I2C_USE_I2C4 + if (&I2CD4 == i2cp) { +#if defined(AT32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__) + nvicDisableVector(AT32_I2C4_GLOBAL_NUMBER); +#elif defined(AT32_I2C4_EVENT_NUMBER) && defined(AT32_I2C4_ERROR_NUMBER) + nvicDisableVector(AT32_I2C4_EVENT_NUMBER); + nvicDisableVector(AT32_I2C4_ERROR_NUMBER); +#else +#error "I2C4 interrupt numbers not defined" +#endif + + crmDisableI2C4(); + } +#endif + } +} + +/** + * @brief Receives data via the I2C bus as master. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] addr slave device address + * @param[out] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if the function succeeded. + * @retval MSG_RESET if one or more I2C errors occurred, the errors can + * be retrieved using @p i2cGetErrors(). + * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a + * timeout the driver must be stopped and restarted + * because the bus is in an uncertain state. + * + * @notapi + */ +msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, + uint8_t *rxbuf, size_t rxbytes, + sysinterval_t timeout) { + msg_t msg; + I2C_TypeDef *dp = i2cp->i2c; + systime_t start, end; + + /* Resetting error flags for this transfer.*/ + i2cp->errors = I2C_NO_ERROR; + + /* Releases the lock from high level driver.*/ + osalSysUnlock(); + +#if AT32_I2C_USE_DMA == TRUE + /* RX DMA setup.*/ + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode); + dmaStreamSetMemory0(i2cp->dmarx, rxbuf); + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); +#else + i2cp->rxptr = rxbuf; + i2cp->rxbytes = rxbytes; +#endif + + /* Calculating the time window for the timeout on the busy bus condition.*/ + start = osalOsGetSystemTimeX(); + end = osalTimeAddX(start, OSAL_MS2I(AT32_I2C_BUSY_TIMEOUT)); + + /* Waits until BUSY flag is reset or, alternatively, for a timeout + condition.*/ + while (true) { + osalSysLock(); + + /* If the bus is not busy then the operation can continue, note, the + loop is exited in the locked state.*/ + if ((dp->STS & I2C_STS_BUSYF) == 0) + break; + + /* If the system time went outside the allowed window then a timeout + condition is returned.*/ + if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) { + return MSG_TIMEOUT; + } + + osalSysUnlock(); + } + + /* Setting up the slave address.*/ + i2c_lld_set_address(i2cp, addr); + + /* Setting up the peripheral.*/ + i2c_lld_setup_rx_transfer(i2cp); + +#if AT32_I2C_USE_DMA == TRUE + /* Enabling RX DMA.*/ + dmaStreamEnable(i2cp->dmarx); + + /* Transfer complete interrupt enabled.*/ + dp->CTRL1 |= I2C_CTRL1_TDCIEN; +#else + + /* Transfer complete and RX interrupts enabled.*/ + dp->CTRL1 |= I2C_CTRL1_TDCIEN | I2C_CTRL1_RDIEN; +#endif + + /* Starts the operation.*/ + dp->CTRL2 |= I2C_CTRL2_GENSTART; + + /* Waits for the operation completion or a timeout.*/ + msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout); + + /* In case of a software timeout a STOP is sent as an extreme attempt + to release the bus and DMA is forcibly disabled.*/ + if (msg == MSG_TIMEOUT) { + dp->CTRL2 |= I2C_CTRL2_GENSTOP; +#if AT32_I2C_USE_DMA == TRUE + dmaStreamDisable(i2cp->dmarx); +#endif + } + + return msg; +} + +/** + * @brief Transmits data via the I2C bus as master. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * @param[in] addr slave device address + * @param[in] txbuf pointer to the transmit buffer + * @param[in] txbytes number of bytes to be transmitted + * @param[out] rxbuf pointer to the receive buffer + * @param[in] rxbytes number of bytes to be received + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval MSG_OK if the function succeeded. + * @retval MSG_RESET if one or more I2C errors occurred, the errors can + * be retrieved using @p i2cGetErrors(). + * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a + * timeout the driver must be stopped and restarted + * because the bus is in an uncertain state. + * + * @notapi + */ +msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, + const uint8_t *txbuf, size_t txbytes, + uint8_t *rxbuf, size_t rxbytes, + sysinterval_t timeout) { + msg_t msg; + I2C_TypeDef *dp = i2cp->i2c; + systime_t start, end; + + /* Resetting error flags for this transfer.*/ + i2cp->errors = I2C_NO_ERROR; + + /* Releases the lock from high level driver.*/ + osalSysUnlock(); + +#if AT32_I2C_USE_DMA == TRUE + /* TX DMA setup.*/ + dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode); + dmaStreamSetMemory0(i2cp->dmatx, txbuf); + dmaStreamSetTransactionSize(i2cp->dmatx, txbytes); + + /* RX DMA setup, note, rxbytes can be zero but we write the value anyway.*/ + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode); + dmaStreamSetMemory0(i2cp->dmarx, rxbuf); + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes); +#else + i2cp->txptr = txbuf; + i2cp->txbytes = txbytes; + i2cp->rxptr = rxbuf; + i2cp->rxbytes = rxbytes; +#endif + + /* Calculating the time window for the timeout on the busy bus condition.*/ + start = osalOsGetSystemTimeX(); + end = osalTimeAddX(start, OSAL_MS2I(AT32_I2C_BUSY_TIMEOUT)); + + /* Waits until BUSY flag is reset or, alternatively, for a timeout + condition.*/ + while (true) { + osalSysLock(); + + /* If the bus is not busy then the operation can continue, note, the + loop is exited in the locked state.*/ + if ((dp->STS & I2C_STS_BUSYF) == 0) + break; + + /* If the system time went outside the allowed window then a timeout + condition is returned.*/ + if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) { + return MSG_TIMEOUT; + } + + osalSysUnlock(); + } + + /* Setting up the slave address.*/ + i2c_lld_set_address(i2cp, addr); + + /* Preparing the transfer.*/ + i2c_lld_setup_tx_transfer(i2cp); + +#if AT32_I2C_USE_DMA == TRUE + /* Enabling TX DMA.*/ + dmaStreamEnable(i2cp->dmatx); + + /* Transfer complete interrupt enabled.*/ + dp->CTRL1 |= I2C_CTRL1_TDCIEN; +#else + /* Transfer complete and TX interrupts enabled.*/ + dp->CTRL1 |= I2C_CTRL1_TDCIEN | I2C_CTRL1_TDIEN; +#endif + + /* Starts the operation.*/ + dp->CTRL2 |= I2C_CTRL2_GENSTART; + + /* Waits for the operation completion or a timeout.*/ + msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout); + + /* In case of a software timeout a STOP is sent as an extreme attempt + to release the bus and DMA is forcibly disabled.*/ + if (msg == MSG_TIMEOUT) { + dp->CTRL2 |= I2C_CTRL2_GENSTOP; +#if AT32_I2C_USE_DMA == TRUE + dmaStreamDisable(i2cp->dmarx); + dmaStreamDisable(i2cp->dmatx); +#endif + } + + return msg; +} + +#endif /* HAL_USE_I2C */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/I2Cv2/hal_i2c_lld.h b/os/hal/ports/AT32/LLD/I2Cv2/hal_i2c_lld.h new file mode 100644 index 0000000000..f6d22314fc --- /dev/null +++ b/os/hal/ports/AT32/LLD/I2Cv2/hal_i2c_lld.h @@ -0,0 +1,525 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file I2Cv2/hal_i2c_lld.h + * @brief AT32 I2C subsystem low level driver header. + * + * @addtogroup I2C + * @{ + */ + +#ifndef HAL_I2C_LLD_H +#define HAL_I2C_LLD_H + +#if HAL_USE_I2C || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name CLKCTRL register definitions + * @{ + */ +#define AT32_CLKCTRL_DIVL_MASK (15U << 28) +#define AT32_CLKCTRL_DIVL(n) ((n) << 28) +#define AT32_CLKCTRL_DIVH_MASK (15U << 24) +#define AT32_CLKCTRL_DIVH(n) ((n) << 24) +#define AT32_CLKCTRL_SCLD_MASK (15U << 20) +#define AT32_CLKCTRL_SCLD(n) ((n) << 20) +#define AT32_CLKCTRL_SDAD_MASK (15U << 16) +#define AT32_CLKCTRL_SDAD(n) ((n) << 16) +#define AT32_CLKCTRL_SCLH_MASK (255U << 8) +#define AT32_CLKCTRL_SCLH(n) ((n) << 8) +#define AT32_CLKCTRL_SCLL_MASK (255U << 0) +#define AT32_CLKCTRL_SCLL(n) ((n) << 0) + + +/* Same as stm32 */ +#define STM32_TIMINGR_PRESC_MASK (AT32_CLKCTRL_DIVH_MASK | AT32_CLKCTRL_DIVL_MASK) +#define STM32_TIMINGR_PRESC(n) (AT32_CLKCTRL_DIVL(n&0xF) | AT32_CLKCTRL_DIVH((n>>4)&0xF)) +#define STM32_TIMINGR_SCLDEL_MASK AT32_CLKCTRL_SCLD_MASK +#define STM32_TIMINGR_SCLDEL(n) AT32_CLKCTRL_SCLD(n) +#define STM32_TIMINGR_SDADEL_MASK AT32_CLKCTRL_SDAD_MASK +#define STM32_TIMINGR_SDADEL(n) AT32_CLKCTRL_SDAD(n) +#define STM32_TIMINGR_SCLH_MASK AT32_CLKCTRL_SCLH_MASK +#define STM32_TIMINGR_SCLH(n) AT32_CLKCTRL_SCLH(n) +#define STM32_TIMINGR_SCLL_MASK AT32_CLKCTRL_SCLL_MASK +#define STM32_TIMINGR_SCLL(n) AT32_CLKCTRL_SCLL(n) + +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief I2C1 driver enable switch. + * @details If set to @p TRUE the support for I2C1 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_I2C_USE_I2C1) || defined(__DOXYGEN__) +#define AT32_I2C_USE_I2C1 FALSE +#endif + +/** + * @brief I2C2 driver enable switch. + * @details If set to @p TRUE the support for I2C2 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_I2C_USE_I2C2) || defined(__DOXYGEN__) +#define AT32_I2C_USE_I2C2 FALSE +#endif + +/** + * @brief I2C3 driver enable switch. + * @details If set to @p TRUE the support for I2C3 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_I2C_USE_I2C3) || defined(__DOXYGEN__) +#define AT32_I2C_USE_I2C3 FALSE +#endif + +/** + * @brief I2C4 driver enable switch. + * @details If set to @p TRUE the support for I2C4 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_I2C_USE_I2C4) || defined(__DOXYGEN__) +#define AT32_I2C_USE_I2C4 FALSE +#endif + +/** + * @brief I2C timeout on busy condition in milliseconds. + */ +#if !defined(AT32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__) +#define AT32_I2C_BUSY_TIMEOUT 50 +#endif + +/** + * @brief I2C1 interrupt priority level setting. + */ +#if !defined(AT32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_I2C_I2C1_IRQ_PRIORITY 10 +#endif + +/** + * @brief I2C2 interrupt priority level setting. + */ +#if !defined(AT32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_I2C_I2C2_IRQ_PRIORITY 10 +#endif + +/** + * @brief I2C3 interrupt priority level setting. + */ +#if !defined(AT32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_I2C_I2C3_IRQ_PRIORITY 10 +#endif + +/** + * @brief I2C4 interrupt priority level setting. + */ +#if !defined(AT32_I2C_I2C4_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_I2C_I2C4_IRQ_PRIORITY 10 +#endif + +/** + * @brief DMA use switch. + */ +#if !defined(AT32_I2C_USE_DMA) || defined(__DOXYGEN__) +#define AT32_I2C_USE_DMA TRUE +#endif + +/** + * @brief I2C1 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(AT32_I2C_I2C1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_I2C_I2C1_DMA_PRIORITY 1 +#endif + +/** + * @brief I2C2 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(AT32_I2C_I2C2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_I2C_I2C2_DMA_PRIORITY 1 +#endif + +/** + * @brief I2C3 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(AT32_I2C_I2C3_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_I2C_I2C3_DMA_PRIORITY 1 +#endif + +/** + * @brief I2C4 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(AT32_I2C_I2C4_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_I2C_I2C4_DMA_PRIORITY 1 +#endif + +/** + * @brief I2C DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(AT32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define AT32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/** @brief error checks */ +#if AT32_I2C_USE_I2C1 && !AT32_HAS_I2C1 +#error "I2C1 not present in the selected device" +#endif + +#if AT32_I2C_USE_I2C2 && !AT32_HAS_I2C2 +#error "I2C2 not present in the selected device" +#endif + +#if AT32_I2C_USE_I2C3 && !AT32_HAS_I2C3 +#error "I2C3 not present in the selected device" +#endif + +#if AT32_I2C_USE_I2C4 && !AT32_HAS_I2C4 +#error "I2C4 not present in the selected device" +#endif + +#if !AT32_I2C_USE_I2C1 && !AT32_I2C_USE_I2C2 && !AT32_I2C_USE_I2C3 && \ + !AT32_I2C_USE_I2C4 +#error "I2C driver activated but no I2C peripheral assigned" +#endif + +#if AT32_I2C_USE_I2C1 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_I2C_I2C1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to I2C1" +#endif + +#if AT32_I2C_USE_I2C2 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_I2C_I2C2_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to I2C2" +#endif + +#if AT32_I2C_USE_I2C3 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_I2C_I2C3_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to I2C3" +#endif + +#if AT32_I2C_USE_I2C4 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_I2C_I2C4_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to I2C4" +#endif + +#if AT32_I2C_USE_DMA == TRUE +#if AT32_I2C_USE_I2C1 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_I2C_I2C1_DMA_PRIORITY) +#error "Invalid DMA priority assigned to I2C1" +#endif + +#if AT32_I2C_USE_I2C2 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_I2C_I2C2_DMA_PRIORITY) +#error "Invalid DMA priority assigned to I2C2" +#endif + +#if AT32_I2C_USE_I2C3 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_I2C_I2C3_DMA_PRIORITY) +#error "Invalid DMA priority assigned to I2C3" +#endif + +#if AT32_I2C_USE_I2C4 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_I2C_I2C4_DMA_PRIORITY) +#error "Invalid DMA priority assigned to I2C4" +#endif +#if 0 +/* Check on the presence of the DMA streams settings in mcuconf.h.*/ +#if AT32_I2C_USE_I2C1 && (!defined(AT32_I2C_I2C1_RX_DMA_STREAM) || \ + !defined(AT32_I2C_I2C1_TX_DMA_STREAM)) +#error "I2C1 DMA streams not defined" +#endif + +#if AT32_I2C_USE_I2C2 && (!defined(AT32_I2C_I2C2_RX_DMA_STREAM) || \ + !defined(AT32_I2C_I2C2_TX_DMA_STREAM)) +#error "I2C2 DMA streams not defined" +#endif + +#if AT32_I2C_USE_I2C3 && (!defined(AT32_I2C_I2C3_RX_DMA_STREAM) || \ + !defined(AT32_I2C_I2C3_TX_DMA_STREAM)) +#error "I2C3 DMA streams not defined" +#endif + +#if AT32_I2C_USE_I2C4 && (!defined(AT32_I2C_I2C4_RX_DMA_STREAM) || \ + !defined(AT32_I2C_I2C4_TX_DMA_STREAM)) +#error "I2C4 DMA streams not defined" +#endif +#endif +/* Devices without DMAMUX require an additional check.*/ +#if !AT32_DMA_SUPPORTS_DMAMUX + +/* Check on the validity of the assigned DMA channels.*/ +#if AT32_I2C_USE_I2C1 && \ + !AT32_DMA_IS_VALID_ID(AT32_I2C_I2C1_RX_DMA_STREAM, \ + AT32_I2C1_RX_DMA_MSK) +#error "invalid DMA stream associated to I2C1 RX" +#endif + +#if AT32_I2C_USE_I2C1 && \ + !AT32_DMA_IS_VALID_ID(AT32_I2C_I2C1_TX_DMA_STREAM, \ + AT32_I2C1_TX_DMA_MSK) +#error "invalid DMA stream associated to I2C1 TX" +#endif + +#if AT32_I2C_USE_I2C2 && \ + !AT32_DMA_IS_VALID_ID(AT32_I2C_I2C2_RX_DMA_STREAM, \ + AT32_I2C2_RX_DMA_MSK) +#error "invalid DMA stream associated to I2C2 RX" +#endif + +#if AT32_I2C_USE_I2C2 && \ + !AT32_DMA_IS_VALID_ID(AT32_I2C_I2C2_TX_DMA_STREAM, \ + AT32_I2C2_TX_DMA_MSK) +#error "invalid DMA stream associated to I2C2 TX" +#endif + +#if AT32_I2C_USE_I2C3 && \ + !AT32_DMA_IS_VALID_ID(AT32_I2C_I2C3_RX_DMA_STREAM, \ + AT32_I2C3_RX_DMA_MSK) +#error "invalid DMA stream associated to I2C3 RX" +#endif + +#if AT32_I2C_USE_I2C3 && \ + !AT32_DMA_IS_VALID_ID(AT32_I2C_I2C3_TX_DMA_STREAM, \ + AT32_I2C3_TX_DMA_MSK) +#error "invalid DMA stream associated to I2C3 TX" +#endif + +#if AT32_I2C_USE_I2C4 && \ + !AT32_DMA_IS_VALID_ID(AT32_I2C_I2C4_RX_DMA_STREAM, \ + AT32_I2C4_RX_DMA_MSK) +#error "invalid DMA stream associated to I2C4 RX" +#endif + +#if AT32_I2C_USE_I2C4 && \ + !AT32_DMA_IS_VALID_ID(AT32_I2C_I2C4_TX_DMA_STREAM, \ + AT32_I2C4_TX_DMA_MSK) +#error "invalid DMA stream associated to I2C4 TX" +#endif + +#endif /* !AT32_DMA_SUPPORTS_DMAMUX */ + +#if !defined(AT32_DMA_REQUIRED) +#define AT32_DMA_REQUIRED +#endif +#endif /* AT32_I2C_USE_DMA == TRUE */ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type representing an I2C address. + */ +typedef uint16_t i2caddr_t; + +/** + * @brief Type of I2C driver condition flags. + */ +typedef uint32_t i2cflags_t; + +/** + * @brief I2C driver configuration structure. + */ +struct hal_i2c_config { + /** + * @brief CLKCTRL register initialization. + * @note Refer to the AT32 reference manual, the values are affected + * by the system clock settings in mcuconf.h. + */ + uint32_t clkctrl; + /** + * @brief CTRL1 register initialization. + * @note Leave to zero unless you know what you are doing. + */ + uint32_t ctrl1; + /** + * @brief CTRL2 register initialization. + * @note Only the ADD10 bit can eventually be specified here. + */ + uint32_t ctrl2; +}; + +/** + * @brief Type of a structure representing an I2C configuration. + */ +typedef struct hal_i2c_config I2CConfig; + +/** + * @brief Type of a structure representing an I2C driver. + */ +typedef struct hal_i2c_driver I2CDriver; + +/** + * @brief Structure representing an I2C driver. + */ +struct hal_i2c_driver { + /** + * @brief Driver state. + */ + i2cstate_t state; + /** + * @brief Current configuration data. + */ + const I2CConfig *config; + /** + * @brief Error flags. + */ + i2cflags_t errors; +#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) + mutex_t mutex; +#endif /* I2C_USE_MUTUAL_EXCLUSION */ +#if defined(I2C_DRIVER_EXT_FIELDS) + I2C_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Thread waiting for I/O completion. + */ + thread_reference_t thread; +#if (AT32_I2C_USE_DMA == TRUE) || defined(__DOXYGEN__) + /** + * @brief RX DMA mode bit mask. + */ + uint32_t rxdmamode; + /** + * @brief TX DMA mode bit mask. + */ + uint32_t txdmamode; + /** + * @brief Receive DMA channel. + */ + const at32_dma_stream_t *dmarx; + /** + * @brief Transmit DMA channel. + */ + const at32_dma_stream_t *dmatx; +#else /* AT32_I2C_USE_DMA == FALSE */ + /** + * @brief Pointer to the next TX buffer location. + */ + const uint8_t *txptr; + /** + * @brief Number of bytes in TX phase. + */ + size_t txbytes; + /** + * @brief Pointer to the next RX buffer location. + */ + uint8_t *rxptr; + /** + * @brief Number of bytes in RX phase. + */ + size_t rxbytes; +#endif /* AT32_I2C_USE_DMA == FALSE */ + /** + * @brief Pointer to the I2Cx registers block. + */ + I2C_TypeDef *i2c; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Get errors from I2C driver. + * + * @param[in] i2cp pointer to the @p I2CDriver object + * + * @notapi + */ +#define i2c_lld_get_errors(i2cp) ((i2cp)->errors) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +#if AT32_I2C_USE_I2C1 +extern I2CDriver I2CD1; +#endif + +#if AT32_I2C_USE_I2C2 +extern I2CDriver I2CD2; +#endif + +#if AT32_I2C_USE_I2C3 +extern I2CDriver I2CD3; +#endif + +#if AT32_I2C_USE_I2C4 +extern I2CDriver I2CD4; +#endif + +#endif /* !defined(__DOXYGEN__) */ + +#ifdef __cplusplus +extern "C" { +#endif + void i2c_lld_init(void); + void i2c_lld_start(I2CDriver *i2cp); + void i2c_lld_stop(I2CDriver *i2cp); + msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr, + const uint8_t *txbuf, size_t txbytes, + uint8_t *rxbuf, size_t rxbytes, + sysinterval_t timeout); + msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr, + uint8_t *rxbuf, size_t rxbytes, + sysinterval_t timeout); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_I2C */ + +#endif /* HAL_I2C_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/AT32/LLD/OTGv1/hal_usb_lld.c index b43b3edb2e..4486b8f946 100644 --- a/os/hal/ports/AT32/LLD/OTGv1/hal_usb_lld.c +++ b/os/hal/ports/AT32/LLD/OTGv1/hal_usb_lld.c @@ -2,6 +2,7 @@ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio ChibiOS - Copyright (C) 2023..2024 HorrorTroll ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -783,6 +784,8 @@ void usb_lld_start(USBDriver *usbp) { #if AT32_USB_USE_OTG2 if (&USBD2 == usbp) { + +#if AT32_OTG2_SUPPORTS_HS /* OTG HS clock enable and reset.*/ crmEnableOTG_HS(true); crmResetOTG_HS(); @@ -791,16 +794,8 @@ void usb_lld_start(USBDriver *usbp) { nvicEnableVector(AT32_OTG2_NUMBER, AT32_USB_OTG2_IRQ_PRIORITY); /* - Forced device mode. - - USB turn-around time = USBTRDTIM_VALUE_HS or USBTRDTIM_VALUE_FS.*/ -#if defined(BOARD_OTG2_USES_ULPI) - /* High speed ULPI PHY.*/ + - USB turn-around time = USBTRDTIM_VALUE_HS or USBTRDTIM_VALUE_FS.*/ otgp->GUSBCFG = GUSBCFG_FDEVMODE | GUSBCFG_USBTRDTIM(USBTRDTIM_VALUE_HS); -#else - otgp->GUSBCFG = GUSBCFG_FDEVMODE | GUSBCFG_USBTRDTIM(USBTRDTIM_VALUE_FS) | - GUSBCFG_PHYSEL; -#endif - -#if defined(BOARD_OTG2_USES_ULPI) #if AT32_USE_USB_OTG2_HS /* USB 2.0 High Speed PHY in HS mode.*/ otgp->DCFG = 0x02200000 | DCFG_DEVSPD_HS; @@ -808,7 +803,20 @@ void usb_lld_start(USBDriver *usbp) { /* USB 2.0 High Speed PHY in FS mode.*/ otgp->DCFG = 0x02200000 | DCFG_DEVSPD_HS_FS; #endif + #else + /* OTG FS clock enable and reset.*/ + crmEnableOTG_FS2(true); + crmResetOTG_FS2(); + + /* Enables IRQ vector.*/ + nvicEnableVector(AT32_OTG2_NUMBER, AT32_USB_OTG2_IRQ_PRIORITY); + + /* - Forced device mode. + - USB turn-around time = USBTRDTIM_VALUE_HS or USBTRDTIM_VALUE_FS.*/ + otgp->GUSBCFG = GUSBCFG_FDEVMODE | GUSBCFG_USBTRDTIM(USBTRDTIM_VALUE_FS) | + GUSBCFG_PHYSEL; + /* 48MHz 1.1 PHY.*/ otgp->DCFG = 0x02200000 | DCFG_DEVSPD_FS11; #endif diff --git a/os/hal/ports/AT32/LLD/SPIv2/driver.mk b/os/hal/ports/AT32/LLD/SPIv2/driver.mk new file mode 100644 index 0000000000..3ccd2ddbb1 --- /dev/null +++ b/os/hal/ports/AT32/LLD/SPIv2/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),) +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/SPIv2/hal_spi_v2_lld.c +endif +else +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/SPIv2/hal_spi_v2_lld.c +endif + +PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/SPIv2 diff --git a/os/hal/ports/AT32/LLD/SPIv2/hal_spi_v2_lld.c b/os/hal/ports/AT32/LLD/SPIv2/hal_spi_v2_lld.c new file mode 100644 index 0000000000..c1ef1cd24e --- /dev/null +++ b/os/hal/ports/AT32/LLD/SPIv2/hal_spi_v2_lld.c @@ -0,0 +1,626 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file SPIv1/hal_spi_v2_lld.c + * @brief AT32 SPI (v2) subsystem low level driver source. + * + * @addtogroup SPI + * @{ + */ + +#include "hal.h" + +#if HAL_USE_SPI || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#if !defined(SPI_SPID1_MEMORY) +#define SPI_SPID1_MEMORY +#endif + +#if !defined(SPI_SPID2_MEMORY) +#define SPI_SPID2_MEMORY +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief SPI1 driver identifier.*/ +#if AT32_SPI_USE_SPI1 || defined(__DOXYGEN__) +SPI_SPID1_MEMORY SPIDriver SPID1; +#endif + +/** @brief SPI2 driver identifier.*/ +#if AT32_SPI_USE_SPI2 || defined(__DOXYGEN__) +SPI_SPID2_MEMORY SPIDriver SPID2; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static void spi_lld_configure(SPIDriver *spip) { + uint32_t ctrl1, ctrl2; + + /* Disabling SPI during (re)configuration.*/ + spip->spi->CTRL1 = 0U; + + /* Common CTRL1 and CTRL2 options.*/ + ctrl1 = spip->config->ctrl1 & ~(SPI_CTRL1_MSTEN | SPI_CTRL1_SPIEN); + ctrl2 = spip->config->ctrl2 | SPI_CTRL2_DMAREN | SPI_CTRL2_DMATEN; + + /* SPI setup.*/ + if (spip->config->slave == false) { + ctrl1 |= SPI_CTRL1_SWCSEN | SPI_CTRL1_SWCSIL | SPI_CTRL1_MSTEN; + ctrl2 |= SPI_CTRL2_HWCSOE; + } + + /* New configuration.*/ + spip->spi->CTRL2 = ctrl2; + spip->spi->CTRL1 = ctrl1; + spip->spi->CTRL1 = ctrl1 | SPI_CTRL1_SPIEN; +} + +/** + * @brief Stopping the SPI transaction. + * @note This is done nicely or by brutally resetting it depending on + * the mode and settings. + * + * @param[in] spip pointer to the @p SPIDriver object + */ +static msg_t spi_lld_stop_abort(SPIDriver *spip) { + + if (!spip->config->slave) { + /* Master mode, stopping gracefully.*/ + + /* Stopping TX DMA channel.*/ + dmaStreamDisable(spip->dmatx); + + /* Waiting for current frame completion then stop SPI.*/ + while ((spip->spi->STS & SPI_STS_BF) != 0U) { + } + + /* Now it is idle, stopping RX DMA channel.*/ + dmaStreamDisable(spip->dmarx); + } + else { + /* Slave mode, this will not be nice.*/ + + /* Stopping DMAs.*/ + dmaStreamDisable(spip->dmatx); + dmaStreamDisable(spip->dmarx); + + /* Resetting SPI, this will stop it for sure and leave it + in a clean state.*/ + if (false) { + } + +#if AT32_SPI_USE_SPI1 + else if (&SPID1 == spip) { + crmResetSPI1(); + } +#endif + +#if AT32_SPI_USE_SPI2 + else if (&SPID2 == spip) { + crmResetSPI2(); + } +#endif + + else { + osalDbgAssert(false, "invalid SPI instance"); + } + + /* Reconfiguring SPI.*/ + spi_lld_configure(spip); + } + + return HAL_RET_SUCCESS; +} + +/** + * @brief Shared end-of-rx service routine. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] flags pre-shifted content of the STS register + */ +static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) { + + /* DMA errors handling.*/ + if ((flags & AT32_DMA_STS_DTERRF) != 0) { +#if defined(AT32_SPI_DMA_ERROR_HOOK) + /* Hook first, if defined.*/ + AT32_SPI_DMA_ERROR_HOOK(spip); +#endif + + /* Aborting the transfer.*/ + (void) spi_lld_stop_abort(spip); + + /* Reporting the failure.*/ + __spi_isr_error_code(spip, HAL_RET_HW_FAILURE); + } + else if (spip->config->circular) { + if ((flags & AT32_DMA_STS_HDTF) != 0U) { + /* Half buffer interrupt.*/ + __spi_isr_half_code(spip); + } + if ((flags & AT32_DMA_STS_FDTF) != 0U) { + /* End buffer interrupt.*/ + __spi_isr_full_code(spip); + } + } + else { + /* Stopping the transfer.*/ + (void) spi_lld_stop_abort(spip); + + /* Operation finished interrupt.*/ + __spi_isr_complete_code(spip); + } +} + +/** + * @brief Shared end-of-tx service routine. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] flags pre-shifted content of the STS register + */ +static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) { + + /* DMA errors handling.*/ + if ((flags & AT32_DMA_STS_DTERRF) != 0) { +#if defined(AT32_SPI_DMA_ERROR_HOOK) + /* Hook first, if defined.*/ + AT32_SPI_DMA_ERROR_HOOK(spip); +#endif + + /* Aborting the transfer.*/ + (void) spi_lld_stop_abort(spip); + + /* Reporting the failure.*/ + __spi_isr_error_code(spip, HAL_RET_HW_FAILURE); + } +} + +/** + * @brief DMA streams allocation. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] rxstream stream to be allocated for RX + * @param[in] txstream stream to be allocated for TX + * @param[in] priority streams IRQ priority + * @return The operation status. + */ +static msg_t spi_lld_get_dma(SPIDriver *spip, uint32_t rxstream, + uint32_t txstream, uint32_t priority) { + + spip->dmarx = dmaStreamAllocI(rxstream, priority, + (at32_dmasts_t)spi_lld_serve_rx_interrupt, + (void *)spip); + if (spip->dmarx == NULL) { + return HAL_RET_NO_RESOURCE; + } + + spip->dmatx = dmaStreamAllocI(txstream, priority, + (at32_dmasts_t)spi_lld_serve_tx_interrupt, + (void *)spip); + if (spip->dmatx == NULL) { + dmaStreamFreeI(spip->dmarx); + return HAL_RET_NO_RESOURCE; + } + + return HAL_RET_SUCCESS; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level SPI driver initialization. + * + * @notapi + */ +void spi_lld_init(void) { + +#if AT32_SPI_USE_SPI1 + spiObjectInit(&SPID1); + SPID1.spi = SPI1; + SPID1.dmarx = NULL; + SPID1.dmatx = NULL; + SPID1.rxdmamode = AT32_DMA_CTRL_CHPL(AT32_SPI_SPI1_DMA_PRIORITY) | + AT32_DMA_CTRL_DTD_P2M | + AT32_DMA_CTRL_FDTIEN | + AT32_DMA_CTRL_DTERRIEN; + SPID1.txdmamode = AT32_DMA_CTRL_CHPL(AT32_SPI_SPI1_DMA_PRIORITY) | + AT32_DMA_CTRL_DTD_M2P | + AT32_DMA_CTRL_DTERRIEN; +#endif + +#if AT32_SPI_USE_SPI2 + spiObjectInit(&SPID2); + SPID2.spi = SPI2; + SPID2.dmarx = NULL; + SPID2.dmatx = NULL; + SPID2.rxdmamode = AT32_DMA_CTRL_CHPL(AT32_SPI_SPI2_DMA_PRIORITY) | + AT32_DMA_CTRL_DTD_P2M | + AT32_DMA_CTRL_FDTIEN | + AT32_DMA_CTRL_DTERRIEN; + SPID2.txdmamode = AT32_DMA_CTRL_CHPL(AT32_SPI_SPI2_DMA_PRIORITY) | + AT32_DMA_CTRL_DTD_M2P | + AT32_DMA_CTRL_DTERRIEN; +#endif +} + +/** + * @brief Configures and activates the SPI peripheral. + * + * @param[in] spip pointer to the @p SPIDriver object + * @return The operation status. + * + * @notapi + */ +msg_t spi_lld_start(SPIDriver *spip) { + msg_t msg; + + /* Resetting TX pattern source.*/ + spip->txsource = (uint32_t)AT32_SPI_FILLER_PATTERN; + + /* If in stopped state then enables the SPI and DMA clocks.*/ + if (spip->state == SPI_STOP) { + if (false) { + } + +#if AT32_SPI_USE_SPI1 + else if (&SPID1 == spip) { + msg = spi_lld_get_dma(spip, + AT32_SPI_SPI1_RX_DMA_STREAM, + AT32_SPI_SPI1_TX_DMA_STREAM, + AT32_SPI_SPI1_IRQ_PRIORITY); + if (msg != HAL_RET_SUCCESS) { + return msg; + } + crmEnableSPI1(true); + crmResetSPI1(); +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(spip->dmarx, AT32_DMAMUX_SPI1_RX); + dmaSetRequestSource(spip->dmatx, AT32_DMAMUX_SPI1_TX); +#endif + } +#endif + +#if AT32_SPI_USE_SPI2 + else if (&SPID2 == spip) { + msg = spi_lld_get_dma(spip, + AT32_SPI_SPI2_RX_DMA_STREAM, + AT32_SPI_SPI2_TX_DMA_STREAM, + AT32_SPI_SPI2_IRQ_PRIORITY); + if (msg != HAL_RET_SUCCESS) { + return msg; + } + crmEnableSPI2(true); + crmResetSPI2(); +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(spip->dmarx, AT32_DMAMUX_SPI2_RX); + dmaSetRequestSource(spip->dmatx, AT32_DMAMUX_SPI2_TX); +#endif + } +#endif + + else { + osalDbgAssert(false, "invalid SPI instance"); + } + + /* DMA setup.*/ + dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DT); + dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DT); + } + + /* Configuration-specific DMA setup.*/ + if ((spip->config->ctrl1 & SPI_CTRL1_FBN) == 0) { + /* Frame width is 8 bits or smaller.*/ + spip->rxdmamode = (spip->rxdmamode & ~AT32_DMA_CTRL_WIDTH_MASK) | + AT32_DMA_CTRL_PWIDTH_BYTE | AT32_DMA_CTRL_MWIDTH_BYTE; + spip->txdmamode = (spip->txdmamode & ~AT32_DMA_CTRL_WIDTH_MASK) | + AT32_DMA_CTRL_PWIDTH_BYTE | AT32_DMA_CTRL_MWIDTH_BYTE; + } + else { + /* Frame width is larger than 8 bits.*/ + spip->rxdmamode = (spip->rxdmamode & ~AT32_DMA_CTRL_WIDTH_MASK) | + AT32_DMA_CTRL_PWIDTH_HWORD | AT32_DMA_CTRL_MWIDTH_HWORD; + spip->txdmamode = (spip->txdmamode & ~AT32_DMA_CTRL_WIDTH_MASK) | + AT32_DMA_CTRL_PWIDTH_HWORD | AT32_DMA_CTRL_MWIDTH_HWORD; + } + + if (spip->config->circular) { + spip->rxdmamode |= (AT32_DMA_CTRL_LM | AT32_DMA_CTRL_HDTIEN); + spip->txdmamode |= (AT32_DMA_CTRL_LM | AT32_DMA_CTRL_HDTIEN); + } + else { + spip->rxdmamode &= ~(AT32_DMA_CTRL_LM | AT32_DMA_CTRL_HDTIEN); + spip->txdmamode &= ~(AT32_DMA_CTRL_LM | AT32_DMA_CTRL_HDTIEN); + } + + /* SPI setup.*/ + spi_lld_configure(spip); + + return HAL_RET_SUCCESS; +} + +/** + * @brief Deactivates the SPI peripheral. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_stop(SPIDriver *spip) { + + /* If in ready state then disables the SPI clock.*/ + if (spip->state == SPI_READY) { + + /* Just in case this has been called uncleanly.*/ + (void) spi_lld_stop_abort(spip); + + /* SPI cleanup.*/ + spip->spi->CTRL1 = 0; + spip->spi->CTRL2 = 0; + + /* DMA channels release.*/ + dmaStreamFreeI(spip->dmatx); + dmaStreamFreeI(spip->dmarx); + spip->dmarx = NULL; + spip->dmatx = NULL; + + /* Clock shutdown.*/ + if (false) { + } + +#if AT32_SPI_USE_SPI1 + else if (&SPID1 == spip) { + crmDisableSPI1(); + } +#endif + +#if AT32_SPI_USE_SPI2 + else if (&SPID2 == spip) { + crmDisableSPI2(); + } +#endif + + else { + osalDbgAssert(false, "invalid SPI instance"); + } + } +} + +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) +/** + * @brief Asserts the slave select signal and prepares for transfers. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_select(SPIDriver *spip) { + + /* No implementation on AT32.*/ +} + +/** + * @brief Deasserts the slave select signal. + * @details The previously selected peripheral is unselected. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_unselect(SPIDriver *spip) { + + /* No implementation on AT32.*/ +} +#endif + +/** + * @brief Ignores data on the SPI bus. + * @details This synchronous function performs the transmission of a series of + * idle words on the SPI bus and ignores the received data. + * @pre In order to use this function the option @p SPI_USE_SYNCHRONIZATION + * must be enabled. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] n number of words to be ignored + * @return The operation status. + * + * @notapi + */ +msg_t spi_lld_ignore(SPIDriver *spip, size_t n) { + + osalDbgAssert(n <= AT32_DMA_MAX_TRANSFER, "unsupported DMA transfer size"); + + dmaStreamSetMemory0(spip->dmarx, &spip->rxsink); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode); + + dmaStreamSetMemory0(spip->dmatx, &spip->txsource); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->txdmamode); + + dmaStreamEnable(spip->dmarx); + dmaStreamEnable(spip->dmatx); + + return HAL_RET_SUCCESS; +} + +/** + * @brief Exchanges data on the SPI bus. + * @details This asynchronous function starts a simultaneous transmit/receive + * operation. + * @post At the end of the operation the configured callback is invoked. + * @note The buffers are organized as uint8_t arrays for data sizes below or + * equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] n number of words to be exchanged + * @param[in] txbuf the pointer to the transmit buffer + * @param[out] rxbuf the pointer to the receive buffer + * @return The operation status. + * + * @notapi + */ +msg_t spi_lld_exchange(SPIDriver *spip, size_t n, + const void *txbuf, void *rxbuf) { + + osalDbgAssert(n <= AT32_DMA_MAX_TRANSFER, "unsupported DMA transfer size"); + + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | AT32_DMA_CTRL_MINCM); + + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->txdmamode | AT32_DMA_CTRL_MINCM); + + dmaStreamEnable(spip->dmarx); + dmaStreamEnable(spip->dmatx); + + return HAL_RET_SUCCESS; +} + +/** + * @brief Sends data over the SPI bus. + * @details This asynchronous function starts a transmit operation. + * @post At the end of the operation the configured callback is invoked. + * @note The buffers are organized as uint8_t arrays for data sizes below or + * equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] n number of words to send + * @param[in] txbuf the pointer to the transmit buffer + * @return The operation status. + * + * @notapi + */ +msg_t spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { + + osalDbgAssert(n <= AT32_DMA_MAX_TRANSFER, "unsupported DMA transfer size"); + + dmaStreamSetMemory0(spip->dmarx, &spip->rxsink); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode); + + dmaStreamSetMemory0(spip->dmatx, txbuf); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->txdmamode | AT32_DMA_CTRL_MINCM); + + dmaStreamEnable(spip->dmarx); + dmaStreamEnable(spip->dmatx); + + return HAL_RET_SUCCESS; +} + +/** + * @brief Receives data from the SPI bus. + * @details This asynchronous function starts a receive operation. + * @post At the end of the operation the configured callback is invoked. + * @note The buffers are organized as uint8_t arrays for data sizes below or + * equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] n number of words to receive + * @param[out] rxbuf the pointer to the receive buffer + * @return The operation status. + * + * @notapi + */ +msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { + + osalDbgAssert(n <= AT32_DMA_MAX_TRANSFER, "unsupported DMA transfer size"); + + dmaStreamSetMemory0(spip->dmarx, rxbuf); + dmaStreamSetTransactionSize(spip->dmarx, n); + dmaStreamSetMode(spip->dmarx, spip->rxdmamode | AT32_DMA_CTRL_MINCM); + + dmaStreamSetMemory0(spip->dmatx, &spip->txsource); + dmaStreamSetTransactionSize(spip->dmatx, n); + dmaStreamSetMode(spip->dmatx, spip->txdmamode); + + dmaStreamEnable(spip->dmarx); + dmaStreamEnable(spip->dmatx); + + return HAL_RET_SUCCESS; +} + +/** + * @brief Aborts the ongoing SPI operation, if any. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[out] sizep pointer to the counter of frames not yet transferred + * or @p NULL + * @return The operation status. + * + * @notapi + */ +msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep) { + msg_t msg; + + /* Stopping everything.*/ + msg = spi_lld_stop_abort(spip); + + if (sizep != NULL) { + *sizep = dmaStreamGetTransactionSize(spip->dmarx); + } + + return msg; +} + +/** + * @brief Exchanges one frame using a polled wait. + * @details This synchronous function exchanges one frame using a polled + * synchronization method. This function is useful when exchanging + * small amount of data on high speed channels, usually in this + * situation is much more efficient just wait for completion using + * polling than suspending the thread waiting for an interrupt. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] frame the data frame to send over the SPI bus + * @return The received data frame from the SPI bus. + */ +uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { + + spip->spi->DT = frame; + while ((spip->spi->STS & SPI_STS_RDBF) == 0U) + ; + return spip->spi->DT; +} + +#endif /* HAL_USE_SPI */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/SPIv2/hal_spi_v2_lld.h b/os/hal/ports/AT32/LLD/SPIv2/hal_spi_v2_lld.h new file mode 100644 index 0000000000..02f96a82ef --- /dev/null +++ b/os/hal/ports/AT32/LLD/SPIv2/hal_spi_v2_lld.h @@ -0,0 +1,234 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file SPIv1/hal_spi_v2_lld.h + * @brief AT32 SPI (v2) subsystem low level driver header. + * + * @addtogroup SPI + * @{ + */ + +#ifndef HAL_SPI_V2_LLD_H +#define HAL_SPI_V2_LLD_H + +#if HAL_USE_SPI || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Circular mode support flag. + */ +#define SPI_SUPPORTS_CIRCULAR TRUE + +/** + * @brief Slave mode support flag. + */ +#define SPI_SUPPORTS_SLAVE_MODE TRUE +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief SPI1 driver enable switch. + * @details If set to @p TRUE the support for SPI1 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SPI_USE_SPI1) || defined(__DOXYGEN__) +#define AT32_SPI_USE_SPI1 FALSE +#endif + +/** + * @brief SPI2 driver enable switch. + * @details If set to @p TRUE the support for SPI2 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SPI_USE_SPI2) || defined(__DOXYGEN__) +#define AT32_SPI_USE_SPI2 FALSE +#endif + +/** + * @brief Filler pattern used when there is nothing to transmit. + */ +#if !defined(AT32_SPI_FILLER_PATTERN) || defined(__DOXYGEN__) +#define AT32_SPI_FILLER_PATTERN 0xFFFFFFFFU +#endif + +/** + * @brief SPI1 interrupt priority level setting. + */ +#if !defined(AT32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SPI_SPI1_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI2 interrupt priority level setting. + */ +#if !defined(AT32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SPI_SPI2_IRQ_PRIORITY 10 +#endif + +/** + * @brief SPI1 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(AT32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SPI_SPI1_DMA_PRIORITY 1 +#endif + +/** + * @brief SPI2 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA streams but + * because of the streams ordering the RX stream has always priority + * over the TX stream. + */ +#if !defined(AT32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SPI_SPI2_DMA_PRIORITY 1 +#endif + +/** + * @brief SPI DMA error hook. + */ +#if !defined(AT32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define AT32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") +#endif + +/** + * @brief SPI DMA max transfer hook. + */ +#if !defined(AT32_DMA_MAX_TRANSFER) || defined(__DOXYGEN__) +#define AT32_DMA_MAX_TRANSFER 65536 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if AT32_SPI_USE_SPI1 && !AT32_HAS_SPI1 +#error "SPI1 not present in the selected device" +#endif + +#if AT32_SPI_USE_SPI2 && !AT32_HAS_SPI2 +#error "SPI2 not present in the selected device" +#endif + +#if !AT32_SPI_USE_SPI1 && !AT32_SPI_USE_SPI2 +#error "SPI driver activated but no SPI peripheral assigned" +#endif + +#if AT32_SPI_USE_SPI1 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SPI_SPI1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI1" +#endif + +#if AT32_SPI_USE_SPI2 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SPI_SPI2_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI2" +#endif + +#if !defined(AT32_DMA_REQUIRED) +#define AT32_DMA_REQUIRED +#endif + +#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD +#error "SPI_SELECT_MODE_LLD not supported by this driver" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +#define spi_lld_driver_fields \ + /* Pointer to the SPIx registers block.*/ \ + SPI_TypeDef *spi; \ + /* Receive DMA stream.*/ \ + const at32_dma_stream_t *dmarx; \ + /* Transmit DMA stream.*/ \ + const at32_dma_stream_t *dmatx; \ + /* RX DMA mode bit mask.*/ \ + uint32_t rxdmamode; \ + /* TX DMA mode bit mask.*/ \ + uint32_t txdmamode; \ + /* Sink for discarded data.*/ \ + uint32_t rxsink; \ + /* Source for default TX pattern.*/ \ + uint32_t txsource + +/** + * @brief Low level fields of the SPI configuration structure. + */ +#define spi_lld_config_fields \ + /* SPI CTRL1 register initialization data.*/ \ + uint16_t ctrl1; \ + /* SPI CTRL2 register initialization data.*/ \ + uint16_t ctrl2 + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if AT32_SPI_USE_SPI1 && !defined(__DOXYGEN__) +extern SPIDriver SPID1; +#endif + +#if AT32_SPI_USE_SPI2 && !defined(__DOXYGEN__) +extern SPIDriver SPID2; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void spi_lld_init(void); + msg_t spi_lld_start(SPIDriver *spip); + void spi_lld_stop(SPIDriver *spip); +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) + void spi_lld_select(SPIDriver *spip); + void spi_lld_unselect(SPIDriver *spip); +#endif + msg_t spi_lld_ignore(SPIDriver *spip, size_t n); + msg_t spi_lld_exchange(SPIDriver *spip, size_t n, + const void *txbuf, void *rxbuf); + msg_t spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); + msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); + msg_t spi_lld_stop_transfer(SPIDriver *spip, size_t *sizep); + uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_SPI */ + +#endif /* HAL_SPI_V2_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/TMRv1/at32_tmr13.inc b/os/hal/ports/AT32/LLD/TMRv1/at32_tmr13.inc new file mode 100644 index 0000000000..e55972480b --- /dev/null +++ b/os/hal/ports/AT32/LLD/TMRv1/at32_tmr13.inc @@ -0,0 +1,136 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file TMRv1/at32_tmr13.inc + * @brief Shared TMR13 handler. + * + * @addtogroup AT32_TMR13_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_TMR13) +#error "AT32_HAS_TMR13 not defined in registry" +#endif + +/* Driver checks for robustness, undefined USE macros are defaulted to + FALSE. This makes this module independent from drivers implementation.*/ +#if !defined(AT32_GPT_USE_TMR13) +#define AT32_GPT_USE_TMR13 FALSE +#endif +#if !defined(AT32_ICU_USE_TMR13) +#define AT32_ICU_USE_TMR13 FALSE +#endif +#if !defined(AT32_PWM_USE_TMR13) +#define AT32_PWM_USE_TMR13 FALSE +#endif +#if !defined(AT32_ST_USE_TMR13) +#define AT32_ST_USE_TMR13 FALSE +#endif + +#if AT32_HAS_TMR13 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_TMR13_PRIORITY) +#error "AT32_IRQ_TMR13_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_TMR13_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_TMR13_PRIORITY" +#endif + +#endif /* AT32_HAS_TMR13 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void tmr13_irq_init(void) { +#if defined(AT32_TMR13_IS_USED) + nvicEnableVector(AT32_TMR13_NUMBER, AT32_IRQ_TMR13_PRIORITY); +#endif +} + +static inline void tmr13_irq_deinit(void) { +#if defined(AT32_TMR13_IS_USED) + nvicDisableVector(AT32_TMR13_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_TMR13_IS_USED) || defined(__DOXYGEN__) +/** + * @brief TMR13 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_TMR13_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_GPT +#if AT32_GPT_USE_TMR13 + gpt_lld_serve_interrupt(&GPTD13); +#endif +#endif +#if HAL_USE_ICU +#if AT32_ICU_USE_TMR13 + icu_lld_serve_interrupt(&ICUD13); +#endif +#endif +#if HAL_USE_PWM +#if AT32_PWM_USE_TMR13 + pwm_lld_serve_interrupt(&PWMD13); +#endif +#endif +#if 1 +#if AT32_ST_USE_TMR13 + st_lld_serve_interrupt(); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/TMRv1/at32_tmr14.inc b/os/hal/ports/AT32/LLD/TMRv1/at32_tmr14.inc new file mode 100644 index 0000000000..4b70b97a64 --- /dev/null +++ b/os/hal/ports/AT32/LLD/TMRv1/at32_tmr14.inc @@ -0,0 +1,136 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file TMRv1/at32_tmr14.inc + * @brief Shared TMR14 handler. + * + * @addtogroup AT32_TMR14_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_TMR14) +#error "AT32_HAS_TMR14 not defined in registry" +#endif + +/* Driver checks for robustness, undefined USE macros are defaulted to + FALSE. This makes this module independent from drivers implementation.*/ +#if !defined(AT32_GPT_USE_TMR14) +#define AT32_GPT_USE_TMR14 FALSE +#endif +#if !defined(AT32_ICU_USE_TMR14) +#define AT32_ICU_USE_TMR14 FALSE +#endif +#if !defined(AT32_PWM_USE_TMR14) +#define AT32_PWM_USE_TMR14 FALSE +#endif +#if !defined(AT32_ST_USE_TMR14) +#define AT32_ST_USE_TMR14 FALSE +#endif + +#if AT32_HAS_TMR14 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_TMR14_PRIORITY) +#error "AT32_IRQ_TMR14_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_TMR14_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_TMR14_PRIORITY" +#endif + +#endif /* AT32_HAS_TMR14 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void tmr14_irq_init(void) { +#if defined(AT32_TMR14_IS_USED) + nvicEnableVector(AT32_TMR14_NUMBER, AT32_IRQ_TMR14_PRIORITY); +#endif +} + +static inline void tmr14_irq_deinit(void) { +#if defined(AT32_TMR14_IS_USED) + nvicDisableVector(AT32_TMR14_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_TMR14_IS_USED) || defined(__DOXYGEN__) +/** + * @brief TMR14 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_TMR14_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_GPT +#if AT32_GPT_USE_TMR14 + gpt_lld_serve_interrupt(&GPTD14); +#endif +#endif +#if HAL_USE_ICU +#if AT32_ICU_USE_TMR14 + icu_lld_serve_interrupt(&ICUD14); +#endif +#endif +#if HAL_USE_PWM +#if AT32_PWM_USE_TMR14 + pwm_lld_serve_interrupt(&PWMD14); +#endif +#endif +#if 1 +#if AT32_ST_USE_TMR14 + st_lld_serve_interrupt(); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/TMRv1/at32_tmr6.inc b/os/hal/ports/AT32/LLD/TMRv1/at32_tmr6.inc new file mode 100644 index 0000000000..aac92e5593 --- /dev/null +++ b/os/hal/ports/AT32/LLD/TMRv1/at32_tmr6.inc @@ -0,0 +1,136 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file TMRv1/at32_tmr6.inc + * @brief Shared TMR6 handler. + * + * @addtogroup AT32_TMR6_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_TMR6) +#error "AT32_HAS_TMR6 not defined in registry" +#endif + +/* Driver checks for robustness, undefined USE macros are defaulted to + FALSE. This makes this module independent from drivers implementation.*/ +#if !defined(AT32_GPT_USE_TMR6) +#define AT32_GPT_USE_TMR6 FALSE +#endif +#if !defined(AT32_ICU_USE_TMR6) +#define AT32_ICU_USE_TMR6 FALSE +#endif +#if !defined(AT32_PWM_USE_TMR6) +#define AT32_PWM_USE_TMR6 FALSE +#endif +#if !defined(AT32_ST_USE_TMR6) +#define AT32_ST_USE_TMR6 FALSE +#endif + +#if AT32_HAS_TMR6 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_TMR6_PRIORITY) +#error "AT32_IRQ_TMR6_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_TMR6_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_TMR6_PRIORITY" +#endif + +#endif /* AT32_HAS_TMR6 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void tmr6_irq_init(void) { +#if defined(AT32_TMR6_IS_USED) + nvicEnableVector(AT32_TMR6_NUMBER, AT32_IRQ_TMR6_PRIORITY); +#endif +} + +static inline void tmr6_irq_deinit(void) { +#if defined(AT32_TMR6_IS_USED) + nvicDisableVector(AT32_TMR6_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_TMR6_IS_USED) || defined(__DOXYGEN__) +/** + * @brief TMR6 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_TMR6_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_GPT +#if AT32_GPT_USE_TMR6 + gpt_lld_serve_interrupt(&GPTD6); +#endif +#endif +#if HAL_USE_ICU +#if AT32_ICU_USE_TMR6 + icu_lld_serve_interrupt(&ICUD6); +#endif +#endif +#if HAL_USE_PWM +#if AT32_PWM_USE_TMR6 + pwm_lld_serve_interrupt(&PWMD6); +#endif +#endif +#if 1 +#if AT32_ST_USE_TMR6 + st_lld_serve_interrupt(); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/TMRv1/at32_tmr7.inc b/os/hal/ports/AT32/LLD/TMRv1/at32_tmr7.inc new file mode 100644 index 0000000000..6e2317d06b --- /dev/null +++ b/os/hal/ports/AT32/LLD/TMRv1/at32_tmr7.inc @@ -0,0 +1,136 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file TMRv1/at32_tmr7.inc + * @brief Shared TMR7 handler. + * + * @addtogroup AT32_TMR7_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_TMR7) +#error "AT32_HAS_TMR7 not defined in registry" +#endif + +/* Driver checks for robustness, undefined USE macros are defaulted to + FALSE. This makes this module independent from drivers implementation.*/ +#if !defined(AT32_GPT_USE_TMR7) +#define AT32_GPT_USE_TMR7 FALSE +#endif +#if !defined(AT32_ICU_USE_TMR7) +#define AT32_ICU_USE_TMR7 FALSE +#endif +#if !defined(AT32_PWM_USE_TMR7) +#define AT32_PWM_USE_TMR7 FALSE +#endif +#if !defined(AT32_ST_USE_TMR7) +#define AT32_ST_USE_TMR7 FALSE +#endif + +#if AT32_HAS_TMR7 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_TMR7_PRIORITY) +#error "AT32_IRQ_TMR7_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_TMR7_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_TMR7_PRIORITY" +#endif + +#endif /* AT32_HAS_TMR7 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void tmr7_irq_init(void) { +#if defined(AT32_TMR7_IS_USED) + nvicEnableVector(AT32_TMR7_NUMBER, AT32_IRQ_TMR7_PRIORITY); +#endif +} + +static inline void tmr7_irq_deinit(void) { +#if defined(AT32_TMR7_IS_USED) + nvicDisableVector(AT32_TMR7_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_TMR7_IS_USED) || defined(__DOXYGEN__) +/** + * @brief TMR7 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_TMR7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_GPT +#if AT32_GPT_USE_TMR7 + gpt_lld_serve_interrupt(&GPTD7); +#endif +#endif +#if HAL_USE_ICU +#if AT32_ICU_USE_TMR7 + icu_lld_serve_interrupt(&ICUD7); +#endif +#endif +#if HAL_USE_PWM +#if AT32_PWM_USE_TMR7 + pwm_lld_serve_interrupt(&PWMD7); +#endif +#endif +#if 1 +#if AT32_ST_USE_TMR7 + st_lld_serve_interrupt(); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/at32_uart4.inc b/os/hal/ports/AT32/LLD/USARTv2/at32_uart4.inc new file mode 100644 index 0000000000..c07c8ff8c6 --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/at32_uart4.inc @@ -0,0 +1,111 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USART/at32_uart4.inc + * @brief Shared UART4 handler. + * + * @addtogroup AT32_UART4_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_UART4) +#error "AT32_HAS_UART4 not defined in registry" +#endif + +#if AT32_HAS_UART4 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_UART4_PRIORITY) +#error "AT32_IRQ_UART4_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_UART4_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_UART4_PRIORITY" +#endif + +#endif /* AT32_HAS_UART4 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void uart4_irq_init(void) { +#if defined(AT32_UART4_IS_USED) + nvicEnableVector(AT32_UART4_NUMBER, AT32_IRQ_UART4_PRIORITY); +#endif +} + +static inline void uart4_irq_deinit(void) { +#if defined(AT32_UART4_IS_USED) + nvicDisableVector(AT32_UART4_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_UART4_IS_USED) || defined(__DOXYGEN__) +/** + * @brief UART4 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART4_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_SERIAL +#if AT32_SERIAL_USE_UART4 + sd_lld_serve_interrupt(&SD4); +#endif +#endif + +#if HAL_USE_UART +#if AT32_UART_USE_UART4 + uart_lld_serve_interrupt(&UARTD4); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/at32_uart5.inc b/os/hal/ports/AT32/LLD/USARTv2/at32_uart5.inc new file mode 100644 index 0000000000..fff0dadae3 --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/at32_uart5.inc @@ -0,0 +1,111 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USART/at32_uart5.inc + * @brief Shared UART5 handler. + * + * @addtogroup AT32_UART5_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_UART5) +#error "AT32_HAS_UART5 not defined in registry" +#endif + +#if AT32_HAS_UART5 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_UART5_PRIORITY) +#error "AT32_IRQ_UART5_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_UART5_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_UART5_PRIORITY" +#endif + +#endif /* AT32_HAS_UART5 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void uart5_irq_init(void) { +#if defined(AT32_UART5_IS_USED) + nvicEnableVector(AT32_UART5_NUMBER, AT32_IRQ_UART5_PRIORITY); +#endif +} + +static inline void uart5_irq_deinit(void) { +#if defined(AT32_UART5_IS_USED) + nvicDisableVector(AT32_UART5_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_UART5_IS_USED) || defined(__DOXYGEN__) +/** + * @brief UART5 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART5_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_SERIAL +#if AT32_SERIAL_USE_UART5 + sd_lld_serve_interrupt(&SD5); +#endif +#endif + +#if HAL_USE_UART +#if AT32_UART_USE_UART5 + uart_lld_serve_interrupt(&UARTD5); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/at32_uart7.inc b/os/hal/ports/AT32/LLD/USARTv2/at32_uart7.inc new file mode 100644 index 0000000000..0ddf35dd0c --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/at32_uart7.inc @@ -0,0 +1,112 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USART/at32_uart7.inc + * @brief Shared UART7 handler. + * + * @addtogroup AT32_UART7_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_UART7) +#error "AT32_HAS_UART7 not defined in registry" +#endif + +#if AT32_HAS_UART7 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_UART7_PRIORITY) +#error "AT32_IRQ_UART7_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_UART7_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_UART7_PRIORITY" +#endif + +#endif /* AT32_HAS_UART7 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void uart7_irq_init(void) { +#if defined(AT32_UART7_IS_USED) + nvicEnableVector(AT32_UART7_NUMBER, AT32_IRQ_UART7_PRIORITY); +#endif +} + +static inline void uart7_irq_deinit(void) { +#if defined(AT32_UART7_IS_USED) + nvicDisableVector(AT32_UART7_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_UART7_IS_USED) || defined(__DOXYGEN__) +/** + * @brief UART7 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_SERIAL +#if AT32_SERIAL_USE_UART7 + sd_lld_serve_interrupt(&SD7); +#endif +#endif + +#if HAL_USE_UART +#if AT32_UART_USE_UART7 + uart_lld_serve_interrupt(&UARTD7); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/at32_uart8.inc b/os/hal/ports/AT32/LLD/USARTv2/at32_uart8.inc new file mode 100644 index 0000000000..3ec2763eb4 --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/at32_uart8.inc @@ -0,0 +1,112 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USART/at32_UART8.inc + * @brief Shared UART8 handler. + * + * @addtogroup AT32_UART8_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_UART8) +#error "AT32_HAS_UART8 not defined in registry" +#endif + +#if AT32_HAS_UART8 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_UART8_PRIORITY) +#error "AT32_IRQ_UART8_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_UART8_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_UART8_PRIORITY" +#endif + +#endif /* AT32_HAS_UART8 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void uart8_irq_init(void) { +#if defined(AT32_UART8_IS_USED) + nvicEnableVector(AT32_UART8_NUMBER, AT32_IRQ_UART8_PRIORITY); +#endif +} + +static inline void uart8_irq_deinit(void) { +#if defined(AT32_UART8_IS_USED) + nvicDisableVector(AT32_UART8_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_UART8_IS_USED) || defined(__DOXYGEN__) +/** + * @brief UART8 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART8_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_SERIAL +#if AT32_SERIAL_USE_UART8 + sd_lld_serve_interrupt(&SD8); +#endif +#endif + +#if HAL_USE_UART +#if AT32_UART_USE_UART8 + uart_lld_serve_interrupt(&UARTD8); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/at32_usart1.inc b/os/hal/ports/AT32/LLD/USARTv2/at32_usart1.inc new file mode 100644 index 0000000000..f215b4f7c7 --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/at32_usart1.inc @@ -0,0 +1,111 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USART/at32_usart1.inc + * @brief Shared USART1 handler. + * + * @addtogroup AT32_USART1_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_USART1) +#error "AT32_HAS_USART1 not defined in registry" +#endif + +#if AT32_HAS_USART1 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_USART1_PRIORITY) +#error "AT32_IRQ_USART1_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_USART1_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_USART1_PRIORITY" +#endif + +#endif /* AT32_HAS_USART1 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void usart1_irq_init(void) { +#if defined(AT32_USART1_IS_USED) + nvicEnableVector(AT32_USART1_NUMBER, AT32_IRQ_USART1_PRIORITY); +#endif +} + +static inline void usart1_irq_deinit(void) { +#if defined(AT32_USART1_IS_USED) + nvicDisableVector(AT32_USART1_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_USART1_IS_USED) || defined(__DOXYGEN__) +/** + * @brief USART1 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART1_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_SERIAL +#if AT32_SERIAL_USE_USART1 + sd_lld_serve_interrupt(&SD1); +#endif +#endif + +#if HAL_USE_UART +#if AT32_UART_USE_USART1 + uart_lld_serve_interrupt(&UARTD1); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/at32_usart2.inc b/os/hal/ports/AT32/LLD/USARTv2/at32_usart2.inc new file mode 100644 index 0000000000..1652352b72 --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/at32_usart2.inc @@ -0,0 +1,111 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USART/at32_usart2.inc + * @brief Shared USART2 handler. + * + * @addtogroup AT32_USART2_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_USART2) +#error "AT32_HAS_USART2 not defined in registry" +#endif + +#if AT32_HAS_USART2 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_USART2_PRIORITY) +#error "AT32_IRQ_USART2_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_USART2_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_USART2_PRIORITY" +#endif + +#endif /* AT32_HAS_USART2 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void usart2_irq_init(void) { +#if defined(AT32_USART2_IS_USED) + nvicEnableVector(AT32_USART2_NUMBER, AT32_IRQ_USART2_PRIORITY); +#endif +} + +static inline void usart2_irq_deinit(void) { +#if defined(AT32_USART2_IS_USED) + nvicDisableVector(AT32_USART2_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_USART2_IS_USED) || defined(__DOXYGEN__) +/** + * @brief USART2 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_SERIAL +#if AT32_SERIAL_USE_USART2 + sd_lld_serve_interrupt(&SD2); +#endif +#endif + +#if HAL_USE_UART +#if AT32_UART_USE_USART2 + uart_lld_serve_interrupt(&UARTD2); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/at32_usart3.inc b/os/hal/ports/AT32/LLD/USARTv2/at32_usart3.inc new file mode 100644 index 0000000000..a00a1a09ad --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/at32_usart3.inc @@ -0,0 +1,111 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USART/at32_usart3.inc + * @brief Shared USART3 handler. + * + * @addtogroup AT32_USART3_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_USART3) +#error "AT32_HAS_USART3 not defined in registry" +#endif + +#if AT32_HAS_USART3 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_USART3_PRIORITY) +#error "AT32_IRQ_USART3_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_USART3_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_USART3_PRIORITY" +#endif + +#endif /* AT32_HAS_USART3 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void usart3_irq_init(void) { +#if defined(AT32_USART3_IS_USED) + nvicEnableVector(AT32_USART3_NUMBER, AT32_IRQ_USART3_PRIORITY); +#endif +} + +static inline void usart3_irq_deinit(void) { +#if defined(AT32_USART3_IS_USED) + nvicDisableVector(AT32_USART3_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_USART3_IS_USED) || defined(__DOXYGEN__) +/** + * @brief USART3 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART3_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_SERIAL +#if AT32_SERIAL_USE_USART3 + sd_lld_serve_interrupt(&SD3); +#endif +#endif + +#if HAL_USE_UART +#if AT32_UART_USE_USART3 + uart_lld_serve_interrupt(&UARTD3); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/at32_usart6.inc b/os/hal/ports/AT32/LLD/USARTv2/at32_usart6.inc new file mode 100644 index 0000000000..cedbc7a285 --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/at32_usart6.inc @@ -0,0 +1,112 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USART/at32_usart6.inc + * @brief Shared USART6 handler. + * + * @addtogroup AT32_USART6_HANDLER + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Registry checks for robustness.*/ +#if !defined(AT32_HAS_USART6) +#error "AT32_HAS_USART6 not defined in registry" +#endif + +#if AT32_HAS_USART6 + +/* Priority settings checks.*/ +#if !defined(AT32_IRQ_USART6_PRIORITY) +#error "AT32_IRQ_USART6_PRIORITY not defined in mcuconf.h" +#endif + +#if !OSAL_IRQ_IS_VALID_PRIORITY(AT32_IRQ_USART6_PRIORITY) +#error "Invalid IRQ priority assigned to AT32_IRQ_USART6_PRIORITY" +#endif + +#endif /* AT32_HAS_USART6 */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void usart6_irq_init(void) { +#if defined(AT32_USART6_IS_USED) + nvicEnableVector(AT32_USART6_NUMBER, AT32_IRQ_USART6_PRIORITY); +#endif +} + +static inline void usart6_irq_deinit(void) { +#if defined(AT32_USART6_IS_USED) + nvicDisableVector(AT32_USART6_NUMBER); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(AT32_USART6_IS_USED) || defined(__DOXYGEN__) +/** + * @brief USART6 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART6_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + +#if HAL_USE_SERIAL +#if AT32_SERIAL_USE_USART6 + sd_lld_serve_interrupt(&SD6); +#endif +#endif + +#if HAL_USE_UART +#if AT32_UART_USE_USART6 + uart_lld_serve_interrupt(&UARTD6); +#endif +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/driver.mk b/os/hal/ports/AT32/LLD/USARTv2/driver.mk new file mode 100644 index 0000000000..65b0977e25 --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/driver.mk @@ -0,0 +1,13 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),) +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/USARTv2/hal_serial_lld.c +endif +ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),) +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/USARTv2/hal_uart_lld.c +endif +else +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/USARTv2/hal_serial_lld.c +PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/USARTv2/hal_uart_lld.c +endif + +PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/ports/AT32/LLD/USARTv2 diff --git a/os/hal/ports/AT32/LLD/USARTv2/hal_serial_lld.c b/os/hal/ports/AT32/LLD/USARTv2/hal_serial_lld.c new file mode 100644 index 0000000000..ecfbc5fb2b --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/hal_serial_lld.c @@ -0,0 +1,679 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USARTv2/hal_serial_lld.c + * @brief AT32 low level serial driver code. + * + * @addtogroup SERIAL + * @{ + */ + +#include "hal.h" + +#if HAL_USE_SERIAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief USART1 serial driver identifier.*/ +#if AT32_SERIAL_USE_USART1 || defined(__DOXYGEN__) +SerialDriver SD1; +#endif + +/** @brief USART2 serial driver identifier.*/ +#if AT32_SERIAL_USE_USART2 || defined(__DOXYGEN__) +SerialDriver SD2; +#endif + +/** @brief USART3 serial driver identifier.*/ +#if AT32_SERIAL_USE_USART3 || defined(__DOXYGEN__) +SerialDriver SD3; +#endif + +/** @brief UART4 serial driver identifier.*/ +#if AT32_SERIAL_USE_UART4 || defined(__DOXYGEN__) +SerialDriver SD4; +#endif + +/** @brief UART5 serial driver identifier.*/ +#if AT32_SERIAL_USE_UART5 || defined(__DOXYGEN__) +SerialDriver SD5; +#endif + +/** @brief USART6 serial driver identifier.*/ +#if AT32_SERIAL_USE_USART6 || defined(__DOXYGEN__) +SerialDriver SD6; +#endif + +/** @brief UART7 serial driver identifier.*/ +#if AT32_SERIAL_USE_UART7 || defined(__DOXYGEN__) +SerialDriver SD7; +#endif + +/** @brief UART8 serial driver identifier.*/ +#if AT32_SERIAL_USE_UART8 || defined(__DOXYGEN__) +SerialDriver SD8; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** @brief Driver default configuration.*/ +static const SerialConfig default_config = +{ + SERIAL_DEFAULT_BITRATE, + 0, + USART_CTRL2_STOPBN1_BITS, + 0 +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief USART initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] config the architecture-dependent serial driver configuration + */ +static void usart_init(SerialDriver *sdp, const SerialConfig *config) { + uint32_t baudr; + USART_TypeDef *u = sdp->usart; + + baudr = (uint32_t)((sdp->clock + config->speed/2) / config->speed); + + osalDbgAssert(baudr < 0x10000, "invalid BAUDR value"); + + u->BAUDR = baudr; + + /* Note that some bits are enforced.*/ + u->CTRL2 = config->ctrl2 | USART_CTRL2_BFIEN; + u->CTRL3 = config->ctrl3 | USART_CTRL3_ERRIEN; + u->CTRL1 = config->ctrl1 | USART_CTRL1_UEN | USART_CTRL1_PERRIEN | + USART_CTRL1_RDBFIEN | USART_CTRL1_TEN | + USART_CTRL1_REN; + u->STS = 0; + (void)u->STS; /* STS reset step 1.*/ + (void)u->DT; /* STS reset step 2.*/ + + /* Deciding mask to be applied on the data register on receive, this is + required in order to mask out the parity bit.*/ + if ((config->ctrl1 & (USART_CTRL1_DBN | USART_CTRL1_PEN)) == USART_CTRL1_PEN) { + sdp->rxmask = 0x7F; + } + else { + sdp->rxmask = 0xFF; + } +} + +/** + * @brief USART de-initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] u pointer to an USART I/O block + */ +static void usart_deinit(USART_TypeDef *u) { + + u->CTRL1 = 0; + u->CTRL2 = 0; + u->CTRL3 = 0; +} + +/** + * @brief Error handling routine. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] sts USART STS register value + */ +static void set_error(SerialDriver *sdp, uint16_t sts) { + eventflags_t status = 0; + + if (sts & USART_STS_ROERR) + status |= SD_OVERRUN_ERROR; + if (sts & USART_STS_PERR) + status |= SD_PARITY_ERROR; + if (sts & USART_STS_FERR) + status |= SD_FRAMING_ERROR; + if (sts & USART_STS_NERR) + status |= SD_NOISE_ERROR; + chnAddFlagsI(sdp, status); +} + +#if AT32_SERIAL_USE_USART1 || defined(__DOXYGEN__) +static void notify1(io_queue_t *qp) { + + (void)qp; + USART1->CTRL1 |= USART_CTRL1_TDBEIEN | USART_CTRL1_TDCIEN; +} +#endif + +#if AT32_SERIAL_USE_USART2 || defined(__DOXYGEN__) +static void notify2(io_queue_t *qp) { + + (void)qp; + USART2->CTRL1 |= USART_CTRL1_TDBEIEN | USART_CTRL1_TDCIEN; +} +#endif + +#if AT32_SERIAL_USE_USART3 || defined(__DOXYGEN__) +static void notify3(io_queue_t *qp) { + + (void)qp; + USART3->CTRL1 |= USART_CTRL1_TDBEIEN | USART_CTRL1_TDCIEN; +} +#endif + +#if AT32_SERIAL_USE_UART4 || defined(__DOXYGEN__) +static void notify4(io_queue_t *qp) { + + (void)qp; + UART4->CTRL1 |= USART_CTRL1_TDBEIEN | USART_CTRL1_TDCIEN; +} +#endif + +#if AT32_SERIAL_USE_UART5 || defined(__DOXYGEN__) +static void notify5(io_queue_t *qp) { + + (void)qp; + UART5->CTRL1 |= USART_CTRL1_TDBEIEN | USART_CTRL1_TDCIEN; +} +#endif + +#if AT32_SERIAL_USE_USART6 || defined(__DOXYGEN__) +static void notify6(io_queue_t *qp) { + + (void)qp; + USART6->CTRL1 |= USART_CTRL1_TDBEIEN | USART_CTRL1_TDCIEN; +} +#endif + +#if AT32_SERIAL_USE_UART7 || defined(__DOXYGEN__) +static void notify7(io_queue_t *qp) { + + (void)qp; + UART7->CTRL1 |= USART_CTRL1_TDBEIEN | USART_CTRL1_TDCIEN; +} +#endif + +#if AT32_SERIAL_USE_UART8 || defined(__DOXYGEN__) +static void notify8(io_queue_t *qp) { + + (void)qp; + UART8->CTRL1 |= USART_CTRL1_TDBEIEN | USART_CTRL1_TDCIEN; +} +#endif + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if AT32_SERIAL_USE_USART1 || defined(__DOXYGEN__) +#if !defined(AT32_USART1_SUPPRESS_ISR) +#if !defined(AT32_USART1_HANDLER) +#error "AT32_USART1_HANDLER not defined" +#endif +/** + * @brief USART1 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART1_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + sd_lld_serve_interrupt(&SD1); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif + +#if AT32_SERIAL_USE_USART2 || defined(__DOXYGEN__) +#if !defined(AT32_USART2_SUPPRESS_ISR) +#if !defined(AT32_USART2_HANDLER) +#error "AT32_USART2_HANDLER not defined" +#endif +/** + * @brief USART2 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + sd_lld_serve_interrupt(&SD2); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif + +#if AT32_SERIAL_USE_USART3 || defined(__DOXYGEN__) +#if !defined(AT32_USART3_SUPPRESS_ISR) +#if !defined(AT32_USART3_HANDLER) +#error "AT32_USART3_HANDLER not defined" +#endif +/** + * @brief USART3 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART3_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + sd_lld_serve_interrupt(&SD3); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif + +#if AT32_SERIAL_USE_UART4 || defined(__DOXYGEN__) +#if !defined(AT32_UART4_SUPPRESS_ISR) +#if !defined(AT32_UART4_HANDLER) +#error "AT32_UART4_HANDLER not defined" +#endif +/** + * @brief UART4 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART4_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + sd_lld_serve_interrupt(&SD4); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif + +#if AT32_SERIAL_USE_UART5 || defined(__DOXYGEN__) +#if !defined(AT32_UART5_SUPPRESS_ISR) +#if !defined(AT32_UART5_HANDLER) +#error "AT32_UART5_HANDLER not defined" +#endif +/** + * @brief UART5 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART5_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + sd_lld_serve_interrupt(&SD5); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif + +#if AT32_SERIAL_USE_USART6 || defined(__DOXYGEN__) +#if !defined(AT32_USART6_SUPPRESS_ISR) +#if !defined(AT32_USART6_HANDLER) +#error "AT32_USART6_HANDLER not defined" +#endif +/** + * @brief USART6 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART6_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + sd_lld_serve_interrupt(&SD6); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif + +#if AT32_SERIAL_USE_UART7 || defined(__DOXYGEN__) +#if !defined(AT32_UART7_SUPPRESS_ISR) +#if !defined(AT32_UART7_HANDLER) +#error "AT32_UART7_HANDLER not defined" +#endif +/** + * @brief UART7 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + sd_lld_serve_interrupt(&SD7); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif + +#if AT32_SERIAL_USE_UART8 || defined(__DOXYGEN__) +#if !defined(AT32_UART8_SUPPRESS_ISR) +#if !defined(AT32_UART8_HANDLER) +#error "AT32_UART8_HANDLER not defined" +#endif +/** + * @brief UART8 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART8_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + sd_lld_serve_interrupt(&SD8); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level serial driver initialization. + * + * @notapi + */ +void sd_lld_init(void) { + +#if AT32_SERIAL_USE_USART1 + sdObjectInit(&SD1, NULL, notify1); + SD1.usart = USART1; + SD1.clock = AT32_PCLK2; +#if !defined(AT32_USART1_SUPPRESS_ISR) && defined(AT32_USART1_NUMBER) + nvicEnableVector(AT32_USART1_NUMBER, AT32_SERIAL_USART1_PRIORITY); +#endif +#endif + +#if AT32_SERIAL_USE_USART2 + sdObjectInit(&SD2, NULL, notify2); + SD2.usart = USART2; + SD2.clock = AT32_PCLK1; +#if !defined(AT32_USART2_SUPPRESS_ISR) && defined(AT32_USART2_NUMBER) + nvicEnableVector(AT32_USART2_NUMBER, AT32_SERIAL_USART2_PRIORITY); +#endif +#endif + +#if AT32_SERIAL_USE_USART3 + sdObjectInit(&SD3, NULL, notify3); + SD3.usart = USART3; + SD3.clock = AT32_PCLK1; +#if !defined(AT32_USART3_SUPPRESS_ISR) && defined(AT32_USART3_NUMBER) + nvicEnableVector(AT32_USART3_NUMBER, AT32_SERIAL_USART3_PRIORITY); +#endif +#endif + +#if AT32_SERIAL_USE_UART4 + sdObjectInit(&SD4, NULL, notify4); + SD4.usart = UART4; + SD4.clock = AT32_PCLK1; +#if !defined(AT32_UART4_SUPPRESS_ISR) && defined(AT32_UART4_NUMBER) + nvicEnableVector(AT32_UART4_NUMBER, AT32_SERIAL_UART4_PRIORITY); +#endif +#endif + +#if AT32_SERIAL_USE_UART5 + sdObjectInit(&SD5, NULL, notify5); + SD5.usart = UART5; + SD5.clock = AT32_PCLK1; +#if !defined(AT32_UART5_SUPPRESS_ISR) && defined(AT32_UART5_NUMBER) + nvicEnableVector(AT32_UART5_NUMBER, AT32_SERIAL_UART5_PRIORITY); +#endif +#endif + +#if AT32_SERIAL_USE_USART6 + sdObjectInit(&SD6, NULL, notify3); + SD6.usart = USART6; + SD6.clock = AT32_PCLK2; +#if !defined(AT32_USART6_SUPPRESS_ISR) && defined(AT32_USART6_NUMBER) + nvicEnableVector(AT32_USART6_NUMBER, AT32_SERIAL_USART6_PRIORITY); +#endif +#endif + +#if AT32_SERIAL_USE_UART7 + sdObjectInit(&SD7, NULL, notify4); + SD7.usart = UART7; + SD7.clock = AT32_PCLK1; +#if !defined(AT32_UART7_SUPPRESS_ISR) && defined(AT32_UART7_NUMBER) + nvicEnableVector(AT32_UART7_NUMBER, AT32_SERIAL_UART7_PRIORITY); +#endif +#endif + +#if AT32_SERIAL_USE_UART8 + sdObjectInit(&SD8, NULL, notify5); + SD8.usart = UART8; + SD8.clock = AT32_PCLK1; +#if !defined(AT32_UART8_SUPPRESS_ISR) && defined(AT32_UART8_NUMBER) + nvicEnableVector(AT32_UART8_NUMBER, AT32_SERIAL_UART8_PRIORITY); +#endif +#endif + +} + +/** + * @brief Low level serial driver configuration and (re)start. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] config the architecture-dependent serial driver configuration. + * If this parameter is set to @p NULL then a default + * configuration is used. + * + * @notapi + */ +void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { + + if (config == NULL) + config = &default_config; + + if (sdp->state == SD_STOP) { +#if AT32_SERIAL_USE_USART1 + if (&SD1 == sdp) { + crmEnableUSART1(true); + } +#endif +#if AT32_SERIAL_USE_USART2 + if (&SD2 == sdp) { + crmEnableUSART2(true); + } +#endif +#if AT32_SERIAL_USE_USART3 + if (&SD3 == sdp) { + crmEnableUSART3(true); + } +#endif +#if AT32_SERIAL_USE_UART4 + if (&SD4 == sdp) { + crmEnableUART4(true); + } +#endif +#if AT32_SERIAL_USE_UART5 + if (&SD5 == sdp) { + crmEnableUART5(true); + } +#endif +#if AT32_SERIAL_USE_USART6 + if (&SD6 == sdp) { + crmEnableUSART6(true); + } +#endif +#if AT32_SERIAL_USE_UART7 + if (&SD7 == sdp) { + crmEnableUART7(true); + } +#endif +#if AT32_SERIAL_USE_UART8 + if (&SD8 == sdp) { + crmEnableUART8(true); + } +#endif + } + usart_init(sdp, config); +} + +/** + * @brief Low level serial driver stop. + * @details De-initializes the USART, stops the associated clock, resets the + * interrupt vector. + * + * @param[in] sdp pointer to a @p SerialDriver object + * + * @notapi + */ +void sd_lld_stop(SerialDriver *sdp) { + + if (sdp->state == SD_READY) { + usart_deinit(sdp->usart); +#if AT32_SERIAL_USE_USART1 + if (&SD1 == sdp) { + crmDisableUSART1(); + return; + } +#endif +#if AT32_SERIAL_USE_USART2 + if (&SD2 == sdp) { + crmDisableUSART2(); + return; + } +#endif +#if AT32_SERIAL_USE_USART3 + if (&SD3 == sdp) { + crmDisableUSART3(); + return; + } +#endif +#if AT32_SERIAL_USE_UART4 + if (&SD4 == sdp) { + crmDisableUART4(); + return; + } +#endif +#if AT32_SERIAL_USE_UART5 + if (&SD5 == sdp) { + crmDisableUART5(); + return; + } +#endif +#if AT32_SERIAL_USE_USART6 + if (&SD6 == sdp) { + crmDisableUSART6(); + return; + } +#endif +#if AT32_SERIAL_USE_UART7 + if (&SD7 == sdp) { + crmDisableUART7(); + return; + } +#endif +#if AT32_SERIAL_USE_UART8 + if (&SD8 == sdp) { + crmDisableUART8(); + return; + } +#endif + } +} + +/** + * @brief Common IRQ handler. + * + * @param[in] sdp communication channel associated to the USART + */ +void sd_lld_serve_interrupt(SerialDriver *sdp) { + USART_TypeDef *u = sdp->usart; + uint16_t ctrl1; + uint16_t sts = u->STS; + + /* Special case, LIN break detection.*/ + if (sts & USART_STS_BFF) { + osalSysLockFromISR(); + chnAddFlagsI(sdp, SD_BREAK_DETECTED); + u->STS = ~USART_STS_BFF; + osalSysUnlockFromISR(); + } + + /* Data available.*/ + osalSysLockFromISR(); + while (sts & (USART_STS_RDBF | USART_STS_ROERR | USART_STS_NERR | USART_STS_FERR | + USART_STS_PERR)) { + uint8_t b; + + /* Error condition detection.*/ + if (sts & (USART_STS_ROERR | USART_STS_NERR | USART_STS_FERR | USART_STS_PERR)) + set_error(sdp, sts); + b = (uint8_t)u->DT & sdp->rxmask; + if (sts & USART_STS_RDBF) + sdIncomingDataI(sdp, b); + sts = u->STS; + } + osalSysUnlockFromISR(); + + /* Caching CTRL1.*/ + ctrl1 = u->CTRL1; + + /* Transmission buffer empty.*/ + if ((ctrl1 & USART_CTRL1_TDBEIEN) && (sts & USART_STS_TDBE)) { + msg_t b; + osalSysLockFromISR(); + b = oqGetI(&sdp->oqueue); + if (b < MSG_OK) { + chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); + ctrl1 &= ~USART_CTRL1_TDBEIEN; + } + else + u->DT = b; + osalSysUnlockFromISR(); + } + + /* Physical transmission end.*/ + if ((ctrl1 & USART_CTRL1_TDCIEN) && (sts & USART_STS_TDC)) { + osalSysLockFromISR(); + if (oqIsEmptyI(&sdp->oqueue)) { + chnAddFlagsI(sdp, CHN_TRANSMISSION_END); + ctrl1 &= ~USART_CTRL1_TDCIEN; + } + osalSysUnlockFromISR(); + } + + /* Writing CTRL1 once.*/ + u->CTRL1 = ctrl1; +} + +#endif /* HAL_USE_SERIAL */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/hal_serial_lld.h b/os/hal/ports/AT32/LLD/USARTv2/hal_serial_lld.h new file mode 100644 index 0000000000..86998e70cd --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/hal_serial_lld.h @@ -0,0 +1,434 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USARTv2/hal_serial_lld.h + * @brief AT32 low level serial driver header. + * + * @addtogroup SERIAL + * @{ + */ + +#ifndef HAL_SERIAL_LLD_H +#define HAL_SERIAL_LLD_H + +#if HAL_USE_SERIAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief USART1 driver enable switch. + * @details If set to @p TRUE the support for USART1 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SERIAL_USE_USART1) || defined(__DOXYGEN__) +#define AT32_SERIAL_USE_USART1 FALSE +#endif + +/** + * @brief USART2 driver enable switch. + * @details If set to @p TRUE the support for USART2 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SERIAL_USE_USART2) || defined(__DOXYGEN__) +#define AT32_SERIAL_USE_USART2 FALSE +#endif + +/** + * @brief USART3 driver enable switch. + * @details If set to @p TRUE the support for USART3 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SERIAL_USE_USART3) || defined(__DOXYGEN__) +#define AT32_SERIAL_USE_USART3 FALSE +#endif + +/** + * @brief UART4 driver enable switch. + * @details If set to @p TRUE the support for UART4 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SERIAL_USE_UART4) || defined(__DOXYGEN__) +#define AT32_SERIAL_USE_UART4 FALSE +#endif + +/** + * @brief UART5 driver enable switch. + * @details If set to @p TRUE the support for UART5 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SERIAL_USE_UART5) || defined(__DOXYGEN__) +#define AT32_SERIAL_USE_UART5 FALSE +#endif + +/** + * @brief USART6 driver enable switch. + * @details If set to @p TRUE the support for USART6 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SERIAL_USE_USART6) || defined(__DOXYGEN__) +#define AT32_SERIAL_USE_USART6 FALSE +#endif + +/** + * @brief UART7 driver enable switch. + * @details If set to @p TRUE the support for UART7 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SERIAL_USE_UART7) || defined(__DOXYGEN__) +#define AT32_SERIAL_USE_UART7 FALSE +#endif + +/** + * @brief UART8 driver enable switch. + * @details If set to @p TRUE the support for UART8 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_SERIAL_USE_UART8) || defined(__DOXYGEN__) +#define AT32_SERIAL_USE_UART8 FALSE +#endif + +/** + * @brief USART1 interrupt priority level setting. + */ +#if !defined(AT32_SERIAL_USART1_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SERIAL_USART1_PRIORITY 12 +#endif + +/** + * @brief USART2 interrupt priority level setting. + */ +#if !defined(AT32_SERIAL_USART2_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SERIAL_USART2_PRIORITY 12 +#endif + +/** + * @brief USART3 interrupt priority level setting. + */ +#if !defined(AT32_SERIAL_USART3_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SERIAL_USART3_PRIORITY 12 +#endif + +/** + * @brief UART4 interrupt priority level setting. + */ +#if !defined(AT32_SERIAL_UART4_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SERIAL_UART4_PRIORITY 12 +#endif + +/** + * @brief UART5 interrupt priority level setting. + */ +#if !defined(AT32_SERIAL_UART5_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SERIAL_UART5_PRIORITY 12 +#endif + +/** + * @brief USART6 interrupt priority level setting. + */ +#if !defined(AT32_SERIAL_USART6_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SERIAL_USART6_PRIORITY 12 +#endif + +/** + * @brief UART7 interrupt priority level setting. + */ +#if !defined(AT32_SERIAL_UART7_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SERIAL_UART7_PRIORITY 12 +#endif + +/** + * @brief UART8 interrupt priority level setting. + */ +#if !defined(AT32_SERIAL_UART8_PRIORITY) || defined(__DOXYGEN__) +#define AT32_SERIAL_UART8_PRIORITY 12 +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if AT32_SERIAL_USE_USART1 && !AT32_HAS_USART1 +#error "USART1 not present in the selected device" +#endif + +#if AT32_SERIAL_USE_USART2 && !AT32_HAS_USART2 +#error "USART2 not present in the selected device" +#endif + +#if AT32_SERIAL_USE_USART3 && !AT32_HAS_USART3 +#error "USART3 not present in the selected device" +#endif + +#if AT32_SERIAL_USE_UART4 && !AT32_HAS_UART4 +#error "UART4 not present in the selected device" +#endif + +#if AT32_SERIAL_USE_UART5 && !AT32_HAS_UART5 +#error "UART5 not present in the selected device" +#endif + +#if AT32_SERIAL_USE_USART6 && !AT32_HAS_USART6 +#error "USART6 not present in the selected device" +#endif + +#if AT32_SERIAL_USE_UART7 && !AT32_HAS_UART7 +#error "UART7 not present in the selected device" +#endif + +#if AT32_SERIAL_USE_UART8 && !AT32_HAS_UART8 +#error "UART8 not present in the selected device" +#endif + +#if !AT32_SERIAL_USE_USART1 && !AT32_SERIAL_USE_USART2 && \ + !AT32_SERIAL_USE_USART3 && !AT32_SERIAL_USE_UART4 && \ + !AT32_SERIAL_USE_UART5 && !AT32_SERIAL_USE_USART6 && \ + !AT32_SERIAL_USE_UART7 && !AT32_SERIAL_USE_UART8 +#error "SERIAL driver activated but no USART/UART peripheral assigned" +#endif + +#if AT32_SERIAL_USE_USART1 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SERIAL_USART1_PRIORITY) +#error "Invalid IRQ priority assigned to USART1" +#endif + +#if AT32_SERIAL_USE_USART2 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SERIAL_USART2_PRIORITY) +#error "Invalid IRQ priority assigned to USART2" +#endif + +#if AT32_SERIAL_USE_USART3 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SERIAL_USART3_PRIORITY) +#error "Invalid IRQ priority assigned to USART3" +#endif + +#if AT32_SERIAL_USE_UART4 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SERIAL_UART4_PRIORITY) +#error "Invalid IRQ priority assigned to UART4" +#endif + +#if AT32_SERIAL_USE_UART5 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SERIAL_UART5_PRIORITY) +#error "Invalid IRQ priority assigned to UART5" +#endif + +#if AT32_SERIAL_USE_USART6 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SERIAL_USART6_PRIORITY) +#error "Invalid IRQ priority assigned to USART6" +#endif + +#if AT32_SERIAL_USE_UART7 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SERIAL_UART7_PRIORITY) +#error "Invalid IRQ priority assigned to UART7" +#endif + +#if AT32_SERIAL_USE_UART8 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_SERIAL_UART8_PRIORITY) +#error "Invalid IRQ priority assigned to UART8" +#endif + +/* Checks on allocation of USARTx units.*/ +#if AT32_SERIAL_USE_USART1 +#if defined(AT32_USART1_IS_USED) +#error "SD1 requires USART1 but it is already used" +#else +#define AT32_USART1_IS_USED +#endif +#endif + +#if AT32_SERIAL_USE_USART2 +#if defined(AT32_USART2_IS_USED) +#error "SD2 requires USART2 but it is already used" +#else +#define AT32_USART2_IS_USED +#endif +#endif + +#if AT32_SERIAL_USE_USART3 +#if defined(AT32_USART3_IS_USED) +#error "SD3 requires USART3 but it is already used" +#else +#define AT32_USART3_IS_USED +#endif +#endif + +#if AT32_SERIAL_USE_UART4 +#if defined(AT32_UART4_IS_USED) +#error "SD4 requires UART4 but it is already used" +#else +#define AT32_UART4_IS_USED +#endif +#endif + +#if AT32_SERIAL_USE_UART5 +#if defined(AT32_UART5_IS_USED) +#error "SD5 requires UART5 but it is already used" +#else +#define AT32_UART5_IS_USED +#endif +#endif + +#if AT32_SERIAL_USE_USART6 +#if defined(AT32_USART6_IS_USED) +#error "SD6 requires USART6 but it is already used" +#else +#define AT32_USART6_IS_USED +#endif +#endif + +#if AT32_SERIAL_USE_UART7 +#if defined(AT32_UART7_IS_USED) +#error "SD7 requires UART7 but it is already used" +#else +#define AT32_UART7_IS_USED +#endif +#endif + +#if AT32_SERIAL_USE_UART8 +#if defined(AT32_UART8_IS_USED) +#error "SD8 requires UART8 but it is already used" +#else +#define AT32_UART8_IS_USED +#endif +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief AT32 Serial Driver configuration structure. + * @details An instance of this structure must be passed to @p sdStart() + * in order to configure and start a serial driver operations. + * @note This structure content is architecture dependent, each driver + * implementation defines its own version and the custom static + * initializers. + */ +typedef struct hal_serial_config { + /** + * @brief Bit rate. + */ + uint32_t speed; + /* End of the mandatory fields.*/ + /** + * @brief Initialization value for the CTRL1 register. + */ + uint16_t ctrl1; + /** + * @brief Initialization value for the CTRL2 register. + */ + uint16_t ctrl2; + /** + * @brief Initialization value for the CTRL3 register. + */ + uint16_t ctrl3; +} SerialConfig; + +/** + * @brief @p SerialDriver specific data. + */ +#define _serial_driver_data \ + _base_asynchronous_channel_data \ + /* Driver state.*/ \ + sdstate_t state; \ + /* Input queue.*/ \ + input_queue_t iqueue; \ + /* Output queue.*/ \ + output_queue_t oqueue; \ + /* Input circular buffer.*/ \ + uint8_t ib[SERIAL_BUFFERS_SIZE]; \ + /* Output circular buffer.*/ \ + uint8_t ob[SERIAL_BUFFERS_SIZE]; \ + /* End of the mandatory fields.*/ \ + /* Pointer to the USART registers block.*/ \ + USART_TypeDef *usart; \ + /* Clock frequency for the associated USART/UART.*/ \ + uint32_t clock; \ + /* Mask to be applied on received frames.*/ \ + uint8_t rxmask; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/* + * Extra USARTs definitions here (missing from the AT header file). + */ +#define USART_CTRL2_STOPBN1_BITS (0 << 12) /**< @brief CTRL2 1 stop bit value.*/ +#define USART_CTRL2_STOPBN0P5_BITS (1 << 12) /**< @brief CTRL2 0.5 stop bit value.*/ +#define USART_CTRL2_STOPBN2_BITS (2 << 12) /**< @brief CTRL2 2 stop bit value.*/ +#define USART_CTRL2_STOPBN1P5_BITS (3 << 12) /**< @brief CTRL2 1.5 stop bit value.*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if AT32_SERIAL_USE_USART1 && !defined(__DOXYGEN__) +extern SerialDriver SD1; +#endif +#if AT32_SERIAL_USE_USART2 && !defined(__DOXYGEN__) +extern SerialDriver SD2; +#endif +#if AT32_SERIAL_USE_USART3 && !defined(__DOXYGEN__) +extern SerialDriver SD3; +#endif +#if AT32_SERIAL_USE_UART4 && !defined(__DOXYGEN__) +extern SerialDriver SD4; +#endif +#if AT32_SERIAL_USE_UART5 && !defined(__DOXYGEN__) +extern SerialDriver SD5; +#endif +#if AT32_SERIAL_USE_USART6 && !defined(__DOXYGEN__) +extern SerialDriver SD6; +#endif +#if AT32_SERIAL_USE_UART7 && !defined(__DOXYGEN__) +extern SerialDriver SD7; +#endif +#if AT32_SERIAL_USE_UART8 && !defined(__DOXYGEN__) +extern SerialDriver SD8; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void sd_lld_init(void); + void sd_lld_start(SerialDriver *sdp, const SerialConfig *config); + void sd_lld_stop(SerialDriver *sdp); + void sd_lld_serve_interrupt(SerialDriver *sdp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_SERIAL */ + +#endif /* HAL_SERIAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/hal_uart_lld.c b/os/hal/ports/AT32/LLD/USARTv2/hal_uart_lld.c new file mode 100644 index 0000000000..a8c507490c --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/hal_uart_lld.c @@ -0,0 +1,983 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USARTv2/hal_uart_lld.c + * @brief AT32 low level UART driver code. + * + * @addtogroup UART + * @{ + */ + +#include "hal.h" + +#if HAL_USE_UART || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define AT32_UART_CTRL2_CHECK_MASK \ + (USART_CTRL2_STOP_0 | USART_CTRL2_CLKEN | USART_CTRL2_CLKPOL | \ + USART_CTRL2_CLKPHA | USART_CTRL2_LBCP) + +#define AT32_UART_CTRL3_CHECK_MASK \ + (USART_CTRL3_CTSCFIEN | USART_CTRL3_CTSEN | USART_CTRL3_RTSEN | \ + USART_CTRL3_SCMEN | USART_CTRL3_SCNACKEN) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief USART1 UART driver identifier.*/ +#if AT32_UART_USE_USART1 || defined(__DOXYGEN__) +UARTDriver UARTD1; +#endif + +/** @brief USART2 UART driver identifier.*/ +#if AT32_UART_USE_USART2 || defined(__DOXYGEN__) +UARTDriver UARTD2; +#endif + +/** @brief USART3 UART driver identifier.*/ +#if AT32_UART_USE_USART3 || defined(__DOXYGEN__) +UARTDriver UARTD3; +#endif + +/** @brief UART4 UART driver identifier.*/ +#if AT32_UART_USE_UART4 || defined(__DOXYGEN__) +UARTDriver UARTD4; +#endif + +/** @brief UART5 UART driver identifier.*/ +#if AT32_UART_USE_UART5 || defined(__DOXYGEN__) +UARTDriver UARTD5; +#endif + +/** @brief USART6 UART driver identifier.*/ +#if AT32_UART_USE_USART6 || defined(__DOXYGEN__) +UARTDriver UARTD6; +#endif + +/** @brief UART7 UART driver identifier.*/ +#if AT32_UART_USE_UART7 || defined(__DOXYGEN__) +UARTDriver UARTD7; +#endif + +/** @brief UART8 UART driver identifier.*/ +#if AT32_UART_USE_UART8 || defined(__DOXYGEN__) +UARTDriver UARTD8; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Status bits translation. + * + * @param[in] sts USART STS register value + * + * @return The error flags. + */ +static uartflags_t translate_errors(uint16_t sts) { + uartflags_t status = 0; + + if (sts & USART_STS_ROERR) + status |= UART_OVERRUN_ERROR; + if (sts & USART_STS_PERR) + status |= UART_PARITY_ERROR; + if (sts & USART_STS_FERR) + status |= UART_FRAMING_ERROR; + if (sts & USART_STS_NERR) + status |= UART_NOISE_ERROR; + if (sts & USART_STS_BFF) + status |= UART_BREAK_DETECTED; + return status; +} + +/** + * @brief Puts the receiver in the UART_RX_IDLE state. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void uart_enter_rx_idle_loop(UARTDriver *uartp) { + uint32_t mode; + + /* RX DMA channel preparation, if the char callback is defined then the + FDTIEN interrupt is enabled too.*/ + if (uartp->config->rxchar_cb == NULL) + mode = AT32_DMA_CCTRL_DTD_P2M | AT32_DMA_CCTRL_LM; + else + mode = AT32_DMA_CCTRL_DTD_P2M | AT32_DMA_CCTRL_LM | AT32_DMA_CCTRL_FDTIEN; + dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, 1); + dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | mode); + dmaStreamEnable(uartp->dmarx); +} + +/** + * @brief USART de-initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void usart_stop(UARTDriver *uartp) { + + /* Stops RX and TX DMA channels.*/ + dmaStreamDisable(uartp->dmarx); + dmaStreamDisable(uartp->dmatx); + + /* Stops USART operations.*/ + uartp->usart->CTRL1 = 0; + uartp->usart->CTRL2 = 0; + uartp->usart->CTRL3 = 0; +} + +/** + * @brief USART initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +static void usart_start(UARTDriver *uartp) { + uint32_t baudr; + uint16_t ctrl1; + USART_TypeDef *u = uartp->usart; + + /* Defensive programming, starting from a clean state.*/ + usart_stop(uartp); + + /* Baud rate setting.*/ + baudr = (uint32_t)((uartp->clock + uartp->config->speed/2) / uartp->config->speed); + u->BAUDR = baudr; + + /* Resetting eventual pending status flags.*/ + (void)u->STS; /* STS reset step 1.*/ + (void)u->DT; /* STS reset step 2.*/ + u->STS = 0; + + /* Note that some bits are enforced because required for correct driver + operations.*/ + u->CTRL2 = uartp->config->ctrl2 | USART_CTRL2_BFIEN; + u->CTRL3 = uartp->config->ctrl3 | USART_CTRL3_DMATEN | USART_CTRL3_DMAREN | + USART_CTRL3_ERRIEN; + + /* Mustn't ever set FDTIEN here - if done, it causes an immediate + interrupt.*/ + ctrl1 = USART_CTRL1_UEN | USART_CTRL1_PERRIEN | USART_CTRL1_TEN | USART_CTRL1_REN; + u->CTRL1 = uartp->config->ctrl1 | ctrl1; + + /* Starting the receiver idle loop.*/ + uart_enter_rx_idle_loop(uartp); +} + +/** + * @brief RX DMA common service routine. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(AT32_UART_DMA_ERROR_HOOK) + if ((flags & AT32_DMA_STS_DTERRF) != 0) { + AT32_UART_DMA_ERROR_HOOK(uartp); + } +#else + (void)flags; +#endif + + if (uartp->rxstate == UART_RX_IDLE) { + /* Receiver in idle state, a callback is generated, if enabled, for each + received character and then the driver stays in the same state.*/ + _uart_rx_idle_code(uartp); + } + else { + /* Receiver in active state, a callback is generated, if enabled, after + a completed transfer.*/ + dmaStreamDisable(uartp->dmarx); + _uart_rx_complete_isr_code(uartp); + } +} + +/** + * @brief TX DMA common service routine. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) { + + /* DMA errors handling.*/ +#if defined(AT32_UART_DMA_ERROR_HOOK) + if ((flags & AT32_DMA_STS_DTERRF) != 0) { + AT32_UART_DMA_ERROR_HOOK(uartp); + } +#else + (void)flags; +#endif + + dmaStreamDisable(uartp->dmatx); + + /* A callback is generated, if enabled, after a completed transfer.*/ + _uart_tx1_isr_code(uartp); +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if AT32_UART_USE_USART1 || defined(__DOXYGEN__) +#if !defined(AT32_USART1_SUPPRESS_ISR) +#if !defined(AT32_USART1_HANDLER) +#error "AT32_USART1_HANDLER not defined" +#endif +/** + * @brief USART1 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART1_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + uart_lld_serve_interrupt(&UARTD1); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif /* AT32_UART_USE_USART1 */ + +#if AT32_UART_USE_USART2 || defined(__DOXYGEN__) +#if !defined(AT32_USART2_SUPPRESS_ISR) +#if !defined(AT32_USART2_HANDLER) +#error "AT32_USART2_HANDLER not defined" +#endif +/** + * @brief USART2 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART2_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + uart_lld_serve_interrupt(&UARTD2); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif /* AT32_UART_USE_USART2 */ + +#if AT32_UART_USE_USART3 || defined(__DOXYGEN__) +#if !defined(AT32_USART3_SUPPRESS_ISR) +#if !defined(AT32_USART3_HANDLER) +#error "AT32_USART3_HANDLER not defined" +#endif +/** + * @brief USART3 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART3_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + uart_lld_serve_interrupt(&UARTD3); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif /* AT32_UART_USE_USART3 */ + +#if AT32_UART_USE_UART4 || defined(__DOXYGEN__) +#if !defined(AT32_UART4_SUPPRESS_ISR) +#if !defined(AT32_UART4_HANDLER) +#error "AT32_UART4_HANDLER not defined" +#endif +/** + * @brief UART4 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART4_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + uart_lld_serve_interrupt(&UARTD4); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif /* AT32_UART_USE_UART4 */ + +#if AT32_UART_USE_UART5 || defined(__DOXYGEN__) +#if !defined(AT32_UART5_SUPPRESS_ISR) +#if !defined(AT32_UART5_HANDLER) +#error "AT32_UART5_HANDLER not defined" +#endif +/** + * @brief UART5 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART5_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + uart_lld_serve_interrupt(&UARTD5); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif /* AT32_UART_USE_UART5 */ + +#if AT32_UART_USE_USART6 || defined(__DOXYGEN__) +#if !defined(AT32_USART6_SUPPRESS_ISR) +#if !defined(AT32_USART6_HANDLER) +#error "AT32_USART6_HANDLER not defined" +#endif +/** + * @brief USART6 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_USART6_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + uart_lld_serve_interrupt(&UARTD6); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif /* AT32_UART_USE_USART6 */ + +#if AT32_UART_USE_UART7 || defined(__DOXYGEN__) +#if !defined(AT32_UART7_SUPPRESS_ISR) +#if !defined(AT32_UART7_HANDLER) +#error "AT32_UART7_HANDLER not defined" +#endif +/** + * @brief UART7 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART7_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + uart_lld_serve_interrupt(&UARTD7); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif /* AT32_UART_USE_UART7 */ + +#if AT32_UART_USE_UART8 || defined(__DOXYGEN__) +#if !defined(AT32_UART8_SUPPRESS_ISR) +#if !defined(AT32_UART8_HANDLER) +#error "AT32_UART8_HANDLER not defined" +#endif +/** + * @brief UART5 IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(AT32_UART8_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + uart_lld_serve_interrupt(&UARTD8); + + OSAL_IRQ_EPILOGUE(); +} +#endif +#endif /* AT32_UART_USE_UART5 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level UART driver initialization. + * + * @notapi + */ +void uart_lld_init(void) { + +#if AT32_UART_USE_USART1 + uartObjectInit(&UARTD1); + UARTD1.usart = USART1; + UARTD1.clock = AT32_PCLK2; + UARTD1.dmarxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD1.dmatxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD1.dmarx = NULL; + UARTD1.dmatx = NULL; +#endif + +#if AT32_UART_USE_USART2 + uartObjectInit(&UARTD2); + UARTD2.usart = USART2; + UARTD2.clock = AT32_PCLK1; + UARTD2.dmarxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD2.dmatxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD2.dmarx = NULL; + UARTD2.dmatx = NULL; +#endif + +#if AT32_UART_USE_USART3 + uartObjectInit(&UARTD3); + UARTD3.usart = USART3; + UARTD3.clock = AT32_PCLK1; + UARTD3.dmarxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD3.dmatxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD3.dmarx = NULL; + UARTD3.dmatx = NULL; +#endif + +#if AT32_UART_USE_UART4 + uartObjectInit(&UARTD4); + UARTD4.usart = UART4; + UARTD4.clock = AT32_PCLK1; + UARTD4.dmarxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD4.dmatxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD4.dmarx = NULL; + UARTD4.dmatx = NULL; +#endif + +#if AT32_UART_USE_UART5 + uartObjectInit(&UARTD5); + UARTD5.usart = UART5; + UARTD5.clock = AT32_PCLK1; + UARTD5.dmarxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD5.dmatxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD5.dmarx = NULL; + UARTD5.dmatx = NULL; +#endif + +#if AT32_UART_USE_USART6 + uartObjectInit(&UARTD6); + UARTD6.usart = USART6; + UARTD6.clock = AT32_PCLK2; + UARTD6.dmarxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD6.dmatxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD6.dmarx = NULL; + UARTD6.dmatx = NULL; +#endif + +#if AT32_UART_USE_UART7 + uartObjectInit(&UARTD7); + UARTD7.usart = UART7; + UARTD7.clock = AT32_PCLK1; + UARTD7.dmarxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD7.dmatxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD7.dmarx = NULL; + UARTD7.dmatx = NULL; +#endif + +#if AT32_UART_USE_UART8 + uartObjectInit(&UARTD8); + UARTD8.usart = UART8; + UARTD8.clock = AT32_PCLK1; + UARTD8.dmarxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD8.dmatxmode = AT32_DMA_CCTRL_DTERRIEN; + UARTD8.dmarx = NULL; + UARTD8.dmatx = NULL; +#endif +} + +/** + * @brief Configures and activates the UART peripheral. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @notapi + */ +void uart_lld_start(UARTDriver *uartp) { + + if (uartp->state == UART_STOP) { +#if AT32_UART_USE_USART1 + if (&UARTD1 == uartp) { + uartp->dmarx = dmaStreamAllocI(AT32_UART_USART1_RX_DMA_STREAM, + AT32_UART_USART1_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream"); + uartp->dmatx = dmaStreamAllocI(AT32_UART_USART1_TX_DMA_STREAM, + AT32_UART_USART1_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream"); + +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(uartp->dmarx, AT32_DMAMUX_USART1_RX); + dmaSetRequestSource(uartp->dmatx, AT32_DMAMUX_USART1_TX); +#endif + + crmEnableUSART1(true); + nvicEnableVector(AT32_USART1_NUMBER, AT32_UART_USART1_IRQ_PRIORITY); + uartp->dmarxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_USART1_DMA_PRIORITY); + uartp->dmatxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_USART1_DMA_PRIORITY); + } +#endif + +#if AT32_UART_USE_USART2 + if (&UARTD2 == uartp) { + uartp->dmarx = dmaStreamAllocI(AT32_UART_USART2_RX_DMA_STREAM, + AT32_UART_USART2_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream"); + uartp->dmatx = dmaStreamAllocI(AT32_UART_USART2_TX_DMA_STREAM, + AT32_UART_USART2_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream"); + +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(uartp->dmarx, AT32_DMAMUX_USART2_RX); + dmaSetRequestSource(uartp->dmatx, AT32_DMAMUX_USART2_TX); +#endif + + crmEnableUSART2(true); + nvicEnableVector(AT32_USART2_NUMBER, AT32_UART_USART2_IRQ_PRIORITY); + uartp->dmarxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_USART2_DMA_PRIORITY); + uartp->dmatxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_USART2_DMA_PRIORITY); + } +#endif + +#if AT32_UART_USE_USART3 + if (&UARTD3 == uartp) { + uartp->dmarx = dmaStreamAllocI(AT32_UART_USART3_RX_DMA_STREAM, + AT32_UART_USART3_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream"); + uartp->dmatx = dmaStreamAllocI(AT32_UART_USART3_TX_DMA_STREAM, + AT32_UART_USART3_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream"); + +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(uartp->dmarx, AT32_DMAMUX_USART3_RX); + dmaSetRequestSource(uartp->dmatx, AT32_DMAMUX_USART3_TX); +#endif + + crmEnableUSART3(true); + nvicEnableVector(AT32_USART3_NUMBER, AT32_UART_USART3_IRQ_PRIORITY); + uartp->dmarxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_USART3_DMA_PRIORITY); + uartp->dmatxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_USART3_DMA_PRIORITY); + } +#endif + +#if AT32_UART_USE_UART4 + if (&UARTD4 == uartp) { + + osalDbgAssert((uartp->config->ctrl2 & AT32_UART_CTRL2_CHECK_MASK) == 0, + "specified invalid bits in UART4 CTRL2 register settings"); + osalDbgAssert((uartp->config->ctrl3 & AT32_UART_CTRL3_CHECK_MASK) == 0, + "specified invalid bits in UART4 CTRL3 register settings"); + + uartp->dmarx = dmaStreamAllocI(AT32_UART_UART4_RX_DMA_STREAM, + AT32_UART_UART4_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream"); + uartp->dmatx = dmaStreamAllocI(AT32_UART_UART4_TX_DMA_STREAM, + AT32_UART_UART4_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream"); + +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(uartp->dmarx, AT32_DMAMUX_UART4_RX); + dmaSetRequestSource(uartp->dmatx, AT32_DMAMUX_UART4_TX); +#endif + + crmEnableUART4(true); + nvicEnableVector(AT32_UART4_NUMBER, AT32_UART_UART4_IRQ_PRIORITY); + uartp->dmarxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_UART4_DMA_PRIORITY); + uartp->dmatxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_UART4_DMA_PRIORITY); + } +#endif + +#if AT32_UART_USE_UART5 + if (&UARTD5 == uartp) { + + osalDbgAssert((uartp->config->ctrl2 & AT32_UART_CTRL2_CHECK_MASK) == 0, + "specified invalid bits in UART5 CTRL2 register settings"); + osalDbgAssert((uartp->config->ctrl3 & AT32_UART_CTRL3_CHECK_MASK) == 0, + "specified invalid bits in UART5 CTRL3 register settings"); + + uartp->dmarx = dmaStreamAllocI(AT32_UART_UART5_RX_DMA_STREAM, + AT32_UART_UART5_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream"); + uartp->dmatx = dmaStreamAllocI(AT32_UART_UART5_TX_DMA_STREAM, + AT32_UART_UART5_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream"); + +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(uartp->dmarx, AT32_DMAMUX_UART5_RX); + dmaSetRequestSource(uartp->dmatx, AT32_DMAMUX_UART5_TX); +#endif + + crmEnableUART5(true); + nvicEnableVector(AT32_UART5_NUMBER, AT32_UART_UART5_IRQ_PRIORITY); + uartp->dmarxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_UART5_DMA_PRIORITY); + uartp->dmatxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_UART5_DMA_PRIORITY); + } +#endif + +#if AT32_UART_USE_USART6 + if (&UARTD6 == uartp) { + uartp->dmarx = dmaStreamAllocI(AT32_UART_USART6_RX_DMA_STREAM, + AT32_UART_USART6_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream"); + uartp->dmatx = dmaStreamAllocI(AT32_UART_USART6_TX_DMA_STREAM, + AT32_UART_USART6_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream"); + +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(uartp->dmarx, AT32_DMAMUX_USART6_RX); + dmaSetRequestSource(uartp->dmatx, AT32_DMAMUX_USART6_TX); +#endif + + crmEnableUSART6(true); + nvicEnableVector(AT32_USART6_NUMBER, AT32_UART_USART6_IRQ_PRIORITY); + uartp->dmarxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_USART6_DMA_PRIORITY); + uartp->dmatxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_USART6_DMA_PRIORITY); + } +#endif + +#if AT32_UART_USE_UART7 + if (&UARTD7 == uartp) { + + osalDbgAssert((uartp->config->ctrl2 & AT32_UART_CTRL2_CHECK_MASK) == 0, + "specified invalid bits in UART7 CTRL2 register settings"); + osalDbgAssert((uartp->config->ctrl3 & AT32_UART_CTRL3_CHECK_MASK) == 0, + "specified invalid bits in UART7 CTRL3 register settings"); + + uartp->dmarx = dmaStreamAllocI(AT32_UART_UART7_RX_DMA_STREAM, + AT32_UART_UART7_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream"); + uartp->dmatx = dmaStreamAllocI(AT32_UART_UART7_TX_DMA_STREAM, + AT32_UART_UART7_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream"); + +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(uartp->dmarx, AT32_DMAMUX_UART7_RX); + dmaSetRequestSource(uartp->dmatx, AT32_DMAMUX_UART7_TX); +#endif + + crmEnableUART7(true); + nvicEnableVector(AT32_UART7_NUMBER, AT32_UART_UART7_IRQ_PRIORITY); + uartp->dmarxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_UART7_DMA_PRIORITY); + uartp->dmatxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_UART7_DMA_PRIORITY); + } +#endif + +#if AT32_UART_USE_UART8 + if (&UARTD8 == uartp) { + + osalDbgAssert((uartp->config->ctrl2 & AT32_UART_CTRL2_CHECK_MASK) == 0, + "specified invalid bits in UART8 CTRL2 register settings"); + osalDbgAssert((uartp->config->ctrl3 & AT32_UART_CTRL3_CHECK_MASK) == 0, + "specified invalid bits in UART8 CTRL3 register settings"); + + uartp->dmarx = dmaStreamAllocI(AT32_UART_UART8_RX_DMA_STREAM, + AT32_UART_UART8_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_rx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream"); + uartp->dmatx = dmaStreamAllocI(AT32_UART_UART8_TX_DMA_STREAM, + AT32_UART_UART8_IRQ_PRIORITY, + (at32_dmasts_t)uart_lld_serve_tx_end_irq, + (void *)uartp); + osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream"); + +#if AT32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(uartp->dmarx, AT32_DMAMUX_UART8_RX); + dmaSetRequestSource(uartp->dmatx, AT32_DMAMUX_UART8_TX); +#endif + + crmEnableUART8(true); + nvicEnableVector(AT32_UART5_NUMBER, AT32_UART_UART8_IRQ_PRIORITY); + uartp->dmarxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_UART8_DMA_PRIORITY); + uartp->dmatxmode |= AT32_DMA_CCTRL_CHPL(AT32_UART_UART8_DMA_PRIORITY); + } +#endif + + /* Static DMA setup, the transfer size depends on the USART settings, + it is 16 bits if M=1 and PEN=0 else it is 8 bits.*/ + if ((uartp->config->ctrl1 & (USART_CTRL1_DBN | USART_CTRL1_PEN)) == USART_CTRL1_DBN) { + uartp->dmarxmode |= AT32_DMA_CCTRL_PWIDTH_HWORD | AT32_DMA_CCTRL_MWIDTH_HWORD; + uartp->dmatxmode |= AT32_DMA_CCTRL_PWIDTH_HWORD | AT32_DMA_CCTRL_MWIDTH_HWORD; + } + dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DT); + dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DT); + uartp->rxbuf = 0; + } + + uartp->rxstate = UART_RX_IDLE; + uartp->txstate = UART_TX_IDLE; + usart_start(uartp); +} + +/** + * @brief Deactivates the UART peripheral. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @notapi + */ +void uart_lld_stop(UARTDriver *uartp) { + + if (uartp->state == UART_READY) { + usart_stop(uartp); + dmaStreamFreeI(uartp->dmarx); + dmaStreamFreeI(uartp->dmatx); + uartp->dmarx = NULL; + uartp->dmatx = NULL; + +#if AT32_UART_USE_USART1 + if (&UARTD1 == uartp) { + nvicDisableVector(AT32_USART1_NUMBER); + crmDisableUSART1(); + return; + } +#endif + +#if AT32_UART_USE_USART2 + if (&UARTD2 == uartp) { + nvicDisableVector(AT32_USART2_NUMBER); + crmDisableUSART2(); + return; + } +#endif + +#if AT32_UART_USE_USART3 + if (&UARTD3 == uartp) { + nvicDisableVector(AT32_USART3_NUMBER); + crmDisableUSART3(); + return; + } +#endif + +#if AT32_UART_USE_UART4 + if (&UARTD4 == uartp) { + nvicDisableVector(AT32_UART4_NUMBER); + crmDisableUART4(); + return; + } +#endif + +#if AT32_UART_USE_UART5 + if (&UARTD5 == uartp) { + nvicDisableVector(AT32_UART5_NUMBER); + crmDisableUART5(); + return; + } +#endif + +#if AT32_UART_USE_USART6 + if (&UARTD6 == uartp) { + nvicDisableVector(AT32_USART6_NUMBER); + crmDisableUSART6(); + return; + } +#endif + +#if AT32_UART_USE_UART7 + if (&UARTD7 == uartp) { + nvicDisableVector(AT32_UART7_NUMBER); + crmDisableUART7(); + return; + } +#endif + +#if AT32_UART_USE_UART8 + if (&UARTD8 == uartp) { + nvicDisableVector(AT32_UART8_NUMBER); + crmDisableUART8(); + return; + } +#endif + + } +} + +/** + * @brief Starts a transmission on the UART peripheral. + * @note The buffers are organized as uint8_t arrays for data sizes below + * or equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] n number of data frames to send + * @param[in] txbuf the pointer to the transmit buffer + * + * @notapi + */ +void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) { + + /* TX DMA channel preparation.*/ + dmaStreamSetMemory0(uartp->dmatx, txbuf); + dmaStreamSetTransactionSize(uartp->dmatx, n); + dmaStreamSetMode(uartp->dmatx, uartp->dmatxmode | AT32_DMA_CCTRL_DTD_M2P | + AT32_DMA_CCTRL_MINCM | AT32_DMA_CCTRL_FDTIEN); + + /* Only enable TDC interrupt if there's a callback attached to it or + if called from uartSendFullTimeout(). Also we need to clear TDC flag + which could be set before.*/ +#if UART_USE_WAIT == TRUE + if ((uartp->config->txend2_cb != NULL) || (uartp->early == false)) { +#else + if (uartp->config->txend2_cb != NULL) { +#endif + uartp->usart->STS = ~USART_STS_TDC; + uartp->usart->CTRL1 |= USART_CTRL1_TDCIEN; + } + + /* Starting transfer.*/ + dmaStreamEnable(uartp->dmatx); +} + +/** + * @brief Stops any ongoing transmission. + * @note Stopping a transmission also suppresses the transmission callbacks. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @return The number of data frames not transmitted by the + * stopped transmit operation. + * + * @notapi + */ +size_t uart_lld_stop_send(UARTDriver *uartp) { + + dmaStreamDisable(uartp->dmatx); + + return dmaStreamGetTransactionSize(uartp->dmatx); +} + +/** + * @brief Starts a receive operation on the UART peripheral. + * @note The buffers are organized as uint8_t arrays for data sizes below + * or equal to 8 bits else it is organized as uint16_t arrays. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] n number of data frames to send + * @param[out] rxbuf the pointer to the receive buffer + * + * @notapi + */ +void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) { + + /* Stopping previous activity (idle state).*/ + dmaStreamDisable(uartp->dmarx); + + /* RX DMA channel preparation.*/ + dmaStreamSetMemory0(uartp->dmarx, rxbuf); + dmaStreamSetTransactionSize(uartp->dmarx, n); + dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | AT32_DMA_CCTRL_DTD_P2M | + AT32_DMA_CCTRL_MINCM | AT32_DMA_CCTRL_FDTIEN); + + /* Starting transfer.*/ + dmaStreamEnable(uartp->dmarx); +} + +/** + * @brief Stops any ongoing receive operation. + * @note Stopping a receive operation also suppresses the receive callbacks. + * + * @param[in] uartp pointer to the @p UARTDriver object + * + * @return The number of data frames not received by the + * stopped receive operation. + * + * @notapi + */ +size_t uart_lld_stop_receive(UARTDriver *uartp) { + size_t n; + + dmaStreamDisable(uartp->dmarx); + n = dmaStreamGetTransactionSize(uartp->dmarx); + uart_enter_rx_idle_loop(uartp); + + return n; +} + +/** + * @brief USART common service routine. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +void uart_lld_serve_interrupt(UARTDriver *uartp) { + uint16_t sts; + USART_TypeDef *u = uartp->usart; + uint32_t ctrl1 = u->CTRL1; + + sts = u->STS; /* STS reset step 1.*/ + + if (sts & (USART_STS_BFF | USART_STS_ROERR | USART_STS_NERR | + USART_STS_FERR | USART_STS_PERR)) { + + (void)u->DT; /* STS reset step 2 - clear ROERR.*/ + + u->STS = ~USART_STS_BFF; + _uart_rx_error_isr_code(uartp, translate_errors(sts)); + } + + if ((sts & USART_STS_TDC) && (ctrl1 & USART_CTRL1_TDCIEN)) { + /* TDC interrupt cleared and disabled.*/ + u->STS = ~USART_STS_TDC; + u->CTRL1 = ctrl1 & ~USART_CTRL1_TDCIEN; + + /* End of transmission, a callback is generated.*/ + _uart_tx2_isr_code(uartp); + } + + /* Timeout interrupt sources are only checked if enabled in CTRL1.*/ + if ((ctrl1 & USART_CTRL1_IDLEIEN) && (sts & USART_STS_IDLEF)) { + _uart_timeout_isr_code(uartp); + } +} + +#endif /* HAL_USE_UART */ + +/** @} */ diff --git a/os/hal/ports/AT32/LLD/USARTv2/hal_uart_lld.h b/os/hal/ports/AT32/LLD/USARTv2/hal_uart_lld.h new file mode 100644 index 0000000000..4c808717cd --- /dev/null +++ b/os/hal/ports/AT32/LLD/USARTv2/hal_uart_lld.h @@ -0,0 +1,675 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + ChibiOS - Copyright (C) 2023..2024 HorrorTroll + ChibiOS - Copyright (C) 2023..2024 Zhaqian + ChibiOS - Copyright (C) 2023..2024 Maxjta + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file USARTv2/hal_uart_lld.h + * @brief AT32 low level UART driver header. + * + * @addtogroup UART + * @{ + */ + +#ifndef HAL_UART_LLD_H +#define HAL_UART_LLD_H + +#if HAL_USE_UART || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief UART driver on USART1 enable switch. + * @details If set to @p TRUE the support for USART1 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_UART_USE_USART1) || defined(__DOXYGEN__) +#define AT32_UART_USE_USART1 FALSE +#endif + +/** + * @brief UART driver on USART2 enable switch. + * @details If set to @p TRUE the support for USART2 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_UART_USE_USART2) || defined(__DOXYGEN__) +#define AT32_UART_USE_USART2 FALSE +#endif + +/** + * @brief UART driver on USART3 enable switch. + * @details If set to @p TRUE the support for USART3 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_UART_USE_USART3) || defined(__DOXYGEN__) +#define AT32_UART_USE_USART3 FALSE +#endif + +/** + * @brief UART driver on UART4 enable switch. + * @details If set to @p TRUE the support for UART4 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_UART_USE_UART4) || defined(__DOXYGEN__) +#define AT32_UART_USE_UART4 FALSE +#endif + +/** + * @brief UART driver on UART5 enable switch. + * @details If set to @p TRUE the support for UART5 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_UART_USE_UART5) || defined(__DOXYGEN__) +#define AT32_UART_USE_UART5 FALSE +#endif + +/** + * @brief UART driver on USART6 enable switch. + * @details If set to @p TRUE the support for USART6 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_UART_USE_USART6) || defined(__DOXYGEN__) +#define AT32_UART_USE_USART6 FALSE +#endif + +/** + * @brief UART driver on UART7 enable switch. + * @details If set to @p TRUE the support for UART7 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_UART_USE_UART7) || defined(__DOXYGEN__) +#define AT32_UART_USE_UART7 FALSE +#endif + +/** + * @brief UART driver on UART8 enable switch. + * @details If set to @p TRUE the support for UART8 is included. + * @note The default is @p FALSE. + */ +#if !defined(AT32_UART_USE_UART8) || defined(__DOXYGEN__) +#define AT32_UART_USE_UART8 FALSE +#endif + +/** + * @brief USART1 interrupt priority level setting. + */ +#if !defined(AT32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_USART1_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART2 interrupt priority level setting. + */ +#if !defined(AT32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_USART2_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART3 interrupt priority level setting. + */ +#if !defined(AT32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_USART3_IRQ_PRIORITY 12 +#endif + +/** + * @brief UART4 interrupt priority level setting. + */ +#if !defined(AT32_UART_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_UART4_IRQ_PRIORITY 12 +#endif + +/** + * @brief UART5 interrupt priority level setting. + */ +#if !defined(AT32_UART_UART5_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_UART5_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART6 interrupt priority level setting. + */ +#if !defined(AT32_UART_USART6_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_USART6_IRQ_PRIORITY 12 +#endif + +/** + * @brief UART7 interrupt priority level setting. + */ +#if !defined(AT32_UART_UART7_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_UART7_IRQ_PRIORITY 12 +#endif + +/** + * @brief UART8 interrupt priority level setting. + */ +#if !defined(AT32_UART_UART8_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_UART8_IRQ_PRIORITY 12 +#endif + +/** + * @brief USART1 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(AT32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_USART1_DMA_PRIORITY 0 +#endif + +/** + * @brief USART2 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(AT32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_USART2_DMA_PRIORITY 0 +#endif + +/** + * @brief USART3 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(AT32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_USART3_DMA_PRIORITY 0 +#endif + +/** + * @brief UART4 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(AT32_UART_UART4_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_UART4_DMA_PRIORITY 0 +#endif + +/** + * @brief UART5 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(AT32_UART_UART5_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_UART5_DMA_PRIORITY 0 +#endif + +/** + * @brief USART6 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(AT32_UART_USART6_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_USART6_DMA_PRIORITY 0 +#endif + +/** + * @brief UART7 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(AT32_UART_UART7_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_UART7_DMA_PRIORITY 0 +#endif + +/** + * @brief UART8 DMA priority (0..3|lowest..highest). + * @note The priority level is used for both the TX and RX DMA channels but + * because of the channels ordering the RX channel has always priority + * over the TX channel. + */ +#if !defined(AT32_UART_UART8_DMA_PRIORITY) || defined(__DOXYGEN__) +#define AT32_UART_UART8_DMA_PRIORITY 0 +#endif + +/** + * @brief USART DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(AT32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define AT32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if AT32_UART_USE_USART1 && !AT32_HAS_USART1 +#error "USART1 not present in the selected device" +#endif + +#if AT32_UART_USE_USART2 && !AT32_HAS_USART2 +#error "USART2 not present in the selected device" +#endif + +#if AT32_UART_USE_USART3 && !AT32_HAS_USART3 +#error "USART3 not present in the selected device" +#endif + +#if AT32_UART_USE_UART4 && !AT32_HAS_UART4 +#error "UART4 not present in the selected device" +#endif + +#if AT32_UART_USE_UART5 && !AT32_HAS_UART5 +#error "UART5 not present in the selected device" +#endif + +#if AT32_UART_USE_USART6 && !AT32_HAS_USART6 +#error "USART6 not present in the selected device" +#endif + +#if AT32_UART_USE_UART7 && !AT32_HAS_UART7 +#error "UART7 not present in the selected device" +#endif + +#if AT32_UART_USE_UART8 && !AT32_HAS_UART8 +#error "UART8 not present in the selected device" +#endif + +#if !AT32_UART_USE_USART1 && !AT32_UART_USE_USART2 && \ + !AT32_UART_USE_USART3 && !AT32_UART_USE_UART4 && \ + !AT32_UART_USE_UART5 && !AT32_UART_USE_USART6 && \ + !AT32_UART_USE_UART7 && !AT32_UART_USE_UART8 +#error "UART driver activated but no USART/UART peripheral assigned" +#endif + +#if AT32_UART_USE_USART1 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_UART_USART1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to USART1" +#endif + +#if AT32_UART_USE_USART2 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_UART_USART2_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to USART2" +#endif + +#if AT32_UART_USE_USART3 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_UART_USART3_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to USART3" +#endif + +#if AT32_UART_USE_UART4 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_UART_UART4_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART4" +#endif + +#if AT32_UART_USE_UART5 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_UART_UART5_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART5" +#endif + +#if AT32_UART_USE_USART6 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_UART_USART6_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to USART6" +#endif + +#if AT32_UART_USE_UART7 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_UART_UART7_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART7" +#endif + +#if AT32_UART_USE_UART8 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(AT32_UART_UART8_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to UART8" +#endif + +#if AT32_UART_USE_USART1 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_UART_USART1_DMA_PRIORITY) +#error "Invalid DMA priority assigned to USART1" +#endif + +#if AT32_UART_USE_USART2 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_UART_USART2_DMA_PRIORITY) +#error "Invalid DMA priority assigned to USART2" +#endif + +#if AT32_UART_USE_USART3 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_UART_USART3_DMA_PRIORITY) +#error "Invalid DMA priority assigned to USART3" +#endif + +#if AT32_UART_USE_UART4 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_UART_UART4_DMA_PRIORITY) +#error "Invalid DMA priority assigned to UART4" +#endif + +#if AT32_UART_USE_UART5 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_UART_UART5_DMA_PRIORITY) +#error "Invalid DMA priority assigned to UART5" +#endif + +#if AT32_UART_USE_USART6 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_UART_USART6_DMA_PRIORITY) +#error "Invalid DMA priority assigned to USART6" +#endif + +#if AT32_UART_USE_UART7 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_UART_UART7_DMA_PRIORITY) +#error "Invalid DMA priority assigned to UART7" +#endif + +#if AT32_UART_USE_UART8 && \ + !AT32_DMA_IS_VALID_PRIORITY(AT32_UART_UART8_DMA_PRIORITY) +#error "Invalid DMA priority assigned to UART8" +#endif + +#if !defined(AT32_DMA_REQUIRED) +#define AT32_DMA_REQUIRED +#endif + +/* Checks on allocation of USARTx units.*/ +#if AT32_UART_USE_USART1 +#if defined(AT32_USART1_IS_USED) +#error "UARTD1 requires USART1 but it is already used" +#else +#define AT32_USART1_IS_USED +#endif +#endif + +#if AT32_UART_USE_USART2 +#if defined(AT32_USART2_IS_USED) +#error "UARTD2 requires USART2 but it is already used" +#else +#define AT32_USART2_IS_USED +#endif +#endif + +#if AT32_UART_USE_USART3 +#if defined(AT32_USART3_IS_USED) +#error "UARTD3 requires USART3 but it is already used" +#else +#define AT32_USART3_IS_USED +#endif +#endif + +#if AT32_UART_USE_UART4 +#if defined(AT32_UART4_IS_USED) +#error "UARTD4 requires UART4 but it is already used" +#else +#define AT32_UART4_IS_USED +#endif +#endif + +#if AT32_UART_USE_UART5 +#if defined(AT32_UART5_IS_USED) +#error "UARTD5 requires UART5 but it is already used" +#else +#define AT32_UART5_IS_USED +#endif +#endif + +#if AT32_UART_USE_USART6 +#if defined(AT32_USART6_IS_USED) +#error "UARTD6 requires USART6 but it is already used" +#else +#define AT32_USART6_IS_USED +#endif +#endif + +#if AT32_UART_USE_UART7 +#if defined(AT32_UART7_IS_USED) +#error "UARTD7 requires UART7 but it is already used" +#else +#define AT32_UART7_IS_USED +#endif +#endif + +#if AT32_UART_USE_UART8 +#if defined(AT32_UART8_IS_USED) +#error "UARTD8 requires UART8 but it is already used" +#else +#define AT32_UART8_IS_USED +#endif +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief UART driver condition flags type. + */ +typedef uint32_t uartflags_t; + +/** + * @brief Type of an UART driver. + */ +typedef struct hal_uart_driver UARTDriver; + +/** + * @brief Generic UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + */ +typedef void (*uartcb_t)(UARTDriver *uartp); + +/** + * @brief Character received UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] c received character + */ +typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c); + +/** + * @brief Receive error UART notification callback type. + * + * @param[in] uartp pointer to the @p UARTDriver object + * @param[in] e receive error mask + */ +typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e); + +/** + * @brief Type of an UART configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct hal_uart_config { + /** + * @brief End of transmission buffer callback. + */ + uartcb_t txend1_cb; + /** + * @brief Physical end of transmission callback. + */ + uartcb_t txend2_cb; + /** + * @brief Receive buffer filled callback. + */ + uartcb_t rxend_cb; + /** + * @brief Character received while out if the @p UART_RECEIVE state. + */ + uartccb_t rxchar_cb; + /** + * @brief Receive error callback. + */ + uartecb_t rxerr_cb; + /* End of the mandatory fields.*/ + /** + * @brief Receiver timeout callback. + * @details Handles idle interrupts depending on configured + * flags in CR registers and supported hardware features. + */ + uartcb_t timeout_cb; + /** + * @brief Bit rate. + */ + uint32_t speed; + /** + * @brief Initialization value for the CTRL1 register. + */ + uint16_t ctrl1; + /** + * @brief Initialization value for the CTRL2 register. + */ + uint16_t ctrl2; + /** + * @brief Initialization value for the CTRL3 register. + */ + uint16_t ctrl3; +} UARTConfig; + +/** + * @brief Structure representing an UART driver. + */ +struct hal_uart_driver { + /** + * @brief Driver state. + */ + uartstate_t state; + /** + * @brief Transmitter state. + */ + uarttxstate_t txstate; + /** + * @brief Receiver state. + */ + uartrxstate_t rxstate; + /** + * @brief Current configuration data. + */ + const UARTConfig *config; +#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__) + /** + * @brief Synchronization flag for transmit operations. + */ + bool early; + /** + * @brief Waiting thread on RX. + */ + thread_reference_t threadrx; + /** + * @brief Waiting thread on TX. + */ + thread_reference_t threadtx; +#endif /* UART_USE_WAIT */ +#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the peripheral. + */ + mutex_t mutex; +#endif /* UART_USE_MUTUAL_EXCLUSION */ +#if defined(UART_DRIVER_EXT_FIELDS) + UART_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the USART registers block. + */ + USART_TypeDef *usart; + /** + * @brief Clock frequency for the associated USART/UART. + */ + uint32_t clock; + /** + * @brief Receive DMA mode bit mask. + */ + uint32_t dmarxmode; + /** + * @brief Send DMA mode bit mask. + */ + uint32_t dmatxmode; + /** + * @brief Receive DMA channel. + */ + const at32_dma_stream_t *dmarx; + /** + * @brief Transmit DMA channel. + */ + const at32_dma_stream_t *dmatx; + /** + * @brief Default receive buffer while into @p UART_RX_IDLE state. + */ + volatile uint16_t rxbuf; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if AT32_UART_USE_USART1 && !defined(__DOXYGEN__) +extern UARTDriver UARTD1; +#endif + +#if AT32_UART_USE_USART2 && !defined(__DOXYGEN__) +extern UARTDriver UARTD2; +#endif + +#if AT32_UART_USE_USART3 && !defined(__DOXYGEN__) +extern UARTDriver UARTD3; +#endif + +#if AT32_UART_USE_UART4 && !defined(__DOXYGEN__) +extern UARTDriver UARTD4; +#endif + +#if AT32_UART_USE_UART5 && !defined(__DOXYGEN__) +extern UARTDriver UARTD5; +#endif + +#if AT32_UART_USE_USART6 && !defined(__DOXYGEN__) +extern UARTDriver UARTD6; +#endif + +#if AT32_UART_USE_UART7 && !defined(__DOXYGEN__) +extern UARTDriver UARTD7; +#endif + +#if AT32_UART_USE_UART8 && !defined(__DOXYGEN__) +extern UARTDriver UARTD8; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void uart_lld_init(void); + void uart_lld_start(UARTDriver *uartp); + void uart_lld_stop(UARTDriver *uartp); + void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf); + size_t uart_lld_stop_send(UARTDriver *uartp); + void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf); + size_t uart_lld_stop_receive(UARTDriver *uartp); + void uart_lld_serve_interrupt(UARTDriver *uartp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_UART */ + +#endif /* HAL_UART_LLD_H */ + +/** @} */