Compare commits
5 Commits
0264ccd54e
...
bare_modbu
| Author | SHA1 | Date | |
|---|---|---|---|
| 98e9e22752 | |||
|
|
c5c265ba6c | ||
|
|
b530a60de2 | ||
|
|
5c70316df7 | ||
|
|
fbc424e507 |
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/STM32F103_Example/MDK-ARM/Modbus_example
|
||||||
|
/Modbus/.vs/
|
||||||
|
/Doc/html/
|
||||||
|
/Doc/latex/
|
||||||
2990
Doc/Doxyfile
Normal file
2990
Doc/Doxyfile
Normal file
@@ -0,0 +1,2990 @@
|
|||||||
|
# Doxyfile 1.14.0
|
||||||
|
|
||||||
|
# This file describes the settings to be used by the documentation system
|
||||||
|
# Doxygen (www.doxygen.org) for a project.
|
||||||
|
#
|
||||||
|
# All text after a double hash (##) is considered a comment and is placed in
|
||||||
|
# front of the TAG it is preceding.
|
||||||
|
#
|
||||||
|
# All text after a single hash (#) is considered a comment and will be ignored.
|
||||||
|
# The format is:
|
||||||
|
# TAG = value [value, ...]
|
||||||
|
# For lists, items can also be appended using:
|
||||||
|
# TAG += value [value, ...]
|
||||||
|
# Values that contain spaces should be placed between quotes (\" \").
|
||||||
|
#
|
||||||
|
# Note:
|
||||||
|
#
|
||||||
|
# Use Doxygen to compare the used configuration file with the template
|
||||||
|
# configuration file:
|
||||||
|
# doxygen -x [configFile]
|
||||||
|
# Use Doxygen to compare the used configuration file with the template
|
||||||
|
# configuration file without replacing the environment variables or CMake type
|
||||||
|
# replacement variables:
|
||||||
|
# doxygen -x_noenv [configFile]
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Project related configuration options
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# This tag specifies the encoding used for all characters in the configuration
|
||||||
|
# file that follow. The default is UTF-8 which is also the encoding used for all
|
||||||
|
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
|
||||||
|
# iconv built into libc) for the transcoding. See
|
||||||
|
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
|
||||||
|
# The default value is: UTF-8.
|
||||||
|
|
||||||
|
DOXYFILE_ENCODING = UTF-8
|
||||||
|
|
||||||
|
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
|
||||||
|
# double-quotes, unless you are using Doxywizard) that should identify the
|
||||||
|
# project for which the documentation is generated. This name is used in the
|
||||||
|
# title of most generated pages and in a few other places.
|
||||||
|
# The default value is: My Project.
|
||||||
|
|
||||||
|
PROJECT_NAME = Modbus
|
||||||
|
|
||||||
|
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||||
|
# could be handy for archiving the generated documentation or if some version
|
||||||
|
# control system is used.
|
||||||
|
|
||||||
|
PROJECT_NUMBER = 0.3
|
||||||
|
|
||||||
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
|
# for a project that appears at the top of each page and should give viewers a
|
||||||
|
# quick idea about the purpose of the project. Keep the description short.
|
||||||
|
|
||||||
|
PROJECT_BRIEF = "Библиотека Modbus для STM"
|
||||||
|
|
||||||
|
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
|
||||||
|
# in the documentation. The maximum height of the logo should not exceed 55
|
||||||
|
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
||||||
|
# the logo to the output directory.
|
||||||
|
|
||||||
|
PROJECT_LOGO =
|
||||||
|
|
||||||
|
# With the PROJECT_ICON tag one can specify an icon that is included in the tabs
|
||||||
|
# when the HTML document is shown. Doxygen will copy the logo to the output
|
||||||
|
# directory.
|
||||||
|
|
||||||
|
PROJECT_ICON =
|
||||||
|
|
||||||
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||||
|
# into which the generated documentation will be written. If a relative path is
|
||||||
|
# entered, it will be relative to the location where Doxygen was started. If
|
||||||
|
# left blank the current directory will be used.
|
||||||
|
|
||||||
|
OUTPUT_DIRECTORY = .
|
||||||
|
|
||||||
|
# If the CREATE_SUBDIRS tag is set to YES then Doxygen will create up to 4096
|
||||||
|
# sub-directories (in 2 levels) under the output directory of each output format
|
||||||
|
# and will distribute the generated files over these directories. Enabling this
|
||||||
|
# option can be useful when feeding Doxygen a huge amount of source files, where
|
||||||
|
# putting all generated files in the same directory would otherwise cause
|
||||||
|
# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to
|
||||||
|
# control the number of sub-directories.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
CREATE_SUBDIRS = NO
|
||||||
|
|
||||||
|
# Controls the number of sub-directories that will be created when
|
||||||
|
# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every
|
||||||
|
# level increment doubles the number of directories, resulting in 4096
|
||||||
|
# directories at level 8 which is the default and also the maximum value. The
|
||||||
|
# sub-directories are organized in 2 levels, the first level always has a fixed
|
||||||
|
# number of 16 directories.
|
||||||
|
# Minimum value: 0, maximum value: 8, default value: 8.
|
||||||
|
# This tag requires that the tag CREATE_SUBDIRS is set to YES.
|
||||||
|
|
||||||
|
CREATE_SUBDIRS_LEVEL = 8
|
||||||
|
|
||||||
|
# If the ALLOW_UNICODE_NAMES tag is set to YES, Doxygen will allow non-ASCII
|
||||||
|
# characters to appear in the names of generated files. If set to NO, non-ASCII
|
||||||
|
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
|
||||||
|
# U+3044.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
ALLOW_UNICODE_NAMES = NO
|
||||||
|
|
||||||
|
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||||
|
# documentation generated by Doxygen is written. Doxygen will use this
|
||||||
|
# information to generate all constant output in the proper language.
|
||||||
|
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian,
|
||||||
|
# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English
|
||||||
|
# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek,
|
||||||
|
# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with
|
||||||
|
# English messages), Korean, Korean-en (Korean with English messages), Latvian,
|
||||||
|
# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese,
|
||||||
|
# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish,
|
||||||
|
# Swedish, Turkish, Ukrainian and Vietnamese.
|
||||||
|
# The default value is: English.
|
||||||
|
|
||||||
|
OUTPUT_LANGUAGE = English
|
||||||
|
|
||||||
|
# If the BRIEF_MEMBER_DESC tag is set to YES, Doxygen will include brief member
|
||||||
|
# descriptions after the members that are listed in the file and class
|
||||||
|
# documentation (similar to Javadoc). Set to NO to disable this.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
BRIEF_MEMBER_DESC = YES
|
||||||
|
|
||||||
|
# If the REPEAT_BRIEF tag is set to YES, Doxygen will prepend the brief
|
||||||
|
# description of a member or function before the detailed description
|
||||||
|
#
|
||||||
|
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
|
||||||
|
# brief descriptions will be completely suppressed.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
REPEAT_BRIEF = YES
|
||||||
|
|
||||||
|
# This tag implements a quasi-intelligent brief description abbreviator that is
|
||||||
|
# used to form the text in various listings. Each string in this list, if found
|
||||||
|
# as the leading text of the brief description, will be stripped from the text
|
||||||
|
# and the result, after processing the whole list, is used as the annotated
|
||||||
|
# text. Otherwise, the brief description is used as-is. If left blank, the
|
||||||
|
# following values are used ($name is automatically replaced with the name of
|
||||||
|
# the entity):The $name class, The $name widget, The $name file, is, provides,
|
||||||
|
# specifies, contains, represents, a, an and the.
|
||||||
|
|
||||||
|
ABBREVIATE_BRIEF = "The $name class" \
|
||||||
|
"The $name widget" \
|
||||||
|
"The $name file" \
|
||||||
|
is \
|
||||||
|
provides \
|
||||||
|
specifies \
|
||||||
|
contains \
|
||||||
|
represents \
|
||||||
|
a \
|
||||||
|
an \
|
||||||
|
the
|
||||||
|
|
||||||
|
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
||||||
|
# Doxygen will generate a detailed section even if there is only a brief
|
||||||
|
# description.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
ALWAYS_DETAILED_SEC = NO
|
||||||
|
|
||||||
|
# If the INLINE_INHERITED_MEMB tag is set to YES, Doxygen will show all
|
||||||
|
# inherited members of a class in the documentation of that class as if those
|
||||||
|
# members were ordinary class members. Constructors, destructors and assignment
|
||||||
|
# operators of the base classes will not be shown.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
INLINE_INHERITED_MEMB = NO
|
||||||
|
|
||||||
|
# If the FULL_PATH_NAMES tag is set to YES, Doxygen will prepend the full path
|
||||||
|
# before files name in the file list and in the header files. If set to NO the
|
||||||
|
# shortest path that makes the file name unique will be used
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
FULL_PATH_NAMES = YES
|
||||||
|
|
||||||
|
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
|
||||||
|
# Stripping is only done if one of the specified strings matches the left-hand
|
||||||
|
# part of the path. The tag can be used to show relative paths in the file list.
|
||||||
|
# If left blank the directory from which Doxygen is run is used as the path to
|
||||||
|
# strip.
|
||||||
|
#
|
||||||
|
# Note that you can specify absolute paths here, but also relative paths, which
|
||||||
|
# will be relative from the directory where Doxygen is started.
|
||||||
|
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||||
|
|
||||||
|
STRIP_FROM_PATH =
|
||||||
|
|
||||||
|
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
||||||
|
# path mentioned in the documentation of a class, which tells the reader which
|
||||||
|
# header file to include in order to use a class. If left blank only the name of
|
||||||
|
# the header file containing the class definition is used. Otherwise one should
|
||||||
|
# specify the list of include paths that are normally passed to the compiler
|
||||||
|
# using the -I flag.
|
||||||
|
|
||||||
|
STRIP_FROM_INC_PATH =
|
||||||
|
|
||||||
|
# If the SHORT_NAMES tag is set to YES, Doxygen will generate much shorter (but
|
||||||
|
# less readable) file names. This can be useful if your file system doesn't
|
||||||
|
# support long names like on DOS, Mac, or CD-ROM.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SHORT_NAMES = NO
|
||||||
|
|
||||||
|
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen will interpret the
|
||||||
|
# first line (until the first dot, question mark or exclamation mark) of a
|
||||||
|
# Javadoc-style comment as the brief description. If set to NO, the Javadoc-
|
||||||
|
# style will behave just like regular Qt-style comments (thus requiring an
|
||||||
|
# explicit @brief command for a brief description.)
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
JAVADOC_AUTOBRIEF = NO
|
||||||
|
|
||||||
|
# If the JAVADOC_BANNER tag is set to YES then Doxygen will interpret a line
|
||||||
|
# such as
|
||||||
|
# /***************
|
||||||
|
# as being the beginning of a Javadoc-style comment "banner". If set to NO, the
|
||||||
|
# Javadoc-style will behave just like regular comments and it will not be
|
||||||
|
# interpreted by Doxygen.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
JAVADOC_BANNER = NO
|
||||||
|
|
||||||
|
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will interpret the first
|
||||||
|
# line (until the first dot, question mark or exclamation mark) of a Qt-style
|
||||||
|
# comment as the brief description. If set to NO, the Qt-style will behave just
|
||||||
|
# like regular Qt-style comments (thus requiring an explicit \brief command for
|
||||||
|
# a brief description.)
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
QT_AUTOBRIEF = NO
|
||||||
|
|
||||||
|
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen treat a
|
||||||
|
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
|
||||||
|
# a brief description. This used to be the default behavior. The new default is
|
||||||
|
# to treat a multi-line C++ comment block as a detailed description. Set this
|
||||||
|
# tag to YES if you prefer the old behavior instead.
|
||||||
|
#
|
||||||
|
# Note that setting this tag to YES also means that rational rose comments are
|
||||||
|
# not recognized any more.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
MULTILINE_CPP_IS_BRIEF = NO
|
||||||
|
|
||||||
|
# By default Python docstrings are displayed as preformatted text and Doxygen's
|
||||||
|
# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
|
||||||
|
# Doxygen's special commands can be used and the contents of the docstring
|
||||||
|
# documentation blocks is shown as Doxygen documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
PYTHON_DOCSTRING = YES
|
||||||
|
|
||||||
|
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
|
||||||
|
# documentation from any documented member that it re-implements.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
INHERIT_DOCS = YES
|
||||||
|
|
||||||
|
# If the SEPARATE_MEMBER_PAGES tag is set to YES then Doxygen will produce a new
|
||||||
|
# page for each member. If set to NO, the documentation of a member will be part
|
||||||
|
# of the file/class/namespace that contains it.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SEPARATE_MEMBER_PAGES = NO
|
||||||
|
|
||||||
|
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
|
||||||
|
# uses this value to replace tabs by spaces in code fragments.
|
||||||
|
# Minimum value: 1, maximum value: 16, default value: 4.
|
||||||
|
|
||||||
|
TAB_SIZE = 2
|
||||||
|
|
||||||
|
# This tag can be used to specify a number of aliases that act as commands in
|
||||||
|
# the documentation. An alias has the form:
|
||||||
|
# name=value
|
||||||
|
# For example adding
|
||||||
|
# "sideeffect=@par Side Effects:^^"
|
||||||
|
# will allow you to put the command \sideeffect (or @sideeffect) in the
|
||||||
|
# documentation, which will result in a user-defined paragraph with heading
|
||||||
|
# "Side Effects:". Note that you cannot put \n's in the value part of an alias
|
||||||
|
# to insert newlines (in the resulting output). You can put ^^ in the value part
|
||||||
|
# of an alias to insert a newline as if a physical newline was in the original
|
||||||
|
# file. When you need a literal { or } or , in the value part of an alias you
|
||||||
|
# have to escape them by means of a backslash (\), this can lead to conflicts
|
||||||
|
# with the commands \{ and \} for these it is advised to use the version @{ and
|
||||||
|
# @} or use a double escape (\\{ and \\})
|
||||||
|
|
||||||
|
ALIASES =
|
||||||
|
|
||||||
|
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||||
|
# only. Doxygen will then generate output that is more tailored for C. For
|
||||||
|
# instance, some of the names that are used will be different. The list of all
|
||||||
|
# members will be omitted, etc.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||||
|
|
||||||
|
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
|
||||||
|
# Python sources only. Doxygen will then generate output that is more tailored
|
||||||
|
# for that language. For instance, namespaces will be presented as packages,
|
||||||
|
# qualified scopes will look different, etc.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
|
||||||
|
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
|
||||||
|
# sources. Doxygen will then generate output that is tailored for Fortran.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
OPTIMIZE_FOR_FORTRAN = NO
|
||||||
|
|
||||||
|
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
|
||||||
|
# sources. Doxygen will then generate output that is tailored for VHDL.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
|
|
||||||
|
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
|
||||||
|
# sources only. Doxygen will then generate output that is more tailored for that
|
||||||
|
# language. For instance, namespaces will be presented as modules, types will be
|
||||||
|
# separated into more groups, etc.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
OPTIMIZE_OUTPUT_SLICE = NO
|
||||||
|
|
||||||
|
# Doxygen selects the parser to use depending on the extension of the files it
|
||||||
|
# parses. With this tag you can assign which parser to use for a given
|
||||||
|
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||||
|
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||||
|
# language is one of the parsers supported by Doxygen: IDL, Java, JavaScript,
|
||||||
|
# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice,
|
||||||
|
# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
|
||||||
|
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
|
||||||
|
# tries to guess whether the code is fixed or free formatted code, this is the
|
||||||
|
# default for Fortran type files). For instance to make Doxygen treat .inc files
|
||||||
|
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
|
||||||
|
# use: inc=Fortran f=C.
|
||||||
|
#
|
||||||
|
# Note: For files without extension you can use no_extension as a placeholder.
|
||||||
|
#
|
||||||
|
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
|
||||||
|
# the files are not read by Doxygen. When specifying no_extension you should add
|
||||||
|
# * to the FILE_PATTERNS.
|
||||||
|
#
|
||||||
|
# Note see also the list of default file extension mappings.
|
||||||
|
|
||||||
|
EXTENSION_MAPPING =
|
||||||
|
|
||||||
|
# If the MARKDOWN_SUPPORT tag is enabled then Doxygen pre-processes all comments
|
||||||
|
# according to the Markdown format, which allows for more readable
|
||||||
|
# documentation. See https://daringfireball.net/projects/markdown/ for details.
|
||||||
|
# The output of markdown processing is further processed by Doxygen, so you can
|
||||||
|
# mix Doxygen, HTML, and XML commands with Markdown formatting. Disable only in
|
||||||
|
# case of backward compatibilities issues.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
MARKDOWN_SUPPORT = YES
|
||||||
|
|
||||||
|
# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
|
||||||
|
# to that level are automatically included in the table of contents, even if
|
||||||
|
# they do not have an id attribute.
|
||||||
|
# Note: This feature currently applies only to Markdown headings.
|
||||||
|
# Minimum value: 0, maximum value: 99, default value: 6.
|
||||||
|
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
|
||||||
|
|
||||||
|
TOC_INCLUDE_HEADINGS = 6
|
||||||
|
|
||||||
|
# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to
|
||||||
|
# generate identifiers for the Markdown headings. Note: Every identifier is
|
||||||
|
# unique.
|
||||||
|
# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a
|
||||||
|
# sequence number starting at 0 and GITHUB use the lower case version of title
|
||||||
|
# with any whitespace replaced by '-' and punctuation characters removed.
|
||||||
|
# The default value is: DOXYGEN.
|
||||||
|
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
|
||||||
|
|
||||||
|
MARKDOWN_ID_STYLE = GITHUB
|
||||||
|
|
||||||
|
# When enabled Doxygen tries to link words that correspond to documented
|
||||||
|
# classes, or namespaces to their corresponding documentation. Such a link can
|
||||||
|
# be prevented in individual cases by putting a % sign in front of the word or
|
||||||
|
# globally by setting AUTOLINK_SUPPORT to NO. Words listed in the
|
||||||
|
# AUTOLINK_IGNORE_WORDS tag are excluded from automatic linking.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
AUTOLINK_SUPPORT = YES
|
||||||
|
|
||||||
|
# This tag specifies a list of words that, when matching the start of a word in
|
||||||
|
# the documentation, will suppress auto links generation, if it is enabled via
|
||||||
|
# AUTOLINK_SUPPORT. This list does not affect links explicitly created using \#
|
||||||
|
# or the \link or commands.
|
||||||
|
# This tag requires that the tag AUTOLINK_SUPPORT is set to YES.
|
||||||
|
|
||||||
|
AUTOLINK_IGNORE_WORDS =
|
||||||
|
|
||||||
|
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
|
||||||
|
# to include (a tag file for) the STL sources as input, then you should set this
|
||||||
|
# tag to YES in order to let Doxygen match functions declarations and
|
||||||
|
# definitions whose arguments contain STL classes (e.g. func(std::string);
|
||||||
|
# versus func(std::string) {}). This also makes the inheritance and
|
||||||
|
# collaboration diagrams that involve STL classes more complete and accurate.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
BUILTIN_STL_SUPPORT = NO
|
||||||
|
|
||||||
|
# If you use Microsoft's C++/CLI language, you should set this option to YES to
|
||||||
|
# enable parsing support.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
CPP_CLI_SUPPORT = NO
|
||||||
|
|
||||||
|
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
|
||||||
|
# https://www.riverbankcomputing.com/software) sources only. Doxygen will parse
|
||||||
|
# them like normal C++ but will assume all classes use public instead of private
|
||||||
|
# inheritance when no explicit protection keyword is present.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SIP_SUPPORT = NO
|
||||||
|
|
||||||
|
# For Microsoft's IDL there are propget and propput attributes to indicate
|
||||||
|
# getter and setter methods for a property. Setting this option to YES will make
|
||||||
|
# Doxygen to replace the get and set methods by a property in the documentation.
|
||||||
|
# This will only work if the methods are indeed getting or setting a simple
|
||||||
|
# type. If this is not the case, or you want to show the methods anyway, you
|
||||||
|
# should set this option to NO.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
IDL_PROPERTY_SUPPORT = YES
|
||||||
|
|
||||||
|
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
||||||
|
# tag is set to YES then Doxygen will reuse the documentation of the first
|
||||||
|
# member in the group (if any) for the other members of the group. By default
|
||||||
|
# all members of a group must be documented explicitly.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
DISTRIBUTE_GROUP_DOC = NO
|
||||||
|
|
||||||
|
# If one adds a struct or class to a group and this option is enabled, then also
|
||||||
|
# any nested class or struct is added to the same group. By default this option
|
||||||
|
# is disabled and one has to add nested compounds explicitly via \ingroup.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
GROUP_NESTED_COMPOUNDS = NO
|
||||||
|
|
||||||
|
# Set the SUBGROUPING tag to YES to allow class member groups of the same type
|
||||||
|
# (for instance a group of public functions) to be put as a subgroup of that
|
||||||
|
# type (e.g. under the Public Functions section). Set it to NO to prevent
|
||||||
|
# subgrouping. Alternatively, this can be done per class using the
|
||||||
|
# \nosubgrouping command.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
SUBGROUPING = YES
|
||||||
|
|
||||||
|
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
|
||||||
|
# are shown inside the group in which they are included (e.g. using \ingroup)
|
||||||
|
# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
|
||||||
|
# and RTF).
|
||||||
|
#
|
||||||
|
# Note that this feature does not work in combination with
|
||||||
|
# SEPARATE_MEMBER_PAGES.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
INLINE_GROUPED_CLASSES = NO
|
||||||
|
|
||||||
|
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
|
||||||
|
# with only public data fields or simple typedef fields will be shown inline in
|
||||||
|
# the documentation of the scope in which they are defined (i.e. file,
|
||||||
|
# namespace, or group documentation), provided this scope is documented. If set
|
||||||
|
# to NO, structs, classes, and unions are shown on a separate page (for HTML and
|
||||||
|
# Man pages) or section (for LaTeX and RTF).
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
INLINE_SIMPLE_STRUCTS = NO
|
||||||
|
|
||||||
|
# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
|
||||||
|
# enum is documented as struct, union, or enum with the name of the typedef. So
|
||||||
|
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
|
||||||
|
# with name TypeT. When disabled the typedef will appear as a member of a file,
|
||||||
|
# namespace, or class. And the struct will be named TypeS. This can typically be
|
||||||
|
# useful for C code in case the coding convention dictates that all compound
|
||||||
|
# types are typedef'ed and only the typedef is referenced, never the tag name.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
TYPEDEF_HIDES_STRUCT = NO
|
||||||
|
|
||||||
|
# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
|
||||||
|
# cache is used to resolve symbols given their name and scope. Since this can be
|
||||||
|
# an expensive process and often the same symbol appears multiple times in the
|
||||||
|
# code, Doxygen keeps a cache of pre-resolved symbols. If the cache is too small
|
||||||
|
# Doxygen will become slower. If the cache is too large, memory is wasted. The
|
||||||
|
# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
|
||||||
|
# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
|
||||||
|
# symbols. At the end of a run Doxygen will report the cache usage and suggest
|
||||||
|
# the optimal cache size from a speed point of view.
|
||||||
|
# Minimum value: 0, maximum value: 9, default value: 0.
|
||||||
|
|
||||||
|
LOOKUP_CACHE_SIZE = 0
|
||||||
|
|
||||||
|
# The NUM_PROC_THREADS specifies the number of threads Doxygen is allowed to use
|
||||||
|
# during processing. When set to 0 Doxygen will based this on the number of
|
||||||
|
# cores available in the system. You can set it explicitly to a value larger
|
||||||
|
# than 0 to get more control over the balance between CPU load and processing
|
||||||
|
# speed. At this moment only the input processing can be done using multiple
|
||||||
|
# threads. Since this is still an experimental feature the default is set to 1,
|
||||||
|
# which effectively disables parallel processing. Please report any issues you
|
||||||
|
# encounter. Generating dot graphs in parallel is controlled by the
|
||||||
|
# DOT_NUM_THREADS setting.
|
||||||
|
# Minimum value: 0, maximum value: 32, default value: 1.
|
||||||
|
|
||||||
|
NUM_PROC_THREADS = 1
|
||||||
|
|
||||||
|
# If the TIMESTAMP tag is set different from NO then each generated page will
|
||||||
|
# contain the date or date and time when the page was generated. Setting this to
|
||||||
|
# NO can help when comparing the output of multiple runs.
|
||||||
|
# Possible values are: YES, NO, DATETIME and DATE.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
TIMESTAMP = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Build related configuration options
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the EXTRACT_ALL tag is set to YES, Doxygen will assume all entities in
|
||||||
|
# documentation are documented, even if no documentation was available. Private
|
||||||
|
# class members and static file members will be hidden unless the
|
||||||
|
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
|
||||||
|
# Note: This will also disable the warnings about undocumented members that are
|
||||||
|
# normally produced when WARNINGS is set to YES.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXTRACT_ALL = NO
|
||||||
|
|
||||||
|
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
|
||||||
|
# be included in the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXTRACT_PRIVATE = NO
|
||||||
|
|
||||||
|
# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual
|
||||||
|
# methods of a class will be included in the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXTRACT_PRIV_VIRTUAL = NO
|
||||||
|
|
||||||
|
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
|
||||||
|
# scope will be included in the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXTRACT_PACKAGE = NO
|
||||||
|
|
||||||
|
# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
|
||||||
|
# included in the documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXTRACT_STATIC = YES
|
||||||
|
|
||||||
|
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
|
||||||
|
# locally in source files will be included in the documentation. If set to NO,
|
||||||
|
# only classes defined in header files are included. Does not have any effect
|
||||||
|
# for Java sources.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
EXTRACT_LOCAL_CLASSES = YES
|
||||||
|
|
||||||
|
# This flag is only useful for Objective-C code. If set to YES, local methods,
|
||||||
|
# which are defined in the implementation section but not in the interface are
|
||||||
|
# included in the documentation. If set to NO, only methods in the interface are
|
||||||
|
# included.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXTRACT_LOCAL_METHODS = NO
|
||||||
|
|
||||||
|
# If this flag is set to YES, the members of anonymous namespaces will be
|
||||||
|
# extracted and appear in the documentation as a namespace called
|
||||||
|
# 'anonymous_namespace{file}', where file will be replaced with the base name of
|
||||||
|
# the file that contains the anonymous namespace. By default anonymous namespace
|
||||||
|
# are hidden.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXTRACT_ANON_NSPACES = NO
|
||||||
|
|
||||||
|
# If this flag is set to YES, the name of an unnamed parameter in a declaration
|
||||||
|
# will be determined by the corresponding definition. By default unnamed
|
||||||
|
# parameters remain unnamed in the output.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
RESOLVE_UNNAMED_PARAMS = YES
|
||||||
|
|
||||||
|
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
||||||
|
# undocumented members inside documented classes or files. If set to NO these
|
||||||
|
# members will be included in the various overviews, but no documentation
|
||||||
|
# section is generated. This option has no effect if EXTRACT_ALL is enabled.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
HIDE_UNDOC_MEMBERS = NO
|
||||||
|
|
||||||
|
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
|
||||||
|
# undocumented classes that are normally visible in the class hierarchy. If set
|
||||||
|
# to NO, these classes will be included in the various overviews. This option
|
||||||
|
# will also hide undocumented C++ concepts if enabled. This option has no effect
|
||||||
|
# if EXTRACT_ALL is enabled.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
HIDE_UNDOC_CLASSES = NO
|
||||||
|
|
||||||
|
# If the HIDE_UNDOC_NAMESPACES tag is set to YES, Doxygen will hide all
|
||||||
|
# undocumented namespaces that are normally visible in the namespace hierarchy.
|
||||||
|
# If set to NO, these namespaces will be included in the various overviews. This
|
||||||
|
# option has no effect if EXTRACT_ALL is enabled.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
HIDE_UNDOC_NAMESPACES = YES
|
||||||
|
|
||||||
|
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all friend
|
||||||
|
# declarations. If set to NO, these declarations will be included in the
|
||||||
|
# documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
HIDE_FRIEND_COMPOUNDS = NO
|
||||||
|
|
||||||
|
# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
|
||||||
|
# documentation blocks found inside the body of a function. If set to NO, these
|
||||||
|
# blocks will be appended to the function's detailed documentation block.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
HIDE_IN_BODY_DOCS = NO
|
||||||
|
|
||||||
|
# The INTERNAL_DOCS tag determines if documentation that is typed after a
|
||||||
|
# \internal command is included. If the tag is set to NO then the documentation
|
||||||
|
# will be excluded. Set it to YES to include the internal documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
INTERNAL_DOCS = NO
|
||||||
|
|
||||||
|
# With the correct setting of option CASE_SENSE_NAMES Doxygen will better be
|
||||||
|
# able to match the capabilities of the underlying filesystem. In case the
|
||||||
|
# filesystem is case sensitive (i.e. it supports files in the same directory
|
||||||
|
# whose names only differ in casing), the option must be set to YES to properly
|
||||||
|
# deal with such files in case they appear in the input. For filesystems that
|
||||||
|
# are not case sensitive the option should be set to NO to properly deal with
|
||||||
|
# output files written for symbols that only differ in casing, such as for two
|
||||||
|
# classes, one named CLASS and the other named Class, and to also support
|
||||||
|
# references to files without having to specify the exact matching casing. On
|
||||||
|
# Windows (including Cygwin) and macOS, users should typically set this option
|
||||||
|
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
||||||
|
# YES.
|
||||||
|
# Possible values are: SYSTEM, NO and YES.
|
||||||
|
# The default value is: SYSTEM.
|
||||||
|
|
||||||
|
CASE_SENSE_NAMES = SYSTEM
|
||||||
|
|
||||||
|
# If the HIDE_SCOPE_NAMES tag is set to NO then Doxygen will show members with
|
||||||
|
# their full class and namespace scopes in the documentation. If set to YES, the
|
||||||
|
# scope will be hidden.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
HIDE_SCOPE_NAMES = NO
|
||||||
|
|
||||||
|
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then Doxygen will
|
||||||
|
# append additional text to a page's title, such as Class Reference. If set to
|
||||||
|
# YES the compound reference will be hidden.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
HIDE_COMPOUND_REFERENCE= NO
|
||||||
|
|
||||||
|
# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class
|
||||||
|
# will show which file needs to be included to use the class.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
SHOW_HEADERFILE = YES
|
||||||
|
|
||||||
|
# If the SHOW_INCLUDE_FILES tag is set to YES then Doxygen will put a list of
|
||||||
|
# the files that are included by a file in the documentation of that file.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
SHOW_INCLUDE_FILES = YES
|
||||||
|
|
||||||
|
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
|
||||||
|
# grouped member an include statement to the documentation, telling the reader
|
||||||
|
# which file to include in order to use the member.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SHOW_GROUPED_MEMB_INC = NO
|
||||||
|
|
||||||
|
# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen will list include
|
||||||
|
# files with double quotes in the documentation rather than with sharp brackets.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
FORCE_LOCAL_INCLUDES = NO
|
||||||
|
|
||||||
|
# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
|
||||||
|
# documentation for inline members.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
INLINE_INFO = YES
|
||||||
|
|
||||||
|
# If the SORT_MEMBER_DOCS tag is set to YES then Doxygen will sort the
|
||||||
|
# (detailed) documentation of file and class members alphabetically by member
|
||||||
|
# name. If set to NO, the members will appear in declaration order.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
SORT_MEMBER_DOCS = NO
|
||||||
|
|
||||||
|
# If the SORT_BRIEF_DOCS tag is set to YES then Doxygen will sort the brief
|
||||||
|
# descriptions of file, namespace and class members alphabetically by member
|
||||||
|
# name. If set to NO, the members will appear in declaration order. Note that
|
||||||
|
# this will also influence the order of the classes in the class list.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SORT_BRIEF_DOCS = NO
|
||||||
|
|
||||||
|
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then Doxygen will sort the
|
||||||
|
# (brief and detailed) documentation of class members so that constructors and
|
||||||
|
# destructors are listed first. If set to NO the constructors will appear in the
|
||||||
|
# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
|
||||||
|
# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
|
||||||
|
# member documentation.
|
||||||
|
# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
|
||||||
|
# detailed member documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SORT_MEMBERS_CTORS_1ST = NO
|
||||||
|
|
||||||
|
# If the SORT_GROUP_NAMES tag is set to YES then Doxygen will sort the hierarchy
|
||||||
|
# of group names into alphabetical order. If set to NO the group names will
|
||||||
|
# appear in their defined order.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SORT_GROUP_NAMES = NO
|
||||||
|
|
||||||
|
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
|
||||||
|
# fully-qualified names, including namespaces. If set to NO, the class list will
|
||||||
|
# be sorted only by class name, not including the namespace part.
|
||||||
|
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
|
||||||
|
# Note: This option applies only to the class list, not to the alphabetical
|
||||||
|
# list.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SORT_BY_SCOPE_NAME = NO
|
||||||
|
|
||||||
|
# If the STRICT_PROTO_MATCHING option is enabled and Doxygen fails to do proper
|
||||||
|
# type resolution of all parameters of a function it will reject a match between
|
||||||
|
# the prototype and the implementation of a member function even if there is
|
||||||
|
# only one candidate or it is obvious which candidate to choose by doing a
|
||||||
|
# simple string match. By disabling STRICT_PROTO_MATCHING Doxygen will still
|
||||||
|
# accept a match between prototype and implementation in such cases.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
STRICT_PROTO_MATCHING = NO
|
||||||
|
|
||||||
|
# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
|
||||||
|
# list. This list is created by putting \todo commands in the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
GENERATE_TODOLIST = YES
|
||||||
|
|
||||||
|
# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
|
||||||
|
# list. This list is created by putting \test commands in the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
GENERATE_TESTLIST = YES
|
||||||
|
|
||||||
|
# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
|
||||||
|
# list. This list is created by putting \bug commands in the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
GENERATE_BUGLIST = YES
|
||||||
|
|
||||||
|
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
|
||||||
|
# the deprecated list. This list is created by putting \deprecated commands in
|
||||||
|
# the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
GENERATE_DEPRECATEDLIST= YES
|
||||||
|
|
||||||
|
# The ENABLED_SECTIONS tag can be used to enable conditional documentation
|
||||||
|
# sections, marked by \if <section_label> ... \endif and \cond <section_label>
|
||||||
|
# ... \endcond blocks.
|
||||||
|
|
||||||
|
ENABLED_SECTIONS =
|
||||||
|
|
||||||
|
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
|
||||||
|
# initial value of a variable or macro / define can have for it to appear in the
|
||||||
|
# documentation. If the initializer consists of more lines than specified here
|
||||||
|
# it will be hidden. Use a value of 0 to hide initializers completely. The
|
||||||
|
# appearance of the value of individual variables and macros / defines can be
|
||||||
|
# controlled using \showinitializer or \hideinitializer command in the
|
||||||
|
# documentation regardless of this setting.
|
||||||
|
# Minimum value: 0, maximum value: 10000, default value: 30.
|
||||||
|
|
||||||
|
MAX_INITIALIZER_LINES = 30
|
||||||
|
|
||||||
|
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
|
||||||
|
# the bottom of the documentation of classes and structs. If set to YES, the
|
||||||
|
# list will mention the files that were used to generate the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
SHOW_USED_FILES = YES
|
||||||
|
|
||||||
|
# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
|
||||||
|
# will remove the Files entry from the Quick Index and from the Folder Tree View
|
||||||
|
# (if specified).
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
SHOW_FILES = YES
|
||||||
|
|
||||||
|
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
|
||||||
|
# page. This will remove the Namespaces entry from the Quick Index and from the
|
||||||
|
# Folder Tree View (if specified).
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
SHOW_NAMESPACES = YES
|
||||||
|
|
||||||
|
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
|
||||||
|
# Doxygen should invoke to get the current version for each file (typically from
|
||||||
|
# the version control system). Doxygen will invoke the program by executing (via
|
||||||
|
# popen()) the command command input-file, where command is the value of the
|
||||||
|
# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
|
||||||
|
# by Doxygen. Whatever the program writes to standard output is used as the file
|
||||||
|
# version. For an example see the documentation.
|
||||||
|
|
||||||
|
FILE_VERSION_FILTER =
|
||||||
|
|
||||||
|
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
|
||||||
|
# by Doxygen. The layout file controls the global structure of the generated
|
||||||
|
# output files in an output format independent way. To create the layout file
|
||||||
|
# that represents Doxygen's defaults, run Doxygen with the -l option. You can
|
||||||
|
# optionally specify a file name after the option, if omitted DoxygenLayout.xml
|
||||||
|
# will be used as the name of the layout file. See also section "Changing the
|
||||||
|
# layout of pages" for information.
|
||||||
|
#
|
||||||
|
# Note that if you run Doxygen from a directory containing a file called
|
||||||
|
# DoxygenLayout.xml, Doxygen will parse it automatically even if the LAYOUT_FILE
|
||||||
|
# tag is left empty.
|
||||||
|
|
||||||
|
LAYOUT_FILE =
|
||||||
|
|
||||||
|
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
||||||
|
# the reference definitions. This must be a list of .bib files. The .bib
|
||||||
|
# extension is automatically appended if omitted. This requires the bibtex tool
|
||||||
|
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
|
||||||
|
# For LaTeX the style of the bibliography can be controlled using
|
||||||
|
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
|
||||||
|
# search path. See also \cite for info how to create references.
|
||||||
|
|
||||||
|
CITE_BIB_FILES =
|
||||||
|
|
||||||
|
# The EXTERNAL_TOOL_PATH tag can be used to extend the search path (PATH
|
||||||
|
# environment variable) so that external tools such as latex and gs can be
|
||||||
|
# found.
|
||||||
|
# Note: Directories specified with EXTERNAL_TOOL_PATH are added in front of the
|
||||||
|
# path already specified by the PATH variable, and are added in the order
|
||||||
|
# specified.
|
||||||
|
# Note: This option is particularly useful for macOS version 14 (Sonoma) and
|
||||||
|
# higher, when running Doxygen from Doxywizard, because in this case any user-
|
||||||
|
# defined changes to the PATH are ignored. A typical example on macOS is to set
|
||||||
|
# EXTERNAL_TOOL_PATH = /Library/TeX/texbin /usr/local/bin
|
||||||
|
# together with the standard path, the full search path used by doxygen when
|
||||||
|
# launching external tools will then become
|
||||||
|
# PATH=/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||||
|
|
||||||
|
EXTERNAL_TOOL_PATH =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to warning and progress messages
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# The QUIET tag can be used to turn on/off the messages that are generated to
|
||||||
|
# standard output by Doxygen. If QUIET is set to YES this implies that the
|
||||||
|
# messages are off.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
QUIET = NO
|
||||||
|
|
||||||
|
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
||||||
|
# generated to standard error (stderr) by Doxygen. If WARNINGS is set to YES
|
||||||
|
# this implies that the warnings are on.
|
||||||
|
#
|
||||||
|
# Tip: Turn warnings on while writing the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
WARNINGS = YES
|
||||||
|
|
||||||
|
# If the WARN_IF_UNDOCUMENTED tag is set to YES then Doxygen will generate
|
||||||
|
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
|
||||||
|
# will automatically be disabled.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
WARN_IF_UNDOCUMENTED = YES
|
||||||
|
|
||||||
|
# If the WARN_IF_DOC_ERROR tag is set to YES, Doxygen will generate warnings for
|
||||||
|
# potential errors in the documentation, such as documenting some parameters in
|
||||||
|
# a documented function twice, or documenting parameters that don't exist or
|
||||||
|
# using markup commands wrongly.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
WARN_IF_DOC_ERROR = YES
|
||||||
|
|
||||||
|
# If WARN_IF_INCOMPLETE_DOC is set to YES, Doxygen will warn about incomplete
|
||||||
|
# function parameter documentation. If set to NO, Doxygen will accept that some
|
||||||
|
# parameters have no documentation without warning.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
WARN_IF_INCOMPLETE_DOC = YES
|
||||||
|
|
||||||
|
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
|
||||||
|
# are documented, but have no documentation for their parameters or return
|
||||||
|
# value. If set to NO, Doxygen will only warn about wrong parameter
|
||||||
|
# documentation, but not about the absence of documentation. If EXTRACT_ALL is
|
||||||
|
# set to YES then this flag will automatically be disabled. See also
|
||||||
|
# WARN_IF_INCOMPLETE_DOC
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
WARN_NO_PARAMDOC = NO
|
||||||
|
|
||||||
|
# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, Doxygen will warn about
|
||||||
|
# undocumented enumeration values. If set to NO, Doxygen will accept
|
||||||
|
# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag
|
||||||
|
# will automatically be disabled.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
WARN_IF_UNDOC_ENUM_VAL = NO
|
||||||
|
|
||||||
|
# If WARN_LAYOUT_FILE option is set to YES, Doxygen will warn about issues found
|
||||||
|
# while parsing the user defined layout file, such as missing or wrong elements.
|
||||||
|
# See also LAYOUT_FILE for details. If set to NO, problems with the layout file
|
||||||
|
# will be suppressed.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
WARN_LAYOUT_FILE = YES
|
||||||
|
|
||||||
|
# If the WARN_AS_ERROR tag is set to YES then Doxygen will immediately stop when
|
||||||
|
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
||||||
|
# then Doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
||||||
|
# at the end of the Doxygen process Doxygen will return with a non-zero status.
|
||||||
|
# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then Doxygen behaves
|
||||||
|
# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined Doxygen will not
|
||||||
|
# write the warning messages in between other messages but write them at the end
|
||||||
|
# of a run, in case a WARN_LOGFILE is defined the warning messages will be
|
||||||
|
# besides being in the defined file also be shown at the end of a run, unless
|
||||||
|
# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case
|
||||||
|
# the behavior will remain as with the setting FAIL_ON_WARNINGS.
|
||||||
|
# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
WARN_AS_ERROR = NO
|
||||||
|
|
||||||
|
# The WARN_FORMAT tag determines the format of the warning messages that Doxygen
|
||||||
|
# can produce. The string should contain the $file, $line, and $text tags, which
|
||||||
|
# will be replaced by the file and line number from which the warning originated
|
||||||
|
# and the warning text. Optionally the format may contain $version, which will
|
||||||
|
# be replaced by the version of the file (if it could be obtained via
|
||||||
|
# FILE_VERSION_FILTER)
|
||||||
|
# See also: WARN_LINE_FORMAT
|
||||||
|
# The default value is: $file:$line: $text.
|
||||||
|
|
||||||
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
|
||||||
|
# In the $text part of the WARN_FORMAT command it is possible that a reference
|
||||||
|
# to a more specific place is given. To make it easier to jump to this place
|
||||||
|
# (outside of Doxygen) the user can define a custom "cut" / "paste" string.
|
||||||
|
# Example:
|
||||||
|
# WARN_LINE_FORMAT = "'vi $file +$line'"
|
||||||
|
# See also: WARN_FORMAT
|
||||||
|
# The default value is: at line $line of file $file.
|
||||||
|
|
||||||
|
WARN_LINE_FORMAT = "at line $line of file $file"
|
||||||
|
|
||||||
|
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
|
||||||
|
# messages should be written. If left blank the output is written to standard
|
||||||
|
# error (stderr). In case the file specified cannot be opened for writing the
|
||||||
|
# warning and error messages are written to standard error. When as file - is
|
||||||
|
# specified the warning and error messages are written to standard output
|
||||||
|
# (stdout).
|
||||||
|
|
||||||
|
WARN_LOGFILE =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the input files
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# The INPUT tag is used to specify the files and/or directories that contain
|
||||||
|
# documented source files. You may enter file names like myfile.cpp or
|
||||||
|
# directories like /usr/src/myproject. Separate the files or directories with
|
||||||
|
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||||
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
|
INPUT = ../ \
|
||||||
|
../Modbus/Inc \
|
||||||
|
../Modbus/Src
|
||||||
|
|
||||||
|
# This tag can be used to specify the character encoding of the source files
|
||||||
|
# that Doxygen parses. Internally Doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||||
|
# documentation (see:
|
||||||
|
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
||||||
|
# See also: INPUT_FILE_ENCODING
|
||||||
|
# The default value is: UTF-8.
|
||||||
|
|
||||||
|
INPUT_ENCODING = UTF-8
|
||||||
|
|
||||||
|
# This tag can be used to specify the character encoding of the source files
|
||||||
|
# that Doxygen parses. The INPUT_FILE_ENCODING tag can be used to specify
|
||||||
|
# character encoding on a per file pattern basis. Doxygen will compare the file
|
||||||
|
# name with each pattern and apply the encoding instead of the default
|
||||||
|
# INPUT_ENCODING if there is a match. The character encodings are a list of the
|
||||||
|
# form: pattern=encoding (like *.php=ISO-8859-1).
|
||||||
|
# See also: INPUT_ENCODING for further information on supported encodings.
|
||||||
|
|
||||||
|
INPUT_FILE_ENCODING =
|
||||||
|
|
||||||
|
# If the value of the INPUT tag contains directories, you can use the
|
||||||
|
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
|
||||||
|
# *.h) to filter out the source-files in the directories.
|
||||||
|
#
|
||||||
|
# Note that for custom extensions or not directly supported extensions you also
|
||||||
|
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||||
|
# read by Doxygen.
|
||||||
|
#
|
||||||
|
# Note the list of default checked file patterns might differ from the list of
|
||||||
|
# default file extension mappings.
|
||||||
|
#
|
||||||
|
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm,
|
||||||
|
# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl,
|
||||||
|
# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php,
|
||||||
|
# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be
|
||||||
|
# provided as Doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
|
||||||
|
# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
|
||||||
|
|
||||||
|
FILE_PATTERNS = *.c \
|
||||||
|
*.cc \
|
||||||
|
*.cxx \
|
||||||
|
*.cxxm \
|
||||||
|
*.cpp \
|
||||||
|
*.cppm \
|
||||||
|
*.ccm \
|
||||||
|
*.c++ \
|
||||||
|
*.c++m \
|
||||||
|
*.java \
|
||||||
|
*.ii \
|
||||||
|
*.ixx \
|
||||||
|
*.ipp \
|
||||||
|
*.i++ \
|
||||||
|
*.inl \
|
||||||
|
*.idl \
|
||||||
|
*.ddl \
|
||||||
|
*.odl \
|
||||||
|
*.h \
|
||||||
|
*.hh \
|
||||||
|
*.hxx \
|
||||||
|
*.hpp \
|
||||||
|
*.h++ \
|
||||||
|
*.l \
|
||||||
|
*.cs \
|
||||||
|
*.d \
|
||||||
|
*.php \
|
||||||
|
*.php4 \
|
||||||
|
*.php5 \
|
||||||
|
*.phtml \
|
||||||
|
*.inc \
|
||||||
|
*.m \
|
||||||
|
*.markdown \
|
||||||
|
*.md \
|
||||||
|
*.mm \
|
||||||
|
*.dox \
|
||||||
|
*.py \
|
||||||
|
*.pyw \
|
||||||
|
*.f90 \
|
||||||
|
*.f95 \
|
||||||
|
*.f03 \
|
||||||
|
*.f08 \
|
||||||
|
*.f18 \
|
||||||
|
*.f \
|
||||||
|
*.for \
|
||||||
|
*.vhd \
|
||||||
|
*.vhdl \
|
||||||
|
*.ucf \
|
||||||
|
*.qsf \
|
||||||
|
*.ice
|
||||||
|
|
||||||
|
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||||
|
# be searched for input files as well.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
RECURSIVE = NO
|
||||||
|
|
||||||
|
# The EXCLUDE tag can be used to specify files and/or directories that should be
|
||||||
|
# excluded from the INPUT source files. This way you can easily exclude a
|
||||||
|
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||||
|
#
|
||||||
|
# Note that relative paths are relative to the directory from which Doxygen is
|
||||||
|
# run.
|
||||||
|
|
||||||
|
EXCLUDE =
|
||||||
|
|
||||||
|
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||||
|
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||||
|
# from the input.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXCLUDE_SYMLINKS = NO
|
||||||
|
|
||||||
|
# If the value of the INPUT tag contains directories, you can use the
|
||||||
|
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
||||||
|
# certain files from those directories.
|
||||||
|
#
|
||||||
|
# Note that the wildcards are matched against the file with absolute path, so to
|
||||||
|
# exclude all test directories for example use the pattern */test/*
|
||||||
|
|
||||||
|
EXCLUDE_PATTERNS =
|
||||||
|
|
||||||
|
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||||
|
# (namespaces, classes, functions, etc.) that should be excluded from the
|
||||||
|
# output. The symbol name can be a fully qualified name, a word, or if the
|
||||||
|
# wildcard * is used, a substring. Examples: ANamespace, AClass,
|
||||||
|
# ANamespace::AClass, ANamespace::*Test
|
||||||
|
|
||||||
|
EXCLUDE_SYMBOLS = Q16_MUL
|
||||||
|
|
||||||
|
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
||||||
|
# that contain example code fragments that are included (see the \include
|
||||||
|
# command).
|
||||||
|
|
||||||
|
EXAMPLE_PATH =
|
||||||
|
|
||||||
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||||
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||||
|
# *.h) to filter out the source-files in the directories. If left blank all
|
||||||
|
# files are included.
|
||||||
|
|
||||||
|
EXAMPLE_PATTERNS = *
|
||||||
|
|
||||||
|
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
|
||||||
|
# searched for input files to be used with the \include or \dontinclude commands
|
||||||
|
# irrespective of the value of the RECURSIVE tag.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
EXAMPLE_RECURSIVE = NO
|
||||||
|
|
||||||
|
# The IMAGE_PATH tag can be used to specify one or more files or directories
|
||||||
|
# that contain images that are to be included in the documentation (see the
|
||||||
|
# \image command).
|
||||||
|
|
||||||
|
IMAGE_PATH =
|
||||||
|
|
||||||
|
# The INPUT_FILTER tag can be used to specify a program that Doxygen should
|
||||||
|
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||||
|
# by executing (via popen()) the command:
|
||||||
|
#
|
||||||
|
# <filter> <input-file>
|
||||||
|
#
|
||||||
|
# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
|
||||||
|
# name of an input file. Doxygen will then use the output that the filter
|
||||||
|
# program writes to standard output. If FILTER_PATTERNS is specified, this tag
|
||||||
|
# will be ignored.
|
||||||
|
#
|
||||||
|
# Note that the filter must not add or remove lines; it is applied before the
|
||||||
|
# code is scanned, but not when the output code is generated. If lines are added
|
||||||
|
# or removed, the anchors will not be placed correctly.
|
||||||
|
#
|
||||||
|
# Note that Doxygen will use the data processed and written to standard output
|
||||||
|
# for further processing, therefore nothing else, like debug statements or used
|
||||||
|
# commands (so in case of a Windows batch file always use @echo OFF), should be
|
||||||
|
# written to standard output.
|
||||||
|
#
|
||||||
|
# Note that for custom extensions or not directly supported extensions you also
|
||||||
|
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||||
|
# properly processed by Doxygen.
|
||||||
|
|
||||||
|
INPUT_FILTER =
|
||||||
|
|
||||||
|
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
|
||||||
|
# basis. Doxygen will compare the file name with each pattern and apply the
|
||||||
|
# filter if there is a match. The filters are a list of the form: pattern=filter
|
||||||
|
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
|
||||||
|
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
|
||||||
|
# patterns match the file name, INPUT_FILTER is applied.
|
||||||
|
#
|
||||||
|
# Note that for custom extensions or not directly supported extensions you also
|
||||||
|
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||||
|
# properly processed by Doxygen.
|
||||||
|
|
||||||
|
FILTER_PATTERNS =
|
||||||
|
|
||||||
|
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
|
||||||
|
# INPUT_FILTER) will also be used to filter the input files that are used for
|
||||||
|
# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
FILTER_SOURCE_FILES = NO
|
||||||
|
|
||||||
|
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
|
||||||
|
# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
|
||||||
|
# it is also possible to disable source filtering for a specific pattern using
|
||||||
|
# *.ext= (so without naming a filter).
|
||||||
|
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
|
||||||
|
|
||||||
|
FILTER_SOURCE_PATTERNS =
|
||||||
|
|
||||||
|
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
|
||||||
|
# is part of the input, its contents will be placed on the main page
|
||||||
|
# (index.html). This can be useful if you have a project on for instance GitHub
|
||||||
|
# and want to reuse the introduction page also for the Doxygen output.
|
||||||
|
|
||||||
|
USE_MDFILE_AS_MAINPAGE = ..\README.md
|
||||||
|
|
||||||
|
# If the IMPLICIT_DIR_DOCS tag is set to YES, any README.md file found in sub-
|
||||||
|
# directories of the project's root, is used as the documentation for that sub-
|
||||||
|
# directory, except when the README.md starts with a \dir, \page or \mainpage
|
||||||
|
# command. If set to NO, the README.md file needs to start with an explicit \dir
|
||||||
|
# command in order to be used as directory documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
IMPLICIT_DIR_DOCS = NO
|
||||||
|
|
||||||
|
# The Fortran standard specifies that for fixed formatted Fortran code all
|
||||||
|
# characters from position 72 are to be considered as comment. A common
|
||||||
|
# extension is to allow longer lines before the automatic comment starts. The
|
||||||
|
# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can
|
||||||
|
# be processed before the automatic comment starts.
|
||||||
|
# Minimum value: 7, maximum value: 10000, default value: 72.
|
||||||
|
|
||||||
|
FORTRAN_COMMENT_AFTER = 72
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to source browsing
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
|
||||||
|
# generated. Documented entities will be cross-referenced with these sources.
|
||||||
|
#
|
||||||
|
# Note: To get rid of all source code in the generated output, make sure that
|
||||||
|
# also VERBATIM_HEADERS is set to NO.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SOURCE_BROWSER = YES
|
||||||
|
|
||||||
|
# Setting the INLINE_SOURCES tag to YES will include the body of functions,
|
||||||
|
# multi-line macros, enums or list initialized variables directly into the
|
||||||
|
# documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
INLINE_SOURCES = NO
|
||||||
|
|
||||||
|
# Setting the STRIP_CODE_COMMENTS tag to YES will instruct Doxygen to hide any
|
||||||
|
# special comment blocks from generated source code fragments. Normal C, C++ and
|
||||||
|
# Fortran comments will always remain visible.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
STRIP_CODE_COMMENTS = NO
|
||||||
|
|
||||||
|
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
|
||||||
|
# entity all documented functions referencing it will be listed.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
REFERENCED_BY_RELATION = NO
|
||||||
|
|
||||||
|
# If the REFERENCES_RELATION tag is set to YES then for each documented function
|
||||||
|
# all documented entities called/used by that function will be listed.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
REFERENCES_RELATION = NO
|
||||||
|
|
||||||
|
# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
|
||||||
|
# to YES then the hyperlinks from functions in REFERENCES_RELATION and
|
||||||
|
# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
|
||||||
|
# link to the documentation.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
|
||||||
|
# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
|
||||||
|
# source code will show a tooltip with additional information such as prototype,
|
||||||
|
# brief description and links to the definition and documentation. Since this
|
||||||
|
# will make the HTML file larger and loading of large files a bit slower, you
|
||||||
|
# can opt to disable this feature.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag SOURCE_BROWSER is set to YES.
|
||||||
|
|
||||||
|
SOURCE_TOOLTIPS = YES
|
||||||
|
|
||||||
|
# If the USE_HTAGS tag is set to YES then the references to source code will
|
||||||
|
# point to the HTML generated by the htags(1) tool instead of Doxygen built-in
|
||||||
|
# source browser. The htags tool is part of GNU's global source tagging system
|
||||||
|
# (see https://www.gnu.org/software/global/global.html). You will need version
|
||||||
|
# 4.8.6 or higher.
|
||||||
|
#
|
||||||
|
# To use it do the following:
|
||||||
|
# - Install the latest version of global
|
||||||
|
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
|
||||||
|
# - Make sure the INPUT points to the root of the source tree
|
||||||
|
# - Run doxygen as normal
|
||||||
|
#
|
||||||
|
# Doxygen will invoke htags (and that will in turn invoke gtags), so these
|
||||||
|
# tools must be available from the command line (i.e. in the search path).
|
||||||
|
#
|
||||||
|
# The result: instead of the source browser generated by Doxygen, the links to
|
||||||
|
# source code will now point to the output of htags.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag SOURCE_BROWSER is set to YES.
|
||||||
|
|
||||||
|
USE_HTAGS = NO
|
||||||
|
|
||||||
|
# If the VERBATIM_HEADERS tag is set the YES then Doxygen will generate a
|
||||||
|
# verbatim copy of the header file for each class for which an include is
|
||||||
|
# specified. Set to NO to disable this.
|
||||||
|
# See also: Section \class.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
VERBATIM_HEADERS = YES
|
||||||
|
|
||||||
|
# If the CLANG_ASSISTED_PARSING tag is set to YES then Doxygen will use the
|
||||||
|
# clang parser (see:
|
||||||
|
# http://clang.llvm.org/) for more accurate parsing at the cost of reduced
|
||||||
|
# performance. This can be particularly helpful with template rich C++ code for
|
||||||
|
# which Doxygen's built-in parser lacks the necessary type information.
|
||||||
|
# Note: The availability of this option depends on whether or not Doxygen was
|
||||||
|
# generated with the -Duse_libclang=ON option for CMake.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
CLANG_ASSISTED_PARSING = NO
|
||||||
|
|
||||||
|
# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS
|
||||||
|
# tag is set to YES then Doxygen will add the directory of each input to the
|
||||||
|
# include path.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
||||||
|
|
||||||
|
CLANG_ADD_INC_PATHS = YES
|
||||||
|
|
||||||
|
# If clang assisted parsing is enabled you can provide the compiler with command
|
||||||
|
# line options that you would normally use when invoking the compiler. Note that
|
||||||
|
# the include paths will already be set by Doxygen for the files and directories
|
||||||
|
# specified with INPUT and INCLUDE_PATH.
|
||||||
|
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
||||||
|
|
||||||
|
CLANG_OPTIONS =
|
||||||
|
|
||||||
|
# If clang assisted parsing is enabled you can provide the clang parser with the
|
||||||
|
# path to the directory containing a file called compile_commands.json. This
|
||||||
|
# file is the compilation database (see:
|
||||||
|
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the
|
||||||
|
# options used when the source files were built. This is equivalent to
|
||||||
|
# specifying the -p option to a clang tool, such as clang-check. These options
|
||||||
|
# will then be passed to the parser. Any options specified with CLANG_OPTIONS
|
||||||
|
# will be added as well.
|
||||||
|
# Note: The availability of this option depends on whether or not Doxygen was
|
||||||
|
# generated with the -Duse_libclang=ON option for CMake.
|
||||||
|
|
||||||
|
CLANG_DATABASE_PATH =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the alphabetical class index
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
|
||||||
|
# compounds will be generated. Enable this if the project contains a lot of
|
||||||
|
# classes, structs, unions or interfaces.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
ALPHABETICAL_INDEX = YES
|
||||||
|
|
||||||
|
# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes)
|
||||||
|
# that should be ignored while generating the index headers. The IGNORE_PREFIX
|
||||||
|
# tag works for classes, function and member names. The entity will be placed in
|
||||||
|
# the alphabetical list under the first letter of the entity name that remains
|
||||||
|
# after removing the prefix.
|
||||||
|
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||||
|
|
||||||
|
IGNORE_PREFIX =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the HTML output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_HTML tag is set to YES, Doxygen will generate HTML output
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
GENERATE_HTML = YES
|
||||||
|
|
||||||
|
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
|
||||||
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
|
# it.
|
||||||
|
# The default directory is: html.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_OUTPUT = html
|
||||||
|
|
||||||
|
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||||
|
# generated HTML page (for example: .htm, .php, .asp).
|
||||||
|
# The default value is: .html.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_FILE_EXTENSION = .html
|
||||||
|
|
||||||
|
# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
|
||||||
|
# each generated HTML page. If the tag is left blank Doxygen will generate a
|
||||||
|
# standard header.
|
||||||
|
#
|
||||||
|
# To get valid HTML the header file that includes any scripts and style sheets
|
||||||
|
# that Doxygen needs, which is dependent on the configuration options used (e.g.
|
||||||
|
# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
|
||||||
|
# default header using
|
||||||
|
# doxygen -w html new_header.html new_footer.html new_stylesheet.css
|
||||||
|
# YourConfigFile
|
||||||
|
# and then modify the file new_header.html. See also section "Doxygen usage"
|
||||||
|
# for information on how to generate the default header that Doxygen normally
|
||||||
|
# uses.
|
||||||
|
# Note: The header is subject to change so you typically have to regenerate the
|
||||||
|
# default header when upgrading to a newer version of Doxygen. For a description
|
||||||
|
# of the possible markers and block names see the documentation.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_HEADER =
|
||||||
|
|
||||||
|
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
||||||
|
# generated HTML page. If the tag is left blank Doxygen will generate a standard
|
||||||
|
# footer. See HTML_HEADER for more information on how to generate a default
|
||||||
|
# footer and what special commands can be used inside the footer. See also
|
||||||
|
# section "Doxygen usage" for information on how to generate the default footer
|
||||||
|
# that Doxygen normally uses.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_FOOTER =
|
||||||
|
|
||||||
|
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
||||||
|
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
||||||
|
# the HTML output. If left blank Doxygen will generate a default style sheet.
|
||||||
|
# See also section "Doxygen usage" for information on how to generate the style
|
||||||
|
# sheet that Doxygen normally uses.
|
||||||
|
# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
|
||||||
|
# it is more robust and this tag (HTML_STYLESHEET) will in the future become
|
||||||
|
# obsolete.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_STYLESHEET =
|
||||||
|
|
||||||
|
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
|
||||||
|
# cascading style sheets that are included after the standard style sheets
|
||||||
|
# created by Doxygen. Using this option one can overrule certain style aspects.
|
||||||
|
# This is preferred over using HTML_STYLESHEET since it does not replace the
|
||||||
|
# standard style sheet and is therefore more robust against future updates.
|
||||||
|
# Doxygen will copy the style sheet files to the output directory.
|
||||||
|
# Note: The order of the extra style sheet files is of importance (e.g. the last
|
||||||
|
# style sheet in the list overrules the setting of the previous ones in the
|
||||||
|
# list).
|
||||||
|
# Note: Since the styling of scrollbars can currently not be overruled in
|
||||||
|
# Webkit/Chromium, the styling will be left out of the default doxygen.css if
|
||||||
|
# one or more extra stylesheets have been specified. So if scrollbar
|
||||||
|
# customization is desired it has to be added explicitly. For an example see the
|
||||||
|
# documentation.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_EXTRA_STYLESHEET =
|
||||||
|
|
||||||
|
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||||
|
# other source files which should be copied to the HTML output directory. Note
|
||||||
|
# that these files will be copied to the base HTML output directory. Use the
|
||||||
|
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
|
||||||
|
# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
|
||||||
|
# files will be copied as-is; there are no commands or markers available.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_EXTRA_FILES =
|
||||||
|
|
||||||
|
# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
|
||||||
|
# should be rendered with a dark or light theme.
|
||||||
|
# Possible values are: LIGHT always generates light mode output, DARK always
|
||||||
|
# generates dark mode output, AUTO_LIGHT automatically sets the mode according
|
||||||
|
# to the user preference, uses light mode if no preference is set (the default),
|
||||||
|
# AUTO_DARK automatically sets the mode according to the user preference, uses
|
||||||
|
# dark mode if no preference is set and TOGGLE allows a user to switch between
|
||||||
|
# light and dark mode via a button.
|
||||||
|
# The default value is: AUTO_LIGHT.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_COLORSTYLE = TOGGLE
|
||||||
|
|
||||||
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||||
|
# will adjust the colors in the style sheet and background images according to
|
||||||
|
# this color. Hue is specified as an angle on a color-wheel, see
|
||||||
|
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
|
||||||
|
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
|
||||||
|
# purple, and 360 is red again.
|
||||||
|
# Minimum value: 0, maximum value: 359, default value: 220.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_COLORSTYLE_HUE = 220
|
||||||
|
|
||||||
|
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
|
||||||
|
# in the HTML output. For a value of 0 the output will use gray-scales only. A
|
||||||
|
# value of 255 will produce the most vivid colors.
|
||||||
|
# Minimum value: 0, maximum value: 255, default value: 100.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_COLORSTYLE_SAT = 100
|
||||||
|
|
||||||
|
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
|
||||||
|
# luminance component of the colors in the HTML output. Values below 100
|
||||||
|
# gradually make the output lighter, whereas values above 100 make the output
|
||||||
|
# darker. The value divided by 100 is the actual gamma applied, so 80 represents
|
||||||
|
# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
|
||||||
|
# change the gamma.
|
||||||
|
# Minimum value: 40, maximum value: 240, default value: 80.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_COLORSTYLE_GAMMA = 80
|
||||||
|
|
||||||
|
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
||||||
|
# documentation will contain a main index with vertical navigation menus that
|
||||||
|
# are dynamically created via JavaScript. If disabled, the navigation index will
|
||||||
|
# consists of multiple levels of tabs that are statically embedded in every HTML
|
||||||
|
# page. Disable this option to support browsers that do not have JavaScript,
|
||||||
|
# like the Qt help browser.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_DYNAMIC_MENUS = YES
|
||||||
|
|
||||||
|
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
|
||||||
|
# documentation will contain sections that can be hidden and shown after the
|
||||||
|
# page has loaded.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_DYNAMIC_SECTIONS = YES
|
||||||
|
|
||||||
|
# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be
|
||||||
|
# dynamically folded and expanded in the generated HTML source code.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_CODE_FOLDING = YES
|
||||||
|
|
||||||
|
# If the HTML_COPY_CLIPBOARD tag is set to YES then Doxygen will show an icon in
|
||||||
|
# the top right corner of code and text fragments that allows the user to copy
|
||||||
|
# its content to the clipboard. Note this only works if supported by the browser
|
||||||
|
# and the web page is served via a secure context (see:
|
||||||
|
# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file:
|
||||||
|
# protocol.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_COPY_CLIPBOARD = YES
|
||||||
|
|
||||||
|
# Doxygen stores a couple of settings persistently in the browser (via e.g.
|
||||||
|
# cookies). By default these settings apply to all HTML pages generated by
|
||||||
|
# Doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store
|
||||||
|
# the settings under a project specific key, such that the user preferences will
|
||||||
|
# be stored separately.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_PROJECT_COOKIE =
|
||||||
|
|
||||||
|
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
|
||||||
|
# shown in the various tree structured indices initially; the user can expand
|
||||||
|
# and collapse entries dynamically later on. Doxygen will expand the tree to
|
||||||
|
# such a level that at most the specified number of entries are visible (unless
|
||||||
|
# a fully collapsed tree already exceeds this amount). So setting the number of
|
||||||
|
# entries 1 will produce a full collapsed tree by default. 0 is a special value
|
||||||
|
# representing an infinite number of entries and will result in a full expanded
|
||||||
|
# tree by default.
|
||||||
|
# Minimum value: 0, maximum value: 9999, default value: 100.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_INDEX_NUM_ENTRIES = 100
|
||||||
|
|
||||||
|
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
|
||||||
|
# generated that can be used as input for Apple's Xcode 3 integrated development
|
||||||
|
# environment (see:
|
||||||
|
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
|
||||||
|
# create a documentation set, Doxygen will generate a Makefile in the HTML
|
||||||
|
# output directory. Running make will produce the docset in that directory and
|
||||||
|
# running make install will install the docset in
|
||||||
|
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
|
||||||
|
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
|
||||||
|
# genXcode/_index.html for more information.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
GENERATE_DOCSET = NO
|
||||||
|
|
||||||
|
# This tag determines the name of the docset feed. A documentation feed provides
|
||||||
|
# an umbrella under which multiple documentation sets from a single provider
|
||||||
|
# (such as a company or product suite) can be grouped.
|
||||||
|
# The default value is: Doxygen generated docs.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
|
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||||
|
|
||||||
|
# This tag determines the URL of the docset feed. A documentation feed provides
|
||||||
|
# an umbrella under which multiple documentation sets from a single provider
|
||||||
|
# (such as a company or product suite) can be grouped.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
|
DOCSET_FEEDURL =
|
||||||
|
|
||||||
|
# This tag specifies a string that should uniquely identify the documentation
|
||||||
|
# set bundle. This should be a reverse domain-name style string, e.g.
|
||||||
|
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
|
||||||
|
# The default value is: org.doxygen.Project.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
|
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||||
|
|
||||||
|
# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
|
||||||
|
# the documentation publisher. This should be a reverse domain-name style
|
||||||
|
# string, e.g. com.mycompany.MyDocSet.documentation.
|
||||||
|
# The default value is: org.doxygen.Publisher.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
|
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||||
|
|
||||||
|
# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
|
||||||
|
# The default value is: Publisher.
|
||||||
|
# This tag requires that the tag GENERATE_DOCSET is set to YES.
|
||||||
|
|
||||||
|
DOCSET_PUBLISHER_NAME = Publisher
|
||||||
|
|
||||||
|
# If the GENERATE_HTMLHELP tag is set to YES then Doxygen generates three
|
||||||
|
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
|
||||||
|
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
|
||||||
|
# on Windows. In the beginning of 2021 Microsoft took the original page, with
|
||||||
|
# a.o. the download links, offline (the HTML help workshop was already many
|
||||||
|
# years in maintenance mode). You can download the HTML help workshop from the
|
||||||
|
# web archives at Installation executable (see:
|
||||||
|
# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo
|
||||||
|
# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe).
|
||||||
|
#
|
||||||
|
# The HTML Help Workshop contains a compiler that can convert all HTML output
|
||||||
|
# generated by Doxygen into a single compiled HTML file (.chm). Compiled HTML
|
||||||
|
# files are now used as the Windows 98 help format, and will replace the old
|
||||||
|
# Windows help format (.hlp) on all Windows platforms in the future. Compressed
|
||||||
|
# HTML files also contain an index, a table of contents, and you can search for
|
||||||
|
# words in the documentation. The HTML workshop also contains a viewer for
|
||||||
|
# compressed HTML files.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
GENERATE_HTMLHELP = NO
|
||||||
|
|
||||||
|
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
|
||||||
|
# file. You can add a path in front of the file if the result should not be
|
||||||
|
# written to the html output directory.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
|
CHM_FILE =
|
||||||
|
|
||||||
|
# The HHC_LOCATION tag can be used to specify the location (absolute path
|
||||||
|
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
|
||||||
|
# Doxygen will try to run the HTML help compiler on the generated index.hhp.
|
||||||
|
# The file has to be specified with full path.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
|
HHC_LOCATION =
|
||||||
|
|
||||||
|
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
||||||
|
# (YES) or that it should be included in the main .chm file (NO).
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
|
GENERATE_CHI = NO
|
||||||
|
|
||||||
|
# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
|
||||||
|
# and project file content.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
|
CHM_INDEX_ENCODING =
|
||||||
|
|
||||||
|
# The BINARY_TOC flag controls whether a binary table of contents is generated
|
||||||
|
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
|
||||||
|
# enables the Previous and Next buttons.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
|
BINARY_TOC = NO
|
||||||
|
|
||||||
|
# The TOC_EXPAND flag can be set to YES to add extra items for group members to
|
||||||
|
# the table of contents of the HTML help documentation and to the tree view.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
|
TOC_EXPAND = NO
|
||||||
|
|
||||||
|
# The SITEMAP_URL tag is used to specify the full URL of the place where the
|
||||||
|
# generated documentation will be placed on the server by the user during the
|
||||||
|
# deployment of the documentation. The generated sitemap is called sitemap.xml
|
||||||
|
# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL
|
||||||
|
# is specified no sitemap is generated. For information about the sitemap
|
||||||
|
# protocol see https://www.sitemaps.org
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
SITEMAP_URL =
|
||||||
|
|
||||||
|
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
|
||||||
|
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
|
||||||
|
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
|
||||||
|
# (.qch) of the generated HTML documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
GENERATE_QHP = NO
|
||||||
|
|
||||||
|
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
|
||||||
|
# the file name of the resulting .qch file. The path specified is relative to
|
||||||
|
# the HTML output folder.
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
|
QCH_FILE =
|
||||||
|
|
||||||
|
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
||||||
|
# Project output. For more information please see Qt Help Project / Namespace
|
||||||
|
# (see:
|
||||||
|
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
|
||||||
|
# The default value is: org.doxygen.Project.
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
|
QHP_NAMESPACE = org.doxygen.Project
|
||||||
|
|
||||||
|
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
|
||||||
|
# Help Project output. For more information please see Qt Help Project / Virtual
|
||||||
|
# Folders (see:
|
||||||
|
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
|
||||||
|
# The default value is: doc.
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
|
QHP_VIRTUAL_FOLDER = doc
|
||||||
|
|
||||||
|
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
|
||||||
|
# filter to add. For more information please see Qt Help Project / Custom
|
||||||
|
# Filters (see:
|
||||||
|
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
|
QHP_CUST_FILTER_NAME =
|
||||||
|
|
||||||
|
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
||||||
|
# custom filter to add. For more information please see Qt Help Project / Custom
|
||||||
|
# Filters (see:
|
||||||
|
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
|
QHP_CUST_FILTER_ATTRS =
|
||||||
|
|
||||||
|
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
|
||||||
|
# project's filter section matches. Qt Help Project / Filter Attributes (see:
|
||||||
|
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
|
QHP_SECT_FILTER_ATTRS =
|
||||||
|
|
||||||
|
# The QHG_LOCATION tag can be used to specify the location (absolute path
|
||||||
|
# including file name) of Qt's qhelpgenerator. If non-empty Doxygen will try to
|
||||||
|
# run qhelpgenerator on the generated .qhp file.
|
||||||
|
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||||
|
|
||||||
|
QHG_LOCATION =
|
||||||
|
|
||||||
|
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
|
||||||
|
# generated, together with the HTML files, they form an Eclipse help plugin. To
|
||||||
|
# install this plugin and make it available under the help contents menu in
|
||||||
|
# Eclipse, the contents of the directory containing the HTML and XML files needs
|
||||||
|
# to be copied into the plugins directory of eclipse. The name of the directory
|
||||||
|
# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
|
||||||
|
# After copying Eclipse needs to be restarted before the help appears.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
GENERATE_ECLIPSEHELP = NO
|
||||||
|
|
||||||
|
# A unique identifier for the Eclipse help plugin. When installing the plugin
|
||||||
|
# the directory name containing the HTML and XML files should also have this
|
||||||
|
# name. Each documentation set should have its own identifier.
|
||||||
|
# The default value is: org.doxygen.Project.
|
||||||
|
# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
|
||||||
|
|
||||||
|
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||||
|
|
||||||
|
# If you want full control over the layout of the generated HTML pages it might
|
||||||
|
# be necessary to disable the index and replace it with your own. The
|
||||||
|
# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
|
||||||
|
# of each HTML page. A value of NO enables the index and the value YES disables
|
||||||
|
# it. Since the tabs in the index contain the same information as the navigation
|
||||||
|
# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
DISABLE_INDEX = NO
|
||||||
|
|
||||||
|
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
|
||||||
|
# structure should be generated to display hierarchical information. If the tag
|
||||||
|
# value is set to YES, a side panel will be generated containing a tree-like
|
||||||
|
# index structure (just like the one that is generated for HTML Help). For this
|
||||||
|
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
|
||||||
|
# (i.e. any modern browser). Windows users are probably better off using the
|
||||||
|
# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
|
||||||
|
# further fine tune the look of the index (see "Fine-tuning the output"). As an
|
||||||
|
# example, the default style sheet generated by Doxygen has an example that
|
||||||
|
# shows how to put an image at the root of the tree instead of the PROJECT_NAME.
|
||||||
|
# Since the tree basically has more details information than the tab index, you
|
||||||
|
# could consider setting DISABLE_INDEX to YES when enabling this option.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
GENERATE_TREEVIEW = YES
|
||||||
|
|
||||||
|
# When GENERATE_TREEVIEW is set to YES, the PAGE_OUTLINE_PANEL option determines
|
||||||
|
# if an additional navigation panel is shown at the right hand side of the
|
||||||
|
# screen, displaying an outline of the contents of the main page, similar to
|
||||||
|
# e.g. https://developer.android.com/reference If GENERATE_TREEVIEW is set to
|
||||||
|
# NO, this option has no effect.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
PAGE_OUTLINE_PANEL = YES
|
||||||
|
|
||||||
|
# When GENERATE_TREEVIEW is set to YES, the FULL_SIDEBAR option determines if
|
||||||
|
# the side bar is limited to only the treeview area (value NO) or if it should
|
||||||
|
# extend to the full height of the window (value YES). Setting this to YES gives
|
||||||
|
# a layout similar to e.g. https://docs.readthedocs.io with more room for
|
||||||
|
# contents, but less room for the project logo, title, and description. If
|
||||||
|
# GENERATE_TREEVIEW is set to NO, this option has no effect.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
FULL_SIDEBAR = NO
|
||||||
|
|
||||||
|
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
|
||||||
|
# Doxygen will group on one line in the generated HTML documentation.
|
||||||
|
#
|
||||||
|
# Note that a value of 0 will completely suppress the enum values from appearing
|
||||||
|
# in the overview section.
|
||||||
|
# Minimum value: 0, maximum value: 20, default value: 4.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
ENUM_VALUES_PER_LINE = 4
|
||||||
|
|
||||||
|
# When the SHOW_ENUM_VALUES tag is set doxygen will show the specified
|
||||||
|
# enumeration values besides the enumeration mnemonics.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
SHOW_ENUM_VALUES = NO
|
||||||
|
|
||||||
|
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
|
||||||
|
# to set the initial width (in pixels) of the frame in which the tree is shown.
|
||||||
|
# Minimum value: 0, maximum value: 1500, default value: 250.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
TREEVIEW_WIDTH = 250
|
||||||
|
|
||||||
|
# If the EXT_LINKS_IN_WINDOW option is set to YES, Doxygen will open links to
|
||||||
|
# external symbols imported via tag files in a separate window.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
EXT_LINKS_IN_WINDOW = NO
|
||||||
|
|
||||||
|
# If the OBFUSCATE_EMAILS tag is set to YES, Doxygen will obfuscate email
|
||||||
|
# addresses.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
OBFUSCATE_EMAILS = YES
|
||||||
|
|
||||||
|
# If the HTML_FORMULA_FORMAT option is set to svg, Doxygen will use the pdf2svg
|
||||||
|
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
|
||||||
|
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
|
||||||
|
# the HTML output. These images will generally look nicer at scaled resolutions.
|
||||||
|
# Possible values are: png (the default) and svg (looks nicer but requires the
|
||||||
|
# pdf2svg or inkscape tool).
|
||||||
|
# The default value is: png.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
HTML_FORMULA_FORMAT = png
|
||||||
|
|
||||||
|
# Use this tag to change the font size of LaTeX formulas included as images in
|
||||||
|
# the HTML documentation. When you change the font size after a successful
|
||||||
|
# Doxygen run you need to manually remove any form_*.png images from the HTML
|
||||||
|
# output directory to force them to be regenerated.
|
||||||
|
# Minimum value: 8, maximum value: 50, default value: 10.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
FORMULA_FONTSIZE = 10
|
||||||
|
|
||||||
|
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
||||||
|
# to create new LaTeX commands to be used in formulas as building blocks. See
|
||||||
|
# the section "Including formulas" for details.
|
||||||
|
|
||||||
|
FORMULA_MACROFILE =
|
||||||
|
|
||||||
|
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
|
||||||
|
# https://www.mathjax.org) which uses client side JavaScript for the rendering
|
||||||
|
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
|
||||||
|
# installed or if you want to formulas look prettier in the HTML output. When
|
||||||
|
# enabled you may also need to install MathJax separately and configure the path
|
||||||
|
# to it using the MATHJAX_RELPATH option.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
USE_MATHJAX = YES
|
||||||
|
|
||||||
|
# With MATHJAX_VERSION it is possible to specify the MathJax version to be used.
|
||||||
|
# Note that the different versions of MathJax have different requirements with
|
||||||
|
# regards to the different settings, so it is possible that also other MathJax
|
||||||
|
# settings have to be changed when switching between the different MathJax
|
||||||
|
# versions.
|
||||||
|
# Possible values are: MathJax_2 and MathJax_3.
|
||||||
|
# The default value is: MathJax_2.
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
|
MATHJAX_VERSION = MathJax_2
|
||||||
|
|
||||||
|
# When MathJax is enabled you can set the default output format to be used for
|
||||||
|
# the MathJax output. For more details about the output format see MathJax
|
||||||
|
# version 2 (see:
|
||||||
|
# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3
|
||||||
|
# (see:
|
||||||
|
# http://docs.mathjax.org/en/latest/web/components/output.html).
|
||||||
|
# Possible values are: HTML-CSS (which is slower, but has the best
|
||||||
|
# compatibility. This is the name for Mathjax version 2, for MathJax version 3
|
||||||
|
# this will be translated into chtml), NativeMML (i.e. MathML. Only supported
|
||||||
|
# for MathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This
|
||||||
|
# is the name for Mathjax version 3, for MathJax version 2 this will be
|
||||||
|
# translated into HTML-CSS) and SVG.
|
||||||
|
# The default value is: HTML-CSS.
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
|
MATHJAX_FORMAT = HTML-CSS
|
||||||
|
|
||||||
|
# When MathJax is enabled you need to specify the location relative to the HTML
|
||||||
|
# output directory using the MATHJAX_RELPATH option. The destination directory
|
||||||
|
# should contain the MathJax.js script. For instance, if the mathjax directory
|
||||||
|
# is located at the same level as the HTML output directory, then
|
||||||
|
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
|
||||||
|
# Content Delivery Network so you can quickly see the result without installing
|
||||||
|
# MathJax. However, it is strongly recommended to install a local copy of
|
||||||
|
# MathJax from https://www.mathjax.org before deployment. The default value is:
|
||||||
|
# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2
|
||||||
|
# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
|
MATHJAX_RELPATH =
|
||||||
|
|
||||||
|
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
||||||
|
# extension names that should be enabled during MathJax rendering. For example
|
||||||
|
# for MathJax version 2 (see
|
||||||
|
# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
|
||||||
|
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
||||||
|
# For example for MathJax version 3 (see
|
||||||
|
# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
|
||||||
|
# MATHJAX_EXTENSIONS = ams
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
|
MATHJAX_EXTENSIONS =
|
||||||
|
|
||||||
|
# The MATHJAX_CODEFILE tag can be used to specify a file with JavaScript pieces
|
||||||
|
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||||
|
# (see:
|
||||||
|
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
|
||||||
|
# example see the documentation.
|
||||||
|
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||||
|
|
||||||
|
MATHJAX_CODEFILE =
|
||||||
|
|
||||||
|
# When the SEARCHENGINE tag is enabled Doxygen will generate a search box for
|
||||||
|
# the HTML output. The underlying search engine uses JavaScript and DHTML and
|
||||||
|
# should work on any modern browser. Note that when using HTML help
|
||||||
|
# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
|
||||||
|
# there is already a search function so this one should typically be disabled.
|
||||||
|
# For large projects the JavaScript based search engine can be slow, then
|
||||||
|
# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
|
||||||
|
# search using the keyboard; to jump to the search box use <access key> + S
|
||||||
|
# (what the <access key> is depends on the OS and browser, but it is typically
|
||||||
|
# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
|
||||||
|
# key> to jump into the search results window, the results can be navigated
|
||||||
|
# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
|
||||||
|
# the search. The filter options can be selected when the cursor is inside the
|
||||||
|
# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
|
||||||
|
# to select a filter and <Enter> or <escape> to activate or cancel the filter
|
||||||
|
# option.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
|
SEARCHENGINE = YES
|
||||||
|
|
||||||
|
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||||
|
# implemented using a web server instead of a web client using JavaScript. There
|
||||||
|
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
|
||||||
|
# setting. When disabled, Doxygen will generate a PHP script for searching and
|
||||||
|
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
|
||||||
|
# and searching needs to be provided by external tools. See the section
|
||||||
|
# "External Indexing and Searching" for details.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
|
SERVER_BASED_SEARCH = NO
|
||||||
|
|
||||||
|
# When EXTERNAL_SEARCH tag is enabled Doxygen will no longer generate the PHP
|
||||||
|
# script for searching. Instead the search results are written to an XML file
|
||||||
|
# which needs to be processed by an external indexer. Doxygen will invoke an
|
||||||
|
# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
|
||||||
|
# search results.
|
||||||
|
#
|
||||||
|
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||||
|
# (doxysearch.cgi) which are based on the open source search engine library
|
||||||
|
# Xapian (see:
|
||||||
|
# https://xapian.org/).
|
||||||
|
#
|
||||||
|
# See the section "External Indexing and Searching" for details.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
|
EXTERNAL_SEARCH = NO
|
||||||
|
|
||||||
|
# The SEARCHENGINE_URL should point to a search engine hosted by a web server
|
||||||
|
# which will return the search results when EXTERNAL_SEARCH is enabled.
|
||||||
|
#
|
||||||
|
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||||
|
# (doxysearch.cgi) which are based on the open source search engine library
|
||||||
|
# Xapian (see:
|
||||||
|
# https://xapian.org/). See the section "External Indexing and Searching" for
|
||||||
|
# details.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
|
SEARCHENGINE_URL =
|
||||||
|
|
||||||
|
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
|
||||||
|
# search data is written to a file for indexing by an external tool. With the
|
||||||
|
# SEARCHDATA_FILE tag the name of this file can be specified.
|
||||||
|
# The default file is: searchdata.xml.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
|
SEARCHDATA_FILE = searchdata.xml
|
||||||
|
|
||||||
|
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
|
||||||
|
# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
|
||||||
|
# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
|
||||||
|
# projects and redirect the results back to the right project.
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
|
EXTERNAL_SEARCH_ID =
|
||||||
|
|
||||||
|
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through Doxygen
|
||||||
|
# projects other than the one defined by this configuration file, but that are
|
||||||
|
# all added to the same external search index. Each project needs to have a
|
||||||
|
# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
|
||||||
|
# to a relative location where the documentation can be found. The format is:
|
||||||
|
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
|
||||||
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
|
EXTRA_SEARCH_MAPPINGS =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the LaTeX output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_LATEX tag is set to YES, Doxygen will generate LaTeX output.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
GENERATE_LATEX = YES
|
||||||
|
|
||||||
|
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
|
||||||
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
|
# it.
|
||||||
|
# The default directory is: latex.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_OUTPUT = latex
|
||||||
|
|
||||||
|
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
|
||||||
|
# invoked.
|
||||||
|
#
|
||||||
|
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
|
||||||
|
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
|
||||||
|
# chosen this is overwritten by pdflatex. For specific output languages the
|
||||||
|
# default can have been set differently, this depends on the implementation of
|
||||||
|
# the output language.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_CMD_NAME =
|
||||||
|
|
||||||
|
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
|
||||||
|
# index for LaTeX.
|
||||||
|
# Note: This tag is used in the Makefile / make.bat.
|
||||||
|
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
|
||||||
|
# (.tex).
|
||||||
|
# The default file is: makeindex.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
MAKEINDEX_CMD_NAME = makeindex
|
||||||
|
|
||||||
|
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
|
||||||
|
# generate index for LaTeX. In case there is no backslash (\) as first character
|
||||||
|
# it will be automatically added in the LaTeX code.
|
||||||
|
# Note: This tag is used in the generated output file (.tex).
|
||||||
|
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
|
||||||
|
# The default value is: makeindex.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_MAKEINDEX_CMD = makeindex
|
||||||
|
|
||||||
|
# If the COMPACT_LATEX tag is set to YES, Doxygen generates more compact LaTeX
|
||||||
|
# documents. This may be useful for small projects and may help to save some
|
||||||
|
# trees in general.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
COMPACT_LATEX = NO
|
||||||
|
|
||||||
|
# The PAPER_TYPE tag can be used to set the paper type that is used by the
|
||||||
|
# printer.
|
||||||
|
# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
|
||||||
|
# 14 inches) and executive (7.25 x 10.5 inches).
|
||||||
|
# The default value is: a4.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
PAPER_TYPE = a4
|
||||||
|
|
||||||
|
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
|
||||||
|
# that should be included in the LaTeX output. The package can be specified just
|
||||||
|
# by its name or with the correct syntax as to be used with the LaTeX
|
||||||
|
# \usepackage command. To get the times font for instance you can specify :
|
||||||
|
# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
|
||||||
|
# To use the option intlimits with the amsmath package you can specify:
|
||||||
|
# EXTRA_PACKAGES=[intlimits]{amsmath}
|
||||||
|
# If left blank no extra packages will be included.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
EXTRA_PACKAGES =
|
||||||
|
|
||||||
|
# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for
|
||||||
|
# the generated LaTeX document. The header should contain everything until the
|
||||||
|
# first chapter. If it is left blank Doxygen will generate a standard header. It
|
||||||
|
# is highly recommended to start with a default header using
|
||||||
|
# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty
|
||||||
|
# and then modify the file new_header.tex. See also section "Doxygen usage" for
|
||||||
|
# information on how to generate the default header that Doxygen normally uses.
|
||||||
|
#
|
||||||
|
# Note: Only use a user-defined header if you know what you are doing!
|
||||||
|
# Note: The header is subject to change so you typically have to regenerate the
|
||||||
|
# default header when upgrading to a newer version of Doxygen. The following
|
||||||
|
# commands have a special meaning inside the header (and footer): For a
|
||||||
|
# description of the possible markers and block names see the documentation.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_HEADER =
|
||||||
|
|
||||||
|
# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for
|
||||||
|
# the generated LaTeX document. The footer should contain everything after the
|
||||||
|
# last chapter. If it is left blank Doxygen will generate a standard footer. See
|
||||||
|
# LATEX_HEADER for more information on how to generate a default footer and what
|
||||||
|
# special commands can be used inside the footer. See also section "Doxygen
|
||||||
|
# usage" for information on how to generate the default footer that Doxygen
|
||||||
|
# normally uses. Note: Only use a user-defined footer if you know what you are
|
||||||
|
# doing!
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_FOOTER =
|
||||||
|
|
||||||
|
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
|
||||||
|
# LaTeX style sheets that are included after the standard style sheets created
|
||||||
|
# by Doxygen. Using this option one can overrule certain style aspects. Doxygen
|
||||||
|
# will copy the style sheet files to the output directory.
|
||||||
|
# Note: The order of the extra style sheet files is of importance (e.g. the last
|
||||||
|
# style sheet in the list overrules the setting of the previous ones in the
|
||||||
|
# list).
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_EXTRA_STYLESHEET =
|
||||||
|
|
||||||
|
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||||
|
# other source files which should be copied to the LATEX_OUTPUT output
|
||||||
|
# directory. Note that the files will be copied as-is; there are no commands or
|
||||||
|
# markers available.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_EXTRA_FILES =
|
||||||
|
|
||||||
|
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
|
||||||
|
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
|
||||||
|
# contain links (just like the HTML output) instead of page references. This
|
||||||
|
# makes the output suitable for online browsing using a PDF viewer.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
PDF_HYPERLINKS = YES
|
||||||
|
|
||||||
|
# If the USE_PDFLATEX tag is set to YES, Doxygen will use the engine as
|
||||||
|
# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
|
||||||
|
# files. Set this option to YES, to get a higher quality PDF documentation.
|
||||||
|
#
|
||||||
|
# See also section LATEX_CMD_NAME for selecting the engine.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
USE_PDFLATEX = YES
|
||||||
|
|
||||||
|
# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error.
|
||||||
|
# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch
|
||||||
|
# mode nothing is printed on the terminal, errors are scrolled as if <return> is
|
||||||
|
# hit at every error; missing files that TeX tries to input or request from
|
||||||
|
# keyboard input (\read on a not open input stream) cause the job to abort,
|
||||||
|
# NON_STOP In nonstop mode the diagnostic message will appear on the terminal,
|
||||||
|
# but there is no possibility of user interaction just like in batch mode,
|
||||||
|
# SCROLL In scroll mode, TeX will stop only for missing files to input or if
|
||||||
|
# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at
|
||||||
|
# each error, asking for user intervention.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_BATCHMODE = NO
|
||||||
|
|
||||||
|
# If the LATEX_HIDE_INDICES tag is set to YES then Doxygen will not include the
|
||||||
|
# index chapters (such as File Index, Compound Index, etc.) in the output.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_HIDE_INDICES = NO
|
||||||
|
|
||||||
|
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
|
||||||
|
# bibliography, e.g. plainnat, or ieeetr. See
|
||||||
|
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
|
||||||
|
# The default value is: plainnat.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_BIB_STYLE = plainnat
|
||||||
|
|
||||||
|
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
|
# path from which the emoji images will be read. If a relative path is entered,
|
||||||
|
# it will be relative to the LATEX_OUTPUT directory. If left blank the
|
||||||
|
# LATEX_OUTPUT directory will be used.
|
||||||
|
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||||
|
|
||||||
|
LATEX_EMOJI_DIRECTORY =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the RTF output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_RTF tag is set to YES, Doxygen will generate RTF output. The
|
||||||
|
# RTF output is optimized for Word 97 and may not look too pretty with other RTF
|
||||||
|
# readers/editors.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
GENERATE_RTF = NO
|
||||||
|
|
||||||
|
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
|
||||||
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
|
# it.
|
||||||
|
# The default directory is: rtf.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
|
RTF_OUTPUT = rtf
|
||||||
|
|
||||||
|
# If the COMPACT_RTF tag is set to YES, Doxygen generates more compact RTF
|
||||||
|
# documents. This may be useful for small projects and may help to save some
|
||||||
|
# trees in general.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
|
COMPACT_RTF = NO
|
||||||
|
|
||||||
|
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
|
||||||
|
# contain hyperlink fields. The RTF file will contain links (just like the HTML
|
||||||
|
# output) instead of page references. This makes the output suitable for online
|
||||||
|
# browsing using Word or some other Word compatible readers that support those
|
||||||
|
# fields.
|
||||||
|
#
|
||||||
|
# Note: WordPad (write) and others do not support links.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
|
RTF_HYPERLINKS = NO
|
||||||
|
|
||||||
|
# Load stylesheet definitions from file. Syntax is similar to Doxygen's
|
||||||
|
# configuration file, i.e. a series of assignments. You only have to provide
|
||||||
|
# replacements, missing definitions are set to their default value.
|
||||||
|
#
|
||||||
|
# See also section "Doxygen usage" for information on how to generate the
|
||||||
|
# default style sheet that Doxygen normally uses.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
|
RTF_STYLESHEET_FILE =
|
||||||
|
|
||||||
|
# Set optional variables used in the generation of an RTF document. Syntax is
|
||||||
|
# similar to Doxygen's configuration file. A template extensions file can be
|
||||||
|
# generated using doxygen -e rtf extensionFile.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
|
RTF_EXTENSIONS_FILE =
|
||||||
|
|
||||||
|
# The RTF_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||||
|
# other source files which should be copied to the RTF_OUTPUT output directory.
|
||||||
|
# Note that the files will be copied as-is; there are no commands or markers
|
||||||
|
# available.
|
||||||
|
# This tag requires that the tag GENERATE_RTF is set to YES.
|
||||||
|
|
||||||
|
RTF_EXTRA_FILES =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the man page output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_MAN tag is set to YES, Doxygen will generate man pages for
|
||||||
|
# classes and files.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
GENERATE_MAN = NO
|
||||||
|
|
||||||
|
# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
|
||||||
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
|
# it. A directory man3 will be created inside the directory specified by
|
||||||
|
# MAN_OUTPUT.
|
||||||
|
# The default directory is: man.
|
||||||
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
|
MAN_OUTPUT = man
|
||||||
|
|
||||||
|
# The MAN_EXTENSION tag determines the extension that is added to the generated
|
||||||
|
# man pages. In case the manual section does not start with a number, the number
|
||||||
|
# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
|
||||||
|
# optional.
|
||||||
|
# The default value is: .3.
|
||||||
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
|
MAN_EXTENSION = .3
|
||||||
|
|
||||||
|
# The MAN_SUBDIR tag determines the name of the directory created within
|
||||||
|
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
|
||||||
|
# MAN_EXTENSION with the initial . removed.
|
||||||
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
|
MAN_SUBDIR =
|
||||||
|
|
||||||
|
# If the MAN_LINKS tag is set to YES and Doxygen generates man output, then it
|
||||||
|
# will generate one additional man file for each entity documented in the real
|
||||||
|
# man page(s). These additional files only source the real man page, but without
|
||||||
|
# them the man command would be unable to find the correct page.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
|
MAN_LINKS = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the XML output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_XML tag is set to YES, Doxygen will generate an XML file that
|
||||||
|
# captures the structure of the code including all documentation.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
GENERATE_XML = NO
|
||||||
|
|
||||||
|
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
|
||||||
|
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
|
||||||
|
# it.
|
||||||
|
# The default directory is: xml.
|
||||||
|
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||||
|
|
||||||
|
XML_OUTPUT = xml
|
||||||
|
|
||||||
|
# If the XML_PROGRAMLISTING tag is set to YES, Doxygen will dump the program
|
||||||
|
# listings (including syntax highlighting and cross-referencing information) to
|
||||||
|
# the XML output. Note that enabling this will significantly increase the size
|
||||||
|
# of the XML output.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||||
|
|
||||||
|
XML_PROGRAMLISTING = YES
|
||||||
|
|
||||||
|
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, Doxygen will include
|
||||||
|
# namespace members in file scope as well, matching the HTML output.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_XML is set to YES.
|
||||||
|
|
||||||
|
XML_NS_MEMB_FILE_SCOPE = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the DOCBOOK output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_DOCBOOK tag is set to YES, Doxygen will generate Docbook files
|
||||||
|
# that can be used to generate PDF.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
GENERATE_DOCBOOK = NO
|
||||||
|
|
||||||
|
# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
|
||||||
|
# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
|
||||||
|
# front of it.
|
||||||
|
# The default directory is: docbook.
|
||||||
|
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
|
||||||
|
|
||||||
|
DOCBOOK_OUTPUT = docbook
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options for the AutoGen Definitions output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_AUTOGEN_DEF tag is set to YES, Doxygen will generate an
|
||||||
|
# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures
|
||||||
|
# the structure of the code including all documentation. Note that this feature
|
||||||
|
# is still experimental and incomplete at the moment.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to Sqlite3 output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_SQLITE3 tag is set to YES Doxygen will generate a Sqlite3
|
||||||
|
# database with symbols found by Doxygen stored in tables.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
GENERATE_SQLITE3 = NO
|
||||||
|
|
||||||
|
# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be
|
||||||
|
# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put
|
||||||
|
# in front of it.
|
||||||
|
# The default directory is: sqlite3.
|
||||||
|
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
|
||||||
|
|
||||||
|
SQLITE3_OUTPUT = sqlite3
|
||||||
|
|
||||||
|
# The SQLITE3_RECREATE_DB tag is set to YES, the existing doxygen_sqlite3.db
|
||||||
|
# database file will be recreated with each Doxygen run. If set to NO, Doxygen
|
||||||
|
# will warn if a database file is already found and not modify it.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
|
||||||
|
|
||||||
|
SQLITE3_RECREATE_DB = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the Perl module output
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the GENERATE_PERLMOD tag is set to YES, Doxygen will generate a Perl module
|
||||||
|
# file that captures the structure of the code including all documentation.
|
||||||
|
#
|
||||||
|
# Note that this feature is still experimental and incomplete at the moment.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
GENERATE_PERLMOD = NO
|
||||||
|
|
||||||
|
# If the PERLMOD_LATEX tag is set to YES, Doxygen will generate the necessary
|
||||||
|
# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
|
||||||
|
# output from the Perl module output.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
||||||
|
|
||||||
|
PERLMOD_LATEX = NO
|
||||||
|
|
||||||
|
# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
|
||||||
|
# formatted so it can be parsed by a human reader. This is useful if you want to
|
||||||
|
# understand what is going on. On the other hand, if this tag is set to NO, the
|
||||||
|
# size of the Perl module output will be much smaller and Perl will parse it
|
||||||
|
# just the same.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
||||||
|
|
||||||
|
PERLMOD_PRETTY = YES
|
||||||
|
|
||||||
|
# The names of the make variables in the generated doxyrules.make file are
|
||||||
|
# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
|
||||||
|
# so different doxyrules.make files included by the same Makefile don't
|
||||||
|
# overwrite each other's variables.
|
||||||
|
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
|
||||||
|
|
||||||
|
PERLMOD_MAKEVAR_PREFIX =
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to the preprocessor
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If the ENABLE_PREPROCESSING tag is set to YES, Doxygen will evaluate all
|
||||||
|
# C-preprocessor directives found in the sources and include files.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
ENABLE_PREPROCESSING = YES
|
||||||
|
|
||||||
|
# If the MACRO_EXPANSION tag is set to YES, Doxygen will expand all macro names
|
||||||
|
# in the source code. If set to NO, only conditional compilation will be
|
||||||
|
# performed. Macro expansion can be done in a controlled way by setting
|
||||||
|
# EXPAND_ONLY_PREDEF to YES.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
|
MACRO_EXPANSION = YES
|
||||||
|
|
||||||
|
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
|
||||||
|
# the macro expansion is limited to the macros specified with the PREDEFINED and
|
||||||
|
# EXPAND_AS_DEFINED tags.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
|
EXPAND_ONLY_PREDEF = YES
|
||||||
|
|
||||||
|
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
|
||||||
|
# INCLUDE_PATH will be searched if a #include is found.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
|
SEARCH_INCLUDES = YES
|
||||||
|
|
||||||
|
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||||
|
# contain include files that are not input files but should be processed by the
|
||||||
|
# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of
|
||||||
|
# RECURSIVE has no effect here.
|
||||||
|
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
|
||||||
|
|
||||||
|
INCLUDE_PATH = ../Modbus/Inc \
|
||||||
|
../
|
||||||
|
|
||||||
|
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
||||||
|
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
||||||
|
# directories. If left blank, the patterns specified with FILE_PATTERNS will be
|
||||||
|
# used.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
|
||||||
|
# The PREDEFINED tag can be used to specify one or more macro names that are
|
||||||
|
# defined before the preprocessor is started (similar to the -D option of e.g.
|
||||||
|
# gcc). The argument of the tag is a list of macros of the form: name or
|
||||||
|
# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
|
||||||
|
# is assumed. To prevent a macro definition from being undefined via #undef or
|
||||||
|
# recursively expanded use the := operator instead of the = operator.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
|
PREDEFINED =
|
||||||
|
|
||||||
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||||
|
# tag can be used to specify a list of macro names that should be expanded. The
|
||||||
|
# macro definition that is found in the sources will be used. Use the PREDEFINED
|
||||||
|
# tag if you want to use a different macro definition that overrules the
|
||||||
|
# definition found in the source code.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
|
EXPAND_AS_DEFINED =
|
||||||
|
|
||||||
|
# If the SKIP_FUNCTION_MACROS tag is set to YES then Doxygen's preprocessor will
|
||||||
|
# remove all references to function-like macros that are alone on a line, have
|
||||||
|
# an all uppercase name, and do not end with a semicolon. Such function macros
|
||||||
|
# are typically used for boiler-plate code, and will confuse the parser if not
|
||||||
|
# removed.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
|
SKIP_FUNCTION_MACROS = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to external references
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# The TAGFILES tag can be used to specify one or more tag files. For each tag
|
||||||
|
# file the location of the external documentation should be added. The format of
|
||||||
|
# a tag file without this location is as follows:
|
||||||
|
# TAGFILES = file1 file2 ...
|
||||||
|
# Adding location for the tag files is done as follows:
|
||||||
|
# TAGFILES = file1=loc1 "file2 = loc2" ...
|
||||||
|
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
|
||||||
|
# section "Linking to external documentation" for more information about the use
|
||||||
|
# of tag files.
|
||||||
|
# Note: Each tag file must have a unique name (where the name does NOT include
|
||||||
|
# the path). If a tag file is not located in the directory in which Doxygen is
|
||||||
|
# run, you must also specify the path to the tagfile here.
|
||||||
|
|
||||||
|
TAGFILES =
|
||||||
|
|
||||||
|
# When a file name is specified after GENERATE_TAGFILE, Doxygen will create a
|
||||||
|
# tag file that is based on the input files it reads. See section "Linking to
|
||||||
|
# external documentation" for more information about the usage of tag files.
|
||||||
|
|
||||||
|
GENERATE_TAGFILE =
|
||||||
|
|
||||||
|
# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces
|
||||||
|
# will be listed in the class and namespace index. If set to NO, only the
|
||||||
|
# inherited external classes will be listed.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
ALLEXTERNALS = NO
|
||||||
|
|
||||||
|
# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
|
||||||
|
# in the topic index. If set to NO, only the current project's groups will be
|
||||||
|
# listed.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
EXTERNAL_GROUPS = YES
|
||||||
|
|
||||||
|
# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
|
||||||
|
# the related pages index. If set to NO, only the current project's pages will
|
||||||
|
# be listed.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
EXTERNAL_PAGES = YES
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# Configuration options related to diagram generator tools
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# If set to YES the inheritance and collaboration graphs will hide inheritance
|
||||||
|
# and usage relations if the target is undocumented or is not a class.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
HIDE_UNDOC_RELATIONS = YES
|
||||||
|
|
||||||
|
# If you set the HAVE_DOT tag to YES then Doxygen will assume the dot tool is
|
||||||
|
# available from the path. This tool is part of Graphviz (see:
|
||||||
|
# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
|
||||||
|
# Bell Labs. The other options in this section have no effect if this option is
|
||||||
|
# set to NO
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
HAVE_DOT = YES
|
||||||
|
|
||||||
|
# The DOT_NUM_THREADS specifies the number of dot invocations Doxygen is allowed
|
||||||
|
# to run in parallel. When set to 0 Doxygen will base this on the number of
|
||||||
|
# processors available in the system. You can set it explicitly to a value
|
||||||
|
# larger than 0 to get control over the balance between CPU load and processing
|
||||||
|
# speed.
|
||||||
|
# Minimum value: 0, maximum value: 32, default value: 0.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_NUM_THREADS = 0
|
||||||
|
|
||||||
|
# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of
|
||||||
|
# subgraphs. When you want a differently looking font in the dot files that
|
||||||
|
# Doxygen generates you can specify fontname, fontcolor and fontsize attributes.
|
||||||
|
# For details please see <a href=https://graphviz.org/doc/info/attrs.html>Node,
|
||||||
|
# Edge and Graph Attributes specification</a> You need to make sure dot is able
|
||||||
|
# to find the font, which can be done by putting it in a standard location or by
|
||||||
|
# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
|
||||||
|
# directory containing the font. Default graphviz fontsize is 14.
|
||||||
|
# The default value is: fontname=Helvetica,fontsize=10.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
|
||||||
|
|
||||||
|
# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can
|
||||||
|
# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. <a
|
||||||
|
# href=https://graphviz.org/doc/info/arrows.html>Complete documentation about
|
||||||
|
# arrows shapes.</a>
|
||||||
|
# The default value is: labelfontname=Helvetica,labelfontsize=10.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
|
||||||
|
|
||||||
|
# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes
|
||||||
|
# around nodes set 'shape=plain' or 'shape=plaintext' <a
|
||||||
|
# href=https://www.graphviz.org/doc/info/shapes.html>Shapes specification</a>
|
||||||
|
# The default value is: shape=box,height=0.2,width=0.4.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
|
||||||
|
|
||||||
|
# You can set the path where dot can find font specified with fontname in
|
||||||
|
# DOT_COMMON_ATTR and others dot attributes.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_FONTPATH =
|
||||||
|
|
||||||
|
# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then Doxygen will
|
||||||
|
# generate a graph for each documented class showing the direct and indirect
|
||||||
|
# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and
|
||||||
|
# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case
|
||||||
|
# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the
|
||||||
|
# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used.
|
||||||
|
# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance
|
||||||
|
# relations will be shown as texts / links. Explicit enabling an inheritance
|
||||||
|
# graph or choosing a different representation for an inheritance graph of a
|
||||||
|
# specific class, can be accomplished by means of the command \inheritancegraph.
|
||||||
|
# Disabling an inheritance graph can be accomplished by means of the command
|
||||||
|
# \hideinheritancegraph.
|
||||||
|
# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
CLASS_GRAPH = YES
|
||||||
|
|
||||||
|
# If the COLLABORATION_GRAPH tag is set to YES then Doxygen will generate a
|
||||||
|
# graph for each documented class showing the direct and indirect implementation
|
||||||
|
# dependencies (inheritance, containment, and class references variables) of the
|
||||||
|
# class with other documented classes. Explicit enabling a collaboration graph,
|
||||||
|
# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the
|
||||||
|
# command \collaborationgraph. Disabling a collaboration graph can be
|
||||||
|
# accomplished by means of the command \hidecollaborationgraph.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
COLLABORATION_GRAPH = YES
|
||||||
|
|
||||||
|
# If the GROUP_GRAPHS tag is set to YES then Doxygen will generate a graph for
|
||||||
|
# groups, showing the direct groups dependencies. Explicit enabling a group
|
||||||
|
# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means
|
||||||
|
# of the command \groupgraph. Disabling a directory graph can be accomplished by
|
||||||
|
# means of the command \hidegroupgraph. See also the chapter Grouping in the
|
||||||
|
# manual.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
GROUP_GRAPHS = YES
|
||||||
|
|
||||||
|
# If the UML_LOOK tag is set to YES, Doxygen will generate inheritance and
|
||||||
|
# collaboration diagrams in a style similar to the OMG's Unified Modeling
|
||||||
|
# Language.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
UML_LOOK = NO
|
||||||
|
|
||||||
|
# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
|
||||||
|
# class node. If there are many fields or methods and many nodes the graph may
|
||||||
|
# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
|
||||||
|
# number of items for each type to make the size more manageable. Set this to 0
|
||||||
|
# for no limit. Note that the threshold may be exceeded by 50% before the limit
|
||||||
|
# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
|
||||||
|
# but if the number exceeds 15, the total amount of fields shown is limited to
|
||||||
|
# 10.
|
||||||
|
# Minimum value: 0, maximum value: 100, default value: 10.
|
||||||
|
# This tag requires that the tag UML_LOOK is set to YES.
|
||||||
|
|
||||||
|
UML_LIMIT_NUM_FIELDS = 10
|
||||||
|
|
||||||
|
# If the UML_LOOK tag is enabled, field labels are shown along the edge between
|
||||||
|
# two class nodes. If there are many fields and many nodes the graph may become
|
||||||
|
# too cluttered. The UML_MAX_EDGE_LABELS threshold limits the number of items to
|
||||||
|
# make the size more manageable. Set this to 0 for no limit.
|
||||||
|
# Minimum value: 0, maximum value: 100, default value: 10.
|
||||||
|
# This tag requires that the tag UML_LOOK is set to YES.
|
||||||
|
|
||||||
|
UML_MAX_EDGE_LABELS = 10
|
||||||
|
|
||||||
|
# If the DOT_UML_DETAILS tag is set to NO, Doxygen will show attributes and
|
||||||
|
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
|
||||||
|
# tag is set to YES, Doxygen will add type and arguments for attributes and
|
||||||
|
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, Doxygen
|
||||||
|
# will not generate fields with class member information in the UML graphs. The
|
||||||
|
# class diagrams will look similar to the default class diagrams but using UML
|
||||||
|
# notation for the relationships.
|
||||||
|
# Possible values are: NO, YES and NONE.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag UML_LOOK is set to YES.
|
||||||
|
|
||||||
|
DOT_UML_DETAILS = NO
|
||||||
|
|
||||||
|
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
|
||||||
|
# to display on a single line. If the actual line length exceeds this threshold
|
||||||
|
# significantly it will be wrapped across multiple lines. Some heuristics are
|
||||||
|
# applied to avoid ugly line breaks.
|
||||||
|
# Minimum value: 0, maximum value: 1000, default value: 17.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_WRAP_THRESHOLD = 17
|
||||||
|
|
||||||
|
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
|
||||||
|
# collaboration graphs will show the relations between templates and their
|
||||||
|
# instances.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
TEMPLATE_RELATIONS = NO
|
||||||
|
|
||||||
|
# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
|
||||||
|
# YES then Doxygen will generate a graph for each documented file showing the
|
||||||
|
# direct and indirect include dependencies of the file with other documented
|
||||||
|
# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO,
|
||||||
|
# can be accomplished by means of the command \includegraph. Disabling an
|
||||||
|
# include graph can be accomplished by means of the command \hideincludegraph.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
INCLUDE_GRAPH = YES
|
||||||
|
|
||||||
|
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
|
||||||
|
# set to YES then Doxygen will generate a graph for each documented file showing
|
||||||
|
# the direct and indirect include dependencies of the file with other documented
|
||||||
|
# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set
|
||||||
|
# to NO, can be accomplished by means of the command \includedbygraph. Disabling
|
||||||
|
# an included by graph can be accomplished by means of the command
|
||||||
|
# \hideincludedbygraph.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
INCLUDED_BY_GRAPH = YES
|
||||||
|
|
||||||
|
# If the CALL_GRAPH tag is set to YES then Doxygen will generate a call
|
||||||
|
# dependency graph for every global function or class method.
|
||||||
|
#
|
||||||
|
# Note that enabling this option will significantly increase the time of a run.
|
||||||
|
# So in most cases it will be better to enable call graphs for selected
|
||||||
|
# functions only using the \callgraph command. Disabling a call graph can be
|
||||||
|
# accomplished by means of the command \hidecallgraph.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
CALL_GRAPH = NO
|
||||||
|
|
||||||
|
# If the CALLER_GRAPH tag is set to YES then Doxygen will generate a caller
|
||||||
|
# dependency graph for every global function or class method.
|
||||||
|
#
|
||||||
|
# Note that enabling this option will significantly increase the time of a run.
|
||||||
|
# So in most cases it will be better to enable caller graphs for selected
|
||||||
|
# functions only using the \callergraph command. Disabling a caller graph can be
|
||||||
|
# accomplished by means of the command \hidecallergraph.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
CALLER_GRAPH = NO
|
||||||
|
|
||||||
|
# If the GRAPHICAL_HIERARCHY tag is set to YES then Doxygen will graphical
|
||||||
|
# hierarchy of all classes instead of a textual one.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
GRAPHICAL_HIERARCHY = YES
|
||||||
|
|
||||||
|
# If the DIRECTORY_GRAPH tag is set to YES then Doxygen will show the
|
||||||
|
# dependencies a directory has on other directories in a graphical way. The
|
||||||
|
# dependency relations are determined by the #include relations between the
|
||||||
|
# files in the directories. Explicit enabling a directory graph, when
|
||||||
|
# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command
|
||||||
|
# \directorygraph. Disabling a directory graph can be accomplished by means of
|
||||||
|
# the command \hidedirectorygraph.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DIRECTORY_GRAPH = YES
|
||||||
|
|
||||||
|
# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels
|
||||||
|
# of child directories generated in directory dependency graphs by dot.
|
||||||
|
# Minimum value: 1, maximum value: 25, default value: 1.
|
||||||
|
# This tag requires that the tag DIRECTORY_GRAPH is set to YES.
|
||||||
|
|
||||||
|
DIR_GRAPH_MAX_DEPTH = 1
|
||||||
|
|
||||||
|
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
|
||||||
|
# generated by dot. For an explanation of the image formats see the section
|
||||||
|
# output formats in the documentation of the dot tool (Graphviz (see:
|
||||||
|
# https://www.graphviz.org/)).
|
||||||
|
#
|
||||||
|
# Note the formats svg:cairo and svg:cairo:cairo cannot be used in combination
|
||||||
|
# with INTERACTIVE_SVG (the INTERACTIVE_SVG will be set to NO).
|
||||||
|
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
|
||||||
|
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus,
|
||||||
|
# png:gdiplus:gdiplus, svg:cairo, svg:cairo:cairo, svg:svg, svg:svg:core,
|
||||||
|
# gif:cairo, gif:cairo:gd, gif:cairo:gdiplus, gif:gdiplus, gif:gdiplus:gdiplus,
|
||||||
|
# gif:gd, gif:gd:gd, jpg:cairo, jpg:cairo:gd, jpg:cairo:gdiplus, jpg:gd,
|
||||||
|
# jpg:gd:gd, jpg:gdiplus and jpg:gdiplus:gdiplus.
|
||||||
|
# The default value is: png.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_IMAGE_FORMAT = png
|
||||||
|
|
||||||
|
# If DOT_IMAGE_FORMAT is set to svg or svg:svg or svg:svg:core, then this option
|
||||||
|
# can be set to YES to enable generation of interactive SVG images that allow
|
||||||
|
# zooming and panning.
|
||||||
|
#
|
||||||
|
# Note that this requires a modern browser other than Internet Explorer. Tested
|
||||||
|
# and working are Firefox, Chrome, Safari, and Opera.
|
||||||
|
#
|
||||||
|
# Note This option will be automatically disabled when DOT_IMAGE_FORMAT is set
|
||||||
|
# to svg:cairo or svg:cairo:cairo.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
INTERACTIVE_SVG = NO
|
||||||
|
|
||||||
|
# The DOT_PATH tag can be used to specify the path where the dot tool can be
|
||||||
|
# found. If left blank, it is assumed the dot tool can be found in the path.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_PATH =
|
||||||
|
|
||||||
|
# The DOTFILE_DIRS tag can be used to specify one or more directories that
|
||||||
|
# contain dot files that are included in the documentation (see the \dotfile
|
||||||
|
# command).
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOTFILE_DIRS =
|
||||||
|
|
||||||
|
# You can include diagrams made with dia in Doxygen documentation. Doxygen will
|
||||||
|
# then run dia to produce the diagram and insert it in the documentation. The
|
||||||
|
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
|
||||||
|
# If left empty dia is assumed to be found in the default search path.
|
||||||
|
|
||||||
|
DIA_PATH =
|
||||||
|
|
||||||
|
# The DIAFILE_DIRS tag can be used to specify one or more directories that
|
||||||
|
# contain dia files that are included in the documentation (see the \diafile
|
||||||
|
# command).
|
||||||
|
|
||||||
|
DIAFILE_DIRS =
|
||||||
|
|
||||||
|
# When using PlantUML, the PLANTUML_JAR_PATH tag should be used to specify the
|
||||||
|
# path where java can find the plantuml.jar file or to the filename of jar file
|
||||||
|
# to be used. If left blank, it is assumed PlantUML is not used or called during
|
||||||
|
# a preprocessing step. Doxygen will generate a warning when it encounters a
|
||||||
|
# \startuml command in this case and will not generate output for the diagram.
|
||||||
|
|
||||||
|
PLANTUML_JAR_PATH =
|
||||||
|
|
||||||
|
# When using PlantUML, the PLANTUML_CFG_FILE tag can be used to specify a
|
||||||
|
# configuration file for PlantUML.
|
||||||
|
|
||||||
|
PLANTUML_CFG_FILE =
|
||||||
|
|
||||||
|
# When using PlantUML, the specified paths are searched for files specified by
|
||||||
|
# the !include statement in a PlantUML block.
|
||||||
|
|
||||||
|
PLANTUML_INCLUDE_PATH =
|
||||||
|
|
||||||
|
# The PLANTUMLFILE_DIRS tag can be used to specify one or more directories that
|
||||||
|
# contain PlantUml files that are included in the documentation (see the
|
||||||
|
# \plantumlfile command).
|
||||||
|
|
||||||
|
PLANTUMLFILE_DIRS =
|
||||||
|
|
||||||
|
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
|
||||||
|
# that will be shown in the graph. If the number of nodes in a graph becomes
|
||||||
|
# larger than this value, Doxygen will truncate the graph, which is visualized
|
||||||
|
# by representing a node as a red box. Note that if the number of direct
|
||||||
|
# children of the root node in a graph is already larger than
|
||||||
|
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
|
||||||
|
# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
|
||||||
|
# Minimum value: 0, maximum value: 10000, default value: 50.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_GRAPH_MAX_NODES = 50
|
||||||
|
|
||||||
|
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
|
||||||
|
# generated by dot. A depth value of 3 means that only nodes reachable from the
|
||||||
|
# root by following a path via at most 3 edges will be shown. Nodes that lay
|
||||||
|
# further from the root node will be omitted. Note that setting this option to 1
|
||||||
|
# or 2 may greatly reduce the computation time needed for large code bases. Also
|
||||||
|
# note that the size of a graph can be further restricted by
|
||||||
|
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
|
||||||
|
# Minimum value: 0, maximum value: 1000, default value: 0.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
MAX_DOT_GRAPH_DEPTH = 0
|
||||||
|
|
||||||
|
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
|
||||||
|
# files in one run (i.e. multiple -o and -T options on the command line). This
|
||||||
|
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
|
||||||
|
# this, this feature is disabled by default.
|
||||||
|
# The default value is: NO.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
DOT_MULTI_TARGETS = NO
|
||||||
|
|
||||||
|
# If the GENERATE_LEGEND tag is set to YES Doxygen will generate a legend page
|
||||||
|
# explaining the meaning of the various boxes and arrows in the dot generated
|
||||||
|
# graphs.
|
||||||
|
# Note: This tag requires that UML_LOOK isn't set, i.e. the Doxygen internal
|
||||||
|
# graphical representation for inheritance and collaboration diagrams is used.
|
||||||
|
# The default value is: YES.
|
||||||
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
|
GENERATE_LEGEND = YES
|
||||||
|
|
||||||
|
# If the DOT_CLEANUP tag is set to YES, Doxygen will remove the intermediate
|
||||||
|
# files that are used to generate the various graphs.
|
||||||
|
#
|
||||||
|
# Note: This setting is not only used for dot files but also for msc temporary
|
||||||
|
# files.
|
||||||
|
# The default value is: YES.
|
||||||
|
|
||||||
|
DOT_CLEANUP = YES
|
||||||
|
|
||||||
|
# You can define message sequence charts within Doxygen comments using the \msc
|
||||||
|
# command. If the MSCGEN_TOOL tag is left empty (the default), then Doxygen will
|
||||||
|
# use a built-in version of mscgen tool to produce the charts. Alternatively,
|
||||||
|
# the MSCGEN_TOOL tag can also specify the name an external tool. For instance,
|
||||||
|
# specifying prog as the value, Doxygen will call the tool as prog -T
|
||||||
|
# <outfile_format> -o <outputfile> <inputfile>. The external tool should support
|
||||||
|
# output file formats "png", "eps", "svg", and "ismap".
|
||||||
|
|
||||||
|
MSCGEN_TOOL =
|
||||||
|
|
||||||
|
# The MSCFILE_DIRS tag can be used to specify one or more directories that
|
||||||
|
# contain msc files that are included in the documentation (see the \mscfile
|
||||||
|
# command).
|
||||||
|
|
||||||
|
MSCFILE_DIRS =
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
/**
|
|
||||||
**************************************************************************
|
|
||||||
* @file __modbus_compat.h
|
|
||||||
* @brief Модуль для совместимости библиотеки MODBUS.
|
|
||||||
**************************************************************************
|
|
||||||
* @details Файл содержит API старых функций, а также заглушки для отключенных модулей:
|
|
||||||
*************************************************************************/
|
|
||||||
#include "modbus.h"
|
|
||||||
|
|
||||||
|
|
||||||
/** @addtogroup MODBUS_LEGACY_API Legacy API
|
|
||||||
* @ingroup MODBUS_FUNCTIONS
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** MODBUS_LEGACY_API
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @cond Заглушки отключенных модулей */
|
|
||||||
|
|
||||||
#ifndef MODBUS_ENABLE_COILS
|
|
||||||
#define MB_Coil_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
|
||||||
#define MB_Coil_Read_Global(Addr, Exception) 0
|
|
||||||
#define MB_Process_Read_Coils(modbus_msg) 0
|
|
||||||
#define MB_Process_Write_Single_Coil(modbus_msg) 0
|
|
||||||
#define MB_Process_Write_Miltuple_Coils(modbus_msg) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MODBUS_ENABLE_HOLDINGS
|
|
||||||
#define MB_Holding_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
|
||||||
#define MB_Holding_Read_Global(Addr, Exception) 0
|
|
||||||
#define MB_Process_Read_Hold_Regs(modbus_msg) 0
|
|
||||||
#define MB_Process_Write_Single_Reg(modbus_msg) 0
|
|
||||||
#define MB_Process_Write_Miltuple_Regs(modbus_msg) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MODBUS_ENABLE_INPUTS
|
|
||||||
#define MB_Input_Write_Global(Addr, WriteVal) ET_ILLEGAL_FUNCTION
|
|
||||||
#define MB_Input_Read_Global(Addr, Exception) 0
|
|
||||||
#define MB_Process_Read_Input_Regs(modbus_msg) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
|
||||||
#define MB_WriteSingleObjectToMessage(mbdata, ind, obj)
|
|
||||||
#define MB_WriteObjectsToMessage(modbus_msg, maxidofobj)
|
|
||||||
#define MB_Process_Read_Device_Identifications(modbus_msg) 0
|
|
||||||
#define MB_DeviceInentificationInit()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
#define MB_DiagnosticsInit()
|
|
||||||
#define MB_Diagnostics_WriteBit(bit_num, bit_state) 0
|
|
||||||
#define MB_Diagnostics_GetBit(bit_num) 0
|
|
||||||
#define MB_Process_Diagnostics(modbus_msg) 0
|
|
||||||
#define MB_Diagnostics_BusMessageCnt()
|
|
||||||
#define MB_Diagnostics_CommunicationErrorCnt()
|
|
||||||
#define MB_Diagnostics_ExceptionErrorCnt()
|
|
||||||
#define MB_Diagnostics_CharacterOverrunCnt()
|
|
||||||
#define MB_Diagnostics_SlaveMessageCnt()
|
|
||||||
#define MB_Diagnostics_SlaveNoResponseCnt()
|
|
||||||
#define MB_Diagnostics_SlaveNAKCnt()
|
|
||||||
#define MB_Diagnostics_SlaveBusyCnt()
|
|
||||||
#define MB_GetDeviceMode(void) MODBUS_NORMAL_MODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef MODBUS_ENABLE_MASTER
|
|
||||||
#define MB_RespGet_RegisterValue(modbus_msg, reg_addr, reg_value) 0
|
|
||||||
#define MB_RespGet_CoilState(modbus_msg, coil_addr, coil_state) 0
|
|
||||||
#define MB_RespGet_NumberOfObjects(modbus_msg) 0
|
|
||||||
#define MB_RespGet_ObjectById(modbus_msg, obj_id, obj_data, obj_length) 0
|
|
||||||
#define MB_RespGet_ObjectByIndex(modbus_msg, index, obj_id, obj_data, obj_length) 0
|
|
||||||
#define MB_RespGet_Diagnostic(modbus_msg, data) 0
|
|
||||||
#define MB_REQUEST_READ_COILS(slave_addr, start_addr, quantity) {0}
|
|
||||||
#define MB_REQUEST_READ_DISCRETE_INPUTS(slave_addr, start_addr, quantity) {0}
|
|
||||||
#define MB_REQUEST_READ_HOLDING_REGS(slave_addr, start_addr, quantity) {0}
|
|
||||||
#define MB_REQUEST_READ_INPUT_REGS(slave_addr, start_addr, quantity) {0}
|
|
||||||
#define MB_REQUEST_WRITE_SINGLE_COIL(slave_addr, coil_addr, value) {0}
|
|
||||||
#define MB_REQUEST_WRITE_SINGLE_REG(slave_addr, reg_addr, value) {0}
|
|
||||||
#define MB_REQUEST_WRITE_MULTIPLE_COILS(slave_addr, start_addr, quantity, coils_data) {0}
|
|
||||||
#define MB_REQUEST_WRITE_MULTIPLE_REGS(slave_addr, start_addr, quantity, regs_data) {0}
|
|
||||||
#define MB_REQUEST_DIAGNOSTIC_QUERY(slave_addr, sub_function, data) {0}
|
|
||||||
#define MB_REQUEST_RETURN_QUERY_DATA(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RESTART_COMMUNICATIONS(slave_addr, data) {0}
|
|
||||||
#define MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_FORCE_LISTEN_ONLY_MODE(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RETURN_SLAVE_NAK_COUNT(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_READ_DEVICE_ID_BASIC(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_READ_DEVICE_ID_REGULAR(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_READ_DEVICE_ID_EXTENDED(slave_addr) {0}
|
|
||||||
#define MB_REQUEST_READ_DEVICE_ID_SPECIFIC(slave_addr, object_id) {0}
|
|
||||||
#define MB_Master_Collect_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
|
||||||
#define MB_Master_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MODBUS_ENABLE_SLAVE
|
|
||||||
#define MB_Slave_Response(hmodbus, modbus_msg) RS_ERR
|
|
||||||
#define MB_Slave_Collect_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
|
||||||
#define MB_Slave_Parse_Message(hmodbus, modbus_msg, modbus_uart_buff) RS_ERR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @endcond */
|
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "modbus.h"
|
#include "modbus.h"
|
||||||
|
|
||||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
||||||
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
MODBUS_Config(&hmodbus1, 1, 1000, MODBUS_MODE_SLAVE);
|
||||||
MODBUS_SlaveStart(&hmodbus1, NULL);
|
MODBUS_SlaveStart(&hmodbus1, NULL);
|
||||||
@endverbatim
|
@endverbatim
|
||||||
@verbatim
|
@verbatim
|
||||||
@@ -36,25 +36,14 @@
|
|||||||
#include "modbus.h"
|
#include "modbus.h"
|
||||||
|
|
||||||
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
||||||
MODBUS_Config(&hmodbus1, 0, 1000, MODBUS_MODE_MASTER);
|
MODBUS_Config(&hmodbus1, 0, 1000, MODBUS_MODE_MASTER); // - если нужны другие настройки, не из modbus_config.h
|
||||||
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
||||||
RS_MsgTypeDef msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
RS_MsgTypeDef msg = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
||||||
MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func);
|
MODBUS_MasterRequest(&hmodbus1, &msg, &callback_func);
|
||||||
|
|
||||||
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||||||
{
|
{
|
||||||
// MB_RespGet_... Чтобы достать нужные данные из ответа
|
// modbus_msg содержит ответ от устройства
|
||||||
if(hmodbus->RS_STATUS == RS_OK)
|
|
||||||
{
|
|
||||||
for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
|
|
||||||
{
|
|
||||||
uint16_t value;
|
|
||||||
if(MB_RespGet_RegisterValue(&MODBUS_MSG, addr, &value))
|
|
||||||
{
|
|
||||||
read_hold[i] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@endverbatim
|
@endverbatim
|
||||||
|
|
||||||
@@ -84,36 +73,15 @@
|
|||||||
#define __MODBUS_H_
|
#define __MODBUS_H_
|
||||||
|
|
||||||
#include "rs_message.h"
|
#include "rs_message.h"
|
||||||
#ifdef MODBUS_ENABLE_MASTER
|
|
||||||
#include "modbus_master.h"
|
#include "modbus_master.h"
|
||||||
#endif
|
|
||||||
#ifdef MODBUS_ENABLE_SLAVE
|
|
||||||
#include "modbus_slave.h"
|
#include "modbus_slave.h"
|
||||||
#endif
|
|
||||||
#ifdef MODBUS_ENABLE_COILS
|
|
||||||
#include "modbus_coils.h"
|
#include "modbus_coils.h"
|
||||||
#endif
|
|
||||||
#ifdef MODBUS_ENABLE_HOLDINGS
|
|
||||||
#include "modbus_holdregs.h"
|
#include "modbus_holdregs.h"
|
||||||
#endif
|
|
||||||
#ifdef MODBUS_ENABLE_INPUTS
|
|
||||||
#include "modbus_inputregs.h"
|
#include "modbus_inputregs.h"
|
||||||
#endif
|
|
||||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
|
||||||
#include "modbus_devid.h"
|
#include "modbus_devid.h"
|
||||||
#endif
|
|
||||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
#include "modbus_diag.h"
|
#include "modbus_diag.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MODBUS_ENABLE_MASTER
|
|
||||||
#define MODBUS_MODE_MASTER 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODBUS_ENABLE_SLAVE
|
|
||||||
#define MODBUS_MODE_SLAVE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
@@ -131,7 +99,7 @@ HAL_StatusTypeDef MODBUS_SlaveStart(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mo
|
|||||||
HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void (*pClbk)(RS_HandleTypeDef*, RS_MsgTypeDef*));
|
HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, void (*pClbk)(RS_HandleTypeDef*, RS_MsgTypeDef*));
|
||||||
|
|
||||||
|
|
||||||
|
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|
||||||
#endif //__MODBUS_H_
|
#endif //__MODBUS_H_
|
||||||
@@ -139,4 +107,3 @@ HAL_StatusTypeDef MODBUS_MasterRequest(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
|||||||
/** MODBUS_FUNCTIONS
|
/** MODBUS_FUNCTIONS
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -34,11 +34,90 @@ Coils упакованы в 16-битные слова для эффективн
|
|||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup MODBUS_COILS
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил
|
||||||
|
* @param _parr_ - массив коилов.
|
||||||
|
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||||
|
* @note Используется вместе с @ref MB_Set_Coil_Mask
|
||||||
|
@verbatim Пояснение выражений
|
||||||
|
- (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_
|
||||||
|
|
||||||
|
Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0)
|
||||||
|
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|
||||||
|
|register[0]----| |register[1]----|
|
||||||
|
|skip this------| |get this-------|
|
||||||
|
|shift to 14 bit|
|
||||||
|
@endverbatim
|
||||||
|
*/
|
||||||
|
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
|
||||||
|
/**
|
||||||
|
* @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра
|
||||||
|
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||||
|
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
|
||||||
|
@verbatim Пояснение выражений
|
||||||
|
- (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра
|
||||||
|
- _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре
|
||||||
|
|
||||||
|
Визуальный пример: 30 коил будет регистре[1], на 14 бите:
|
||||||
|
register = 30/16 = 1
|
||||||
|
bit = 30 - (16*30/16) = 30 - 16 = 14
|
||||||
|
|
||||||
|
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|
||||||
|
|register[0]----| |register[1]----|
|
||||||
|
|skip this------| |get this-------|
|
||||||
|
|shift to 14 bit|
|
||||||
|
@endverbatim
|
||||||
|
*/
|
||||||
|
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
|
||||||
|
|
||||||
|
/** MODBUS_COILS
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup MODBUS_REQ_COILS_API API for Coils
|
||||||
|
* @ingroup MODBUS_REQUEST_MSG
|
||||||
|
* @brief API для чтения coils из ответа в режиме мастер
|
||||||
|
* @details Примеры использования:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
|
||||||
|
* int coil_state;
|
||||||
|
* if(MB_RespGet_CoilState(&MODBUS_MSG, 25, &coil_state))
|
||||||
|
* {
|
||||||
|
* printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF");
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Пример: Получить состояние всех запрошенных coils
|
||||||
|
* for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
|
||||||
|
* {
|
||||||
|
* int state;
|
||||||
|
* if(MB_RespGet_CoilState(&MODBUS_MSG, addr, &state))
|
||||||
|
* {
|
||||||
|
* printf("Coil %d: %s\n", addr, state ? "ON" : "OFF");
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state);
|
||||||
|
|
||||||
|
/** MODBUS_REQ_COILS_API
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +127,7 @@ Coils упакованы в 16-битные слова для эффективн
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @brief Enum for coils operation */
|
/** @brief Structure for coils operation */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SET_COIL,
|
SET_COIL,
|
||||||
@@ -99,6 +178,7 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
@{
|
||||||
@@ -116,3 +196,7 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);
|
|||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|
||||||
#endif //__MODBUS_COILS_H_
|
#endif //__MODBUS_COILS_H_
|
||||||
|
|
||||||
|
/** MODBUS_COILS
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
@@ -9,11 +9,9 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
Файл содержит настройки для работы Modbus:
|
Файл содержит настройки для работы Modbus:
|
||||||
- Подключение библиотек контроллера
|
- Идентификатор устройства и таймауты
|
||||||
- ID устройства и таймауты
|
|
||||||
- Строковые идентификаторы (Vendor, Product, Revision)
|
- Строковые идентификаторы (Vendor, Product, Revision)
|
||||||
- Настройки периферии (UART, TIMER)
|
- Настройки периферии (UART, TIMER)
|
||||||
- Подключение модулей Modbus
|
|
||||||
- Опциональные функции (переключение команд 0x03/0x04)
|
- Опциональные функции (переключение команд 0x03/0x04)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifndef _MODBUS_CONFIG_H_
|
#ifndef _MODBUS_CONFIG_H_
|
||||||
@@ -32,9 +30,7 @@
|
|||||||
#define MODBUS_PRODUCT_NAME ""
|
#define MODBUS_PRODUCT_NAME ""
|
||||||
#define MODBUS_MODEL_NAME ""
|
#define MODBUS_MODEL_NAME ""
|
||||||
#define MODBUS_USER_APPLICATION_NAME ""
|
#define MODBUS_USER_APPLICATION_NAME ""
|
||||||
|
#define MODBUS_NUMB_OF_USEROBJECTS 0
|
||||||
#define MODBUS_NUMB_OF_USEROBJECTS 0 ///< Количество пользовательских объектов
|
|
||||||
#define MODBUS_USEROBJECT_0_NAME "" ///< Строка пользовательского идентификатора 0. По аналогии можно определить строки до <=128 USEROBJECT
|
|
||||||
|
|
||||||
// Периферия (опционально)
|
// Периферия (опционально)
|
||||||
#define mb_huart huart1 ///< Удобный дефайн для модбасовского uart
|
#define mb_huart huart1 ///< Удобный дефайн для модбасовского uart
|
||||||
@@ -53,7 +49,6 @@
|
|||||||
#define MODBUS_ENABLE_DEVICE_IDENTIFICATIONS ///< Включить обработку идентификаторы устройства
|
#define MODBUS_ENABLE_DEVICE_IDENTIFICATIONS ///< Включить обработку идентификаторы устройства
|
||||||
#define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас
|
#define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас
|
||||||
|
|
||||||
//#define MODBUS_PROTOCOL_TCP ///< Включить TCP-протокол, иначе - RTU
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Поменять комманды 0x03 и 0x04 местами (для LabView терминалки от двигателей)
|
* @brief Поменять комманды 0x03 и 0x04 местами (для LabView терминалки от двигателей)
|
||||||
@@ -40,24 +40,16 @@
|
|||||||
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
||||||
//-------------DEFINES FOR STRUCTURE----------------
|
//-------------DEFINES FOR STRUCTURE----------------
|
||||||
/* defines for structure of modbus message */
|
/* defines for structure of modbus message */
|
||||||
#define TransactionID_size 2 ///< size of (Transaction ID)
|
#define MbAddr_SIZE 1 ///< size of (MbAddr)
|
||||||
#define ProtocolID_size 2 ///< size of (Protocol ID)
|
#define Func_Code_SIZE 1 ///< size of (Func_Code)
|
||||||
#define PDULength_size 2 ///< size of (PDU Length)
|
#define Addr_SIZE 2 ///< size of (Addr)
|
||||||
#define MbAddr_SIZE 1 ///< size of (Slave Addr)
|
#define Qnt_SIZE 2 ///< size of (Qnt)
|
||||||
#define Func_Code_SIZE 1 ///< size of (Function Code)
|
#define ByteCnt_SIZE 1 ///< size of (ByteCnt)
|
||||||
#define Addr_SIZE 2 ///< size of (Address)
|
|
||||||
#define Qnt_SIZE 2 ///< size of (Quantity)
|
|
||||||
#define ByteCnt_SIZE 1 ///< size of (Byte Count)
|
|
||||||
#define DATA_SIZE 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
|
#define DATA_SIZE 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
|
||||||
#define CRC_SIZE 2 ///< size of (MbCRC) in bytes
|
#define CRC_SIZE 2 ///< size of (MB_CRC) in bytes
|
||||||
|
|
||||||
#ifndef MODBUS_PROTOCOL_TCP
|
/** @brief Size of whole message */
|
||||||
/** @brief Size of whole RTU message */
|
|
||||||
#define INFO_SIZE_MAX (MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE+ByteCnt_SIZE)
|
#define INFO_SIZE_MAX (MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE+ByteCnt_SIZE)
|
||||||
#else
|
|
||||||
/** @brief Size of whole TCP message */
|
|
||||||
#define INFO_SIZE_MAX (TransactionID_size+ProtocolID_size+PDULength_size+MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @brief Size of first part of message that will be received
|
/** @brief Size of first part of message that will be received
|
||||||
first receive info part of message, than defines size of rest message*/
|
first receive info part of message, than defines size of rest message*/
|
||||||
@@ -66,104 +58,100 @@ first receive info part of message, than defines size of rest message*/
|
|||||||
/** @brief Size of buffer: max size of whole message */
|
/** @brief Size of buffer: max size of whole message */
|
||||||
#define MSG_SIZE_MAX (INFO_SIZE_MAX + DATA_SIZE*2 + CRC_SIZE) // max possible size of message
|
#define MSG_SIZE_MAX (INFO_SIZE_MAX + DATA_SIZE*2 + CRC_SIZE) // max possible size of message
|
||||||
|
|
||||||
/**
|
/** @brief Structure for modbus exception codes */
|
||||||
* @brief Enum for modbus exception codes
|
|
||||||
* @details Prefix ET for Error Type
|
|
||||||
*/
|
|
||||||
typedef enum //MB_ExceptionTypeDef
|
typedef enum //MB_ExceptionTypeDef
|
||||||
{
|
{
|
||||||
// reading
|
// reading
|
||||||
ET_NO_ERRORS = 0x00, ///< no errors
|
NO_ERRORS = 0x00, ///< no errors
|
||||||
ET_ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
|
ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
|
||||||
ET_ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
|
ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
|
||||||
ET_ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
|
ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
|
||||||
ET_SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
|
SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
|
||||||
// ET_ACKNOWLEDGE = 0x05, ///< idk
|
// ACKNOWLEDGE = 0x05, ///< idk
|
||||||
// ET_SLAVE_DEVICE_BUSY = 0x06, ///< idk
|
// SLAVE_DEVICE_BUSY = 0x06, ///< idk
|
||||||
// ET_MEMORY_PARITY_ERROR = 0x08, ///< idk
|
// MEMORY_PARITY_ERROR = 0x08, ///< idk
|
||||||
}MB_ExceptionTypeDef;
|
}MB_ExceptionTypeDef;
|
||||||
|
|
||||||
#define FC_ERR_VALUES_START 0x80U ///< from this value starts error func codes
|
#define ERR_VALUES_START 0x80U ///< from this value starts error func codes
|
||||||
/**
|
/** @brief Structure for modbus func codes */
|
||||||
* @brief Enum for modbus func codes
|
|
||||||
* @details Prefix FC for Function Code
|
|
||||||
*/
|
|
||||||
typedef enum //MB_FunctonTypeDef
|
typedef enum //MB_FunctonTypeDef
|
||||||
{
|
{
|
||||||
/* COMMANDS */
|
/* COMMANDS */
|
||||||
// reading
|
// reading
|
||||||
FC_R_COILS = 0x01, ///< Чтение битовых ячеек
|
MB_R_COILS = 0x01, ///< Чтение битовых ячеек
|
||||||
//FC_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
||||||
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
||||||
FC_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
||||||
FC_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
||||||
#else
|
#else
|
||||||
FC_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
|
MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
|
||||||
FC_R_IN_REGS = 0x03, ///< Чтение регистров хранения
|
MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// writting
|
// writting
|
||||||
FC_W_COIL = 0x05, ///< Запись битовой ячейки
|
MB_W_COIL = 0x05, ///< Запись битовой ячейки
|
||||||
FC_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
|
MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
|
||||||
FC_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
|
MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
|
||||||
FC_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
|
MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
|
||||||
|
|
||||||
FC_R_DIAGNOSTICS = 0x08, ///< Чтение диагностической информации устройства
|
MB_R_DIAGNOSTIC = 0x08, ///< Чтение диагностической информации устройства
|
||||||
FC_R_DEVICE_ID = 0x2B, ///< Чтение информации об устройстве
|
MB_R_DEVICE_INFO = 0x2B, ///< Чтение информации об устройстве
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
// error reading
|
// error reading
|
||||||
FC_ERR_R_COILS = FC_R_COILS + FC_ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
||||||
//FC_ERR_R_DISC_IN = FC_R_DISC_IN + FC_ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
||||||
FC_ERR_R_IN_REGS = FC_R_IN_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
||||||
FC_ERR_R_HOLD_REGS = FC_R_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
||||||
|
|
||||||
// error writting
|
// error writting
|
||||||
FC_ERR_W_COIL = FC_W_COIL + FC_ERR_VALUES_START, ///< Ошибка записи битовой ячейки
|
MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки
|
||||||
FC_ERR_W_HOLD_REG = FC_W_HOLD_REG + FC_ERR_VALUES_START, ///< Ошибка записи одиночного регистра
|
MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра
|
||||||
FC_ERR_W_COILS = FC_W_COILS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
||||||
FC_ERR_W_HOLD_REGS = FC_W_HOLD_REGS + FC_ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
||||||
|
|
||||||
FC_ERR_R_DIAGNOSTIC = FC_R_DIAGNOSTICS + FC_ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
|
MB_ERR_R_DIAGNOSTIC = MB_R_DIAGNOSTIC + ERR_VALUES_START, ///< Ошибка чтения диагностической информации устройства
|
||||||
MB_FC_ERR_R_DEVICE_INFO = FC_R_DEVICE_ID + FC_ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
MB_ERR_R_DEVICE_INFO = MB_R_DEVICE_INFO + ERR_VALUES_START, ///< Ошибка чтения информации об устройстве
|
||||||
}MB_FunctonTypeDef;
|
}MB_FunctonTypeDef;
|
||||||
|
|
||||||
/** @brief Enum for MEI func codes */
|
/** @brief Structure for MEI func codes */
|
||||||
typedef enum //MB_FunctonTypeDef
|
typedef enum //MB_FunctonTypeDef
|
||||||
{
|
{
|
||||||
MEI_DEVICE_IDENTIFICATIONS = 0x0E,
|
MEI_DEVICE_IDENTIFICATIONS = 0x0E,
|
||||||
}MB_MEITypeDef;
|
}MB_MEITypeDef;
|
||||||
|
|
||||||
/**
|
/** @brief Structure for comformity */
|
||||||
* @brief Enum for Read Device Id codes
|
|
||||||
* @details Prefix RID for Read ID
|
|
||||||
*/
|
|
||||||
typedef enum //MB_FunctonTypeDef
|
typedef enum //MB_FunctonTypeDef
|
||||||
{
|
{
|
||||||
RID_BASIC_IDENTIFICATIONS = 0x01, /*!< @brief Basic Device Identifications.
|
MB_BASIC_IDENTIFICATIONS = 0x01, /*!< @brief Basic Device Identifications.
|
||||||
@details All objects of this category are mandatory:
|
@details All objects of this category are mandatory:
|
||||||
VendorName,Product code, and revision number */
|
VendorName,Product code, and revision number */
|
||||||
|
|
||||||
RID_REGULAR_IDENTIFICATIONS = 0x02, /*!< @brief Regular Device Identifications.
|
MB_REGULAR_IDENTIFICATIONS = 0x02, /*!< @brief Regular Device Identifications.
|
||||||
@details The device provides additional and optional
|
@details The device provides additional and optional
|
||||||
identifications and description data objects */
|
identifications and description data objects */
|
||||||
|
|
||||||
RID_EXTENDED_IDENTIFICATIONS = 0x03, /*!< @brief Extended Device Identifications.
|
MB_EXTENDED_IDENTIFICATIONS = 0x03, /*!< @brief Extended Device Identifications.
|
||||||
@details The device provides additional and optional
|
@details The device provides additional and optional
|
||||||
identifications and description private data about the physical
|
identifications and description private data about the physical
|
||||||
device itself. All of these data are device dependent. */
|
device itself. All of these data are device dependent. */
|
||||||
|
|
||||||
RID_SPEDIFIC_IDENTIFICATIONS = 0x04, /*!< @brief Specific Device Identifications.
|
MB_SPEDIFIC_IDENTIFICATIONS = 0x04, /*!< @brief Specific Device Identifications.
|
||||||
@details The device provides one specific identifications object. */
|
@details The device provides one specific identifications object. */
|
||||||
|
|
||||||
}ReadDevId;
|
/* ERRORS */
|
||||||
|
MB_ERR_BASIC_IDENTIFICATIONS = MB_BASIC_IDENTIFICATIONS + ERR_VALUES_START,
|
||||||
|
MB_ERR_REGULAR_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||||
|
MB_ERR_EXTENDED_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||||
|
MB_ERR_SPEDIFIC_IDENTIFICATIONS = MB_REGULAR_IDENTIFICATIONS + ERR_VALUES_START,
|
||||||
|
}MB_ConformityTypeDef;
|
||||||
|
|
||||||
/** @brief Structure for device identifications message type */
|
/** @brief Structure for decive identifications message type */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identifications Interface
|
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identifications Interface
|
||||||
ReadDevId ReadDevId;
|
MB_ConformityTypeDef ReadDevId;
|
||||||
uint8_t Conformity; ///< Identification conformity level of the device and type of supported access @ref MODBUS_DEVICE_CONFORMITY
|
MB_ConformityTypeDef Conformity;
|
||||||
uint8_t MoreFollows;
|
uint8_t MoreFollows;
|
||||||
uint8_t NextObjId;
|
uint8_t NextObjId;
|
||||||
uint8_t NumbOfObj;
|
uint8_t NumbOfObj;
|
||||||
@@ -173,23 +161,17 @@ typedef struct
|
|||||||
/** @brief Structure for modbus messsage */
|
/** @brief Structure for modbus messsage */
|
||||||
typedef struct // RS_MsgTypeDef
|
typedef struct // RS_MsgTypeDef
|
||||||
{
|
{
|
||||||
#ifdef MODBUS_PROTOCOL_TCP
|
|
||||||
uint16_t TransactionID; ///< Modbus TCP: ID Transaction
|
|
||||||
uint16_t ProtocolID; ///< Modbus TCP: ID Protocol
|
|
||||||
uint16_t PDULength; ///< Modbus TCP: PDU Length
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t MbAddr; ///< Modbus Slave Address
|
uint8_t MbAddr; ///< Modbus Slave Address
|
||||||
MB_FunctonTypeDef FuncCode; ///< Modbus Function Code
|
MB_FunctonTypeDef Func_Code; ///< Modbus Function Code
|
||||||
MB_DevIdMsgTypeDef DevId; ///< Read Device Identifications Header struct
|
MB_DevIdMsgTypeDef DevId; ///< Read Device Identifications Header struct
|
||||||
uint16_t Addr; ///< Modbus Address of data
|
uint16_t Addr; ///< Modbus Address of data
|
||||||
uint16_t Qnt; ///< Quantity of modbus data
|
uint16_t Qnt; ///< Quantity of modbus data
|
||||||
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive
|
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive
|
||||||
|
|
||||||
uint16_t MbData[DATA_SIZE]; ///< Modbus Data
|
uint16_t DATA[DATA_SIZE]; ///< Modbus Data
|
||||||
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
|
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
|
||||||
|
|
||||||
uint16_t MbCRC; ///< Modbus CRC
|
uint16_t MB_CRC; ///< Modbus CRC
|
||||||
}RS_MsgTypeDef;
|
}RS_MsgTypeDef;
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
extern RS_MsgTypeDef MODBUS_MSG;
|
extern RS_MsgTypeDef MODBUS_MSG;
|
||||||
@@ -212,42 +194,6 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
|||||||
*/
|
*/
|
||||||
#define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_))
|
#define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_))
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Макрос для установки указателя на регистр, содержащий запрашиваемый коил
|
|
||||||
* @param _parr_ - массив коилов.
|
|
||||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
|
||||||
* @note Используется вместе с @ref MB_Set_Coil_Mask
|
|
||||||
@verbatim Пояснение выражений
|
|
||||||
- (_coil_/16) - индекс регистра, в котором содержится коил по адресу _coil_
|
|
||||||
|
|
||||||
Визуальный пример: 30 коил будет в 30/16 = 1 регистре (индексация с 0)
|
|
||||||
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|
|
||||||
|register[0]----| |register[1]----|
|
|
||||||
|skip this------| |get this-------|
|
|
||||||
|shift to 14 bit|
|
|
||||||
@endverbatim
|
|
||||||
*/
|
|
||||||
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
|
|
||||||
/**
|
|
||||||
* @brief Макрос для установки маски, чтобы выделить запрашиваемый коил из регистра
|
|
||||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
|
||||||
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
|
|
||||||
@verbatim Пояснение выражений
|
|
||||||
- (16*(_coil_/16) - сколько коилов нужно пропустить. прим. (16*30/16) - первые 16 коилов находятся вне регистра
|
|
||||||
- _coil_-(16*(_coil_/16)) - сдвинуть бит на место запрашиваемого коила в регистре
|
|
||||||
|
|
||||||
Визуальный пример: 30 коил будет регистре[1], на 14 бите:
|
|
||||||
register = 30/16 = 1
|
|
||||||
bit = 30 - (16*30/16) = 30 - 16 = 14
|
|
||||||
|
|
||||||
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|
|
||||||
|register[0]----| |register[1]----|
|
|
||||||
|skip this------| |get this-------|
|
|
||||||
|shift to 14 bit|
|
|
||||||
@endverbatim
|
|
||||||
*/
|
|
||||||
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
|
|
||||||
|
|
||||||
/** GENERAL_MODBUS_STUFF
|
/** GENERAL_MODBUS_STUFF
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
@@ -287,6 +233,7 @@ extern RS_MsgTypeDef MODBUS_MSG;
|
|||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|
||||||
|
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
@{
|
||||||
@@ -303,9 +250,6 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
|
|||||||
/** MODBUS_CMD_PROCESS_FUNCTIONS
|
/** MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
#endif //__MODBUS_CORE_H_
|
#endif //__MODBUS_CORE_H_
|
||||||
/** MODBUS_INTERNAL
|
/** MODBUS_INTERNAL
|
||||||
@@ -36,14 +36,14 @@
|
|||||||
uint16_t user_regs[16];
|
uint16_t user_regs[16];
|
||||||
|
|
||||||
//...
|
//...
|
||||||
else if(MB_Check_Address_For_Arr(Addr, Qnt, R_USER_ADDR, R_USER_QNT) == ET_NO_ERRORS)
|
else if(MB_Check_Address_For_Arr(Addr, Qnt, R_USER_ADDR, R_USER_QNT) == NO_ERRORS)
|
||||||
{
|
{
|
||||||
*pRegs = MB_Set_Register_Ptr(&user_regs, Addr-R_USER_ADDR); // ВАЖНО!
|
*pRegs = MB_Set_Register_Ptr(&user_regs, Addr-R_USER_ADDR); // ВАЖНО!
|
||||||
// -R_USER_ADDR нужен чтобы взять адрес относительно начала массива
|
// -R_USER_ADDR нужен чтобы взять адрес относительно начала массива
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ET_ILLEGAL_DATA_ADDRESS;
|
return ILLEGAL_DATA_ADDRESS;
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@@ -31,12 +31,6 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if MODBUS_NUMB_OF_USEROBJECTS > 0
|
|
||||||
#define MODBUS_DEVICE_CONFORMITY 0x83
|
|
||||||
#else
|
|
||||||
#define MODBUS_DEVICE_CONFORMITY 0x82
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @brief Структура для объекта (идентификатора устройства модбас) */
|
/** @brief Структура для объекта (идентификатора устройства модбас) */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -92,6 +86,52 @@ void MB_DeviceInentificationInit(void);
|
|||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup MODBUS_REQ_DEFID_API API for Device Identifications
|
||||||
|
* @ingroup MODBUS_REQUEST_MSG
|
||||||
|
* @brief API для чтения идентификторов из ответа в режиме мастер
|
||||||
|
* @details Примеры использования:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* // Пример 1: Получить VendorName (ID = 0x00)
|
||||||
|
* uint8_t length;
|
||||||
|
* char vendor_name[64];
|
||||||
|
* if(MB_RespGet_ObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
|
||||||
|
* {
|
||||||
|
* // получено
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Пример 2: Перебрать все объекты в сообщении
|
||||||
|
* uint8_t obj_id, obj_length;
|
||||||
|
* char obj_data[256];
|
||||||
|
*
|
||||||
|
* int obj_count = MB_RespGet_NumberOfObjects(&MODBUS_MSG);
|
||||||
|
* printf("Total objects: %d\n", obj_count);
|
||||||
|
*
|
||||||
|
* for(int i = 0; i < obj_count; i++)
|
||||||
|
* {
|
||||||
|
* if(MB_RespGet_ObjectByIndex(&MODBUS_MSG, i, &obj_id, obj_data, &obj_length))
|
||||||
|
* {
|
||||||
|
* // получено
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Получить количество объектов в сообщении */
|
||||||
|
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg);
|
||||||
|
/* Найти объект по ID в сообщении */
|
||||||
|
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length);
|
||||||
|
/* Получить объект по индексу в сообщении */
|
||||||
|
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length);
|
||||||
|
|
||||||
|
|
||||||
|
/** MODBUS_REQ_DEFID_API
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_DEVID
|
* @addtogroup MODBUS_DEVID
|
||||||
* @{
|
* @{
|
||||||
@@ -105,7 +145,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj);
|
|||||||
/** MODBUS_DEVID
|
/** MODBUS_DEVID
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
@{
|
||||||
@@ -119,4 +159,3 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg);
|
|||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|
||||||
#endif //__MODBUS_DEVID_H_
|
#endif //__MODBUS_DEVID_H_
|
||||||
|
|
||||||
@@ -65,6 +65,29 @@ void MB_DiagnosticsInit(void);
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup MODBUS_REQ_DIAG_API API for Diagnostics
|
||||||
|
* @ingroup MODBUS_REQUEST_MSG
|
||||||
|
* @brief API для чтения диагностической информации из ответа в режиме мастер
|
||||||
|
* @details Примеры использования:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* // Получить данные диагностики (значение счетчика)
|
||||||
|
* uint16_t counter_value;
|
||||||
|
* if(MB_RespGet_Diagnostic(&MODBUS_MSG, &counter_value))
|
||||||
|
* {
|
||||||
|
* printf("Counter value: %d\n", counter_value);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data);
|
||||||
|
|
||||||
|
/** MODBUS_REQ_DIAG_API
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -98,6 +121,7 @@ void MB_Diagnostics_SlaveBusyCnt(void);
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
@{
|
||||||
@@ -120,4 +144,3 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg);
|
|||||||
/** MODBUS_DIAG
|
/** MODBUS_DIAG
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -23,22 +23,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|
||||||
/**
|
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||||
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Записать регистр хранения по глобальному адресу. */
|
|
||||||
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal);
|
|
||||||
/* Считать регистр хранения по глобальному адресу. */
|
|
||||||
uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
|
||||||
|
|
||||||
/** MODBUS_DATA_ACCESS_FUNCTIONS
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||||
@{
|
@{
|
||||||
@@ -21,21 +21,7 @@
|
|||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||||
|
|
||||||
/**
|
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||||
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Записать входной регистр по глобальному адресу. */
|
|
||||||
MB_ExceptionTypeDef MB_Input_Write_Global(uint16_t Addr, uint16_t WriteVal);
|
|
||||||
/* Считать входной регистр по глобальному адресу. */
|
|
||||||
uint16_t MB_Input_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
|
||||||
|
|
||||||
/** MODBUS_DATA_ACCESS_FUNCTIONS
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions
|
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS Internal Process Functions
|
||||||
* @ingroup MODBUS_INTERNAL
|
* @ingroup MODBUS_INTERNAL
|
||||||
@@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
#include "rs_message.h"
|
#include "rs_message.h"
|
||||||
|
|
||||||
|
#ifdef MODBUS_ENABLE_MASTER
|
||||||
|
#define MODBUS_MODE_MASTER 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_REQUEST_MSG API for Master Requests
|
* @addtogroup MODBUS_REQUEST_MSG API for Master Requests
|
||||||
* @ingroup MODBUS_FUNCTIONS
|
* @ingroup MODBUS_FUNCTIONS
|
||||||
@@ -105,115 +109,6 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
|||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup MODBUS_REQ_COILS_API API for Coils
|
|
||||||
* @ingroup MODBUS_REQUEST_MSG
|
|
||||||
* @brief API для чтения coils из ответа в режиме мастер
|
|
||||||
* @details Примеры использования:
|
|
||||||
*
|
|
||||||
* @code
|
|
||||||
* // Пример: Запросили 10 coils с адреса 20, хотим узнать состояние coil 25
|
|
||||||
* int coil_state;
|
|
||||||
* if(MB_RespGet_CoilState(&MODBUS_MSG, 25, &coil_state))
|
|
||||||
* {
|
|
||||||
* printf("Coil 25 state: %s\n", coil_state ? "ON" : "OFF");
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // Пример: Получить состояние всех запрошенных coils
|
|
||||||
* for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
|
|
||||||
* {
|
|
||||||
* int state;
|
|
||||||
* if(MB_RespGet_CoilState(&MODBUS_MSG, addr, &state))
|
|
||||||
* {
|
|
||||||
* printf("Coil %d: %s\n", addr, state ? "ON" : "OFF");
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state);
|
|
||||||
|
|
||||||
/** MODBUS_REQ_COILS_API
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup MODBUS_REQ_DEFID_API API for Device Identifications
|
|
||||||
* @ingroup MODBUS_REQUEST_MSG
|
|
||||||
* @brief API для чтения идентификторов из ответа в режиме мастер
|
|
||||||
* @details Примеры использования:
|
|
||||||
*
|
|
||||||
* @code
|
|
||||||
* // Пример 1: Получить VendorName (ID = 0x00)
|
|
||||||
* uint8_t length;
|
|
||||||
* char vendor_name[64];
|
|
||||||
* if(MB_RespGet_ObjectById(&MODBUS_MSG, 0x00, vendor_name, &length))
|
|
||||||
* {
|
|
||||||
* // получено
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // Пример 2: Перебрать все объекты в сообщении
|
|
||||||
* uint8_t obj_id, obj_length;
|
|
||||||
* char obj_data[256];
|
|
||||||
*
|
|
||||||
* int obj_count = MB_RespGet_NumberOfObjects(&MODBUS_MSG);
|
|
||||||
* printf("Total objects: %d\n", obj_count);
|
|
||||||
*
|
|
||||||
* for(int i = 0; i < obj_count; i++)
|
|
||||||
* {
|
|
||||||
* if(MB_RespGet_ObjectByIndex(&MODBUS_MSG, i, &obj_id, obj_data, &obj_length))
|
|
||||||
* {
|
|
||||||
* // получено
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Получить количество объектов в сообщении */
|
|
||||||
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg);
|
|
||||||
/* Найти объект по ID в сообщении */
|
|
||||||
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length);
|
|
||||||
/* Получить объект по индексу в сообщении */
|
|
||||||
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length);
|
|
||||||
|
|
||||||
|
|
||||||
/** MODBUS_REQ_DEFID_API
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup MODBUS_REQ_DIAG_API API for Diagnostics
|
|
||||||
* @ingroup MODBUS_REQUEST_MSG
|
|
||||||
* @brief API для чтения диагностической информации из ответа в режиме мастер
|
|
||||||
* @details Примеры использования:
|
|
||||||
*
|
|
||||||
* @code
|
|
||||||
* // Получить данные диагностики (значение счетчика)
|
|
||||||
* uint16_t counter_value;
|
|
||||||
* if(MB_RespGet_Diagnostic(&MODBUS_MSG, &counter_value))
|
|
||||||
* {
|
|
||||||
* printf("Counter value: %d\n", counter_value);
|
|
||||||
* }
|
|
||||||
* @endcode
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data);
|
|
||||||
|
|
||||||
/** MODBUS_REQ_DIAG_API
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_MASTER
|
* @addtogroup MODBUS_MASTER
|
||||||
* @{
|
* @{
|
||||||
@@ -15,6 +15,9 @@
|
|||||||
#include "rs_message.h"
|
#include "rs_message.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MODBUS_ENABLE_SLAVE
|
||||||
|
#define MODBUS_MODE_SLAVE 0
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* @addtogroup MODBUS_SLAVE
|
* @addtogroup MODBUS_SLAVE
|
||||||
* @{
|
* @{
|
||||||
@@ -76,73 +76,47 @@
|
|||||||
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
|
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
|
||||||
|
|
||||||
|
|
||||||
#ifndef RS_USER_VARS_NUMB
|
|
||||||
#define RS_USER_VARS_NUMB 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef local_time
|
|
||||||
#define local_time() uwTick
|
|
||||||
#endif
|
|
||||||
/** @endcond */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup RS_DEBUG Tools for debug RS/UART/TIM
|
|
||||||
* @ingroup RS_TOOLS
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RS_USER_VARS_NUMB
|
|
||||||
#define RS_USER_VARS_NUMB 0 ///< Количество переменных в @ref TrackerTypeDef
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Тип структуры для счетчиков-переменных
|
|
||||||
* @param num_user_vars Есть возмоность добавления num_user_vars количества пользовательскиъх переменных
|
|
||||||
*/
|
|
||||||
#define TrackerTypeDef(num_user_vars) void *
|
|
||||||
/** @brief Инкрементировать переменную - успешных событий */
|
|
||||||
#define TrackerCnt_Ok(_cntstruct_)
|
|
||||||
/** @brief Инкрементировать переменную - ошибок */
|
|
||||||
#define TrackerCnt_Err(_cntstruct_)
|
|
||||||
/** @brief Инкрементировать переменную - предупреждений */
|
|
||||||
#define TrackerCnt_Warn(_cntstruct_)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef printf_rs
|
|
||||||
/** @brief Printf обычных событий RS/UART/TIM */
|
|
||||||
#define printf_rs(...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef printf_rs_err
|
#ifndef printf_rs_err
|
||||||
/** @brief Printf ошибок RS/UART/TIM */
|
|
||||||
#define printf_rs_err(...)
|
#define printf_rs_err(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef printf_rs
|
||||||
#ifndef RS_TIM_Handler_ENTER
|
#define printf_rs(...)
|
||||||
/** @brief Действия при заходе в прерывания таймера */
|
|
||||||
#define RS_TIM_Handler_ENTER()
|
|
||||||
#endif
|
|
||||||
#ifndef RS_TIM_Handler_EXIT
|
|
||||||
/** @brief Действия при выходе из прерывания таймера */
|
|
||||||
#define RS_TIM_Handler_EXIT()
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RS_UART_Handler_ENTER
|
#ifndef __MYLIBS_CONFIG_H_
|
||||||
/** @brief Действия при заходе в прерывания UART */
|
// дефайны из mylibs include
|
||||||
#define RS_UART_Handler_ENTER()
|
static int dummy;
|
||||||
|
#define TrackerTypeDef(num_user_vars) void *
|
||||||
|
#define num_of_usercnts(_user_) 0
|
||||||
|
#define assert_tracecnt(_cntstruct_, _uservarnumb_) 0
|
||||||
|
#define if_assert_usertracker(_cntstruct_, _uservarnumb_) if(0)
|
||||||
|
#define tern_assert_usertracker(_cntstruct_, _uservarnumb_) 0
|
||||||
|
#define TrackerGet_Ok(_cntstruct_) dummy
|
||||||
|
#define TrackerGet_Err(_cntstruct_) dummy
|
||||||
|
#define TrackerGet_Warn(_cntstruct_) dummy
|
||||||
|
#define TrackerGet_User(_cntstruct_, _uservarnumb_) dummy
|
||||||
|
#define TrackerCnt_Ok(_cntstruct_)
|
||||||
|
#define TrackerCnt_Err(_cntstruct_)
|
||||||
|
#define TrackerCnt_Warn(_cntstruct_)
|
||||||
|
#define TrackerCnt_User(_cntstruct_, _uservarnumb_)
|
||||||
|
#define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_)
|
||||||
|
#define TrackerClear_All(_cntstruct_)
|
||||||
|
#define TrackerClear_Ok(_cntstruct_)
|
||||||
|
#define TrackerClear_Err(_cntstruct_)
|
||||||
|
#define TrackerClear_Warn(_cntstruct_)
|
||||||
|
#define TrackerClear_User(_cntstruct_)
|
||||||
|
#define TrackerClear_UserAll(_cntstruct_)
|
||||||
|
#else
|
||||||
|
#include "mylibs_include.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef RS_UART_Handler_EXIT
|
|
||||||
/** @brief Действия при выходе из прерывания UART */
|
|
||||||
#define RS_UART_Handler_EXIT()
|
|
||||||
#endif
|
|
||||||
/** RS_TOOLS
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RS_USER_VARS_NUMB
|
||||||
|
#define RS_USER_VARS_NUMB 0
|
||||||
|
#endif
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
|
|
||||||
// направление передачи rs485
|
// направление передачи rs485
|
||||||
#ifndef RS_EnableReceive
|
#ifndef RS_EnableReceive
|
||||||
@@ -167,10 +141,9 @@ typedef enum // RS_StatusTypeDef
|
|||||||
/*0x03*/ RS_ABORTED,
|
/*0x03*/ RS_ABORTED,
|
||||||
/*0x04*/ RS_BUSY,
|
/*0x04*/ RS_BUSY,
|
||||||
/*0x05*/ RS_SKIP,
|
/*0x05*/ RS_SKIP,
|
||||||
/*0x06*/ RS_TIMEOUT,
|
|
||||||
|
|
||||||
/*0x07*/ RS_COLLECT_MSG_ERR,
|
/*0x06*/ RS_COLLECT_MSG_ERR,
|
||||||
/*0x08*/ RS_PARSE_MSG_ERR,
|
/*0x07*/ RS_PARSE_MSG_ERR,
|
||||||
|
|
||||||
// reserved values
|
// reserved values
|
||||||
// /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero)
|
// /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero)
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
* @brief Выставить/сбросить коил по глобальному адресу.
|
* @brief Выставить/сбросить коил по глобальному адресу.
|
||||||
* @param Addr Адрес коила.
|
* @param Addr Адрес коила.
|
||||||
* @param WriteVal Что записать в коил: 0 или 1.
|
* @param WriteVal Что записать в коил: 0 или 1.
|
||||||
* @return ExceptionCode Код исключения если коила по адресу не существует, и ET_NO_ERRORS если все ок.
|
* @return ExceptionCode Код исключения если коила по адресу не существует, и NO_ERRORS если все ок.
|
||||||
*
|
*
|
||||||
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
||||||
Вне зависимости от того как коилы размещены в памяти.
|
Вне зависимости от того как коилы размещены в памяти.
|
||||||
@@ -26,13 +26,13 @@
|
|||||||
MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
|
MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
|
||||||
{
|
{
|
||||||
//---------CHECK FOR ERRORS----------
|
//---------CHECK FOR ERRORS----------
|
||||||
MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
|
MB_ExceptionTypeDef Exception = NO_ERRORS;
|
||||||
uint16_t *coils;
|
uint16_t *coils;
|
||||||
uint16_t start_shift = 0; // shift in coils register
|
uint16_t start_shift = 0; // shift in coils register
|
||||||
|
|
||||||
//------------WRITE COIL-------------
|
//------------WRITE COIL-------------
|
||||||
Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 1);
|
Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 1);
|
||||||
if(Exception == ET_NO_ERRORS)
|
if(Exception == NO_ERRORS)
|
||||||
{
|
{
|
||||||
switch(WriteVal)
|
switch(WriteVal)
|
||||||
{
|
{
|
||||||
@@ -57,7 +57,7 @@ MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteV
|
|||||||
/**
|
/**
|
||||||
* @brief Считать коил по глобальному адресу.
|
* @brief Считать коил по глобальному адресу.
|
||||||
* @param Addr Адрес коила.
|
* @param Addr Адрес коила.
|
||||||
* @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении.
|
* @param Exception Указатель на переменную для кода исключения, в случа неудачи при чтении.
|
||||||
* @return uint16_t Возвращает весь регистр с маской на запрошенном коиле.
|
* @return uint16_t Возвращает весь регистр с маской на запрошенном коиле.
|
||||||
*
|
*
|
||||||
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
||||||
@@ -75,7 +75,7 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
|||||||
|
|
||||||
//------------READ COIL--------------
|
//------------READ COIL--------------
|
||||||
*Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 0);
|
*Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 0);
|
||||||
if(*Exception == ET_NO_ERRORS)
|
if(*Exception == NO_ERRORS)
|
||||||
{
|
{
|
||||||
return ((*coils)&(1<<start_shift));
|
return ((*coils)&(1<<start_shift));
|
||||||
}
|
}
|
||||||
@@ -86,6 +86,51 @@ uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Получить состояние coil в ответе по его адресу
|
||||||
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
|
* @param coil_addr Адрес coil, состояние которого нужно получить
|
||||||
|
* @param coil_state Указатель для состояния coil (1 - ON, 0 - OFF)
|
||||||
|
* @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса
|
||||||
|
*/
|
||||||
|
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state)
|
||||||
|
{
|
||||||
|
if(modbus_msg == NULL || coil_state == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Проверяем что ответ связан с коилами
|
||||||
|
if(modbus_msg->Func_Code != MB_R_COILS)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем что coil_addr в пределах запрошенного диапазона
|
||||||
|
if(coil_addr < modbus_msg->Addr || coil_addr >= modbus_msg->Addr + modbus_msg->Qnt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Вычисляем индекс coil в полученных данных
|
||||||
|
uint16_t coil_index = coil_addr - modbus_msg->Addr;
|
||||||
|
|
||||||
|
// Вычисляем байт и бит
|
||||||
|
uint8_t byte_index = coil_index / 8;
|
||||||
|
uint8_t data_index = coil_index / 16;
|
||||||
|
uint8_t bit_index = coil_index % 16;
|
||||||
|
|
||||||
|
// Проверяем что байт существует в данных
|
||||||
|
if(byte_index >= modbus_msg->ByteCnt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Получаем байт и проверяем бит
|
||||||
|
if(bit_index < 8)
|
||||||
|
*coil_state = (modbus_msg->DATA[data_index] >> (bit_index+8)) & 0x01;
|
||||||
|
else
|
||||||
|
*coil_state = (modbus_msg->DATA[data_index] >> bit_index) & 0x01;
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Обработать функцию Read Coils (01 - 0x01).
|
* @brief Обработать функцию Read Coils (01 - 0x01).
|
||||||
* @param modbus_msg Указатель на структуру собщения modbus.
|
* @param modbus_msg Указатель на структуру собщения modbus.
|
||||||
@@ -99,7 +144,7 @@ uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg)
|
|||||||
uint16_t start_shift = 0; // shift in coils register
|
uint16_t start_shift = 0; // shift in coils register
|
||||||
|
|
||||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 0);
|
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 0);
|
||||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//-----------READING COIL------------
|
//-----------READING COIL------------
|
||||||
@@ -127,14 +172,14 @@ uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg)
|
|||||||
shift = 0; // set shift to zero for the next step
|
shift = 0; // set shift to zero for the next step
|
||||||
|
|
||||||
//-----------READ COILS--------------
|
//-----------READ COILS--------------
|
||||||
modbus_msg->MbData[ind] = (*(coils+ind)&mask_for_coils) >> start_shift;
|
modbus_msg->DATA[ind] = (*(coils+ind)&mask_for_coils) >> start_shift;
|
||||||
if(ind > 0)
|
if(ind > 0)
|
||||||
modbus_msg->MbData[ind-1] |= ((*(coils+ind)&mask_for_coils) << 16) >> start_shift;
|
modbus_msg->DATA[ind-1] |= ((*(coils+ind)&mask_for_coils) << 16) >> start_shift;
|
||||||
|
|
||||||
}
|
}
|
||||||
// т.к. MbData 16-битная, для 8-битной передачи, надо поменять местами верхний и нижний байты
|
// т.к. DATA 16-битная, для 8-битной передачи, надо поменять местами верхний и нижний байты
|
||||||
for(; ind >= 0; --ind)
|
for(; ind >= 0; --ind)
|
||||||
modbus_msg->MbData[ind] = ByteSwap16(modbus_msg->MbData[ind]);
|
modbus_msg->DATA[ind] = ByteSwap16(modbus_msg->DATA[ind]);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -150,14 +195,14 @@ uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
|
|||||||
//---------CHECK FOR ERRORS----------
|
//---------CHECK FOR ERRORS----------
|
||||||
if ((modbus_msg->Qnt != 0x0000) && (modbus_msg->Qnt != 0xFF00))
|
if ((modbus_msg->Qnt != 0x0000) && (modbus_msg->Qnt != 0xFF00))
|
||||||
{
|
{
|
||||||
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
|
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// define position of coil
|
// define position of coil
|
||||||
uint16_t *coils;
|
uint16_t *coils;
|
||||||
uint16_t start_shift = 0; // shift in coils register
|
uint16_t start_shift = 0; // shift in coils register
|
||||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, 0, &start_shift, 1);
|
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, 0, &start_shift, 1);
|
||||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -181,14 +226,14 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
|||||||
//---------CHECK FOR ERRORS----------
|
//---------CHECK FOR ERRORS----------
|
||||||
if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8))
|
if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8))
|
||||||
{ // if quantity too large OR if quantity and bytes count arent match
|
{ // if quantity too large OR if quantity and bytes count arent match
|
||||||
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
|
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// define position of coil
|
// define position of coil
|
||||||
uint16_t *coils; // pointer to coils
|
uint16_t *coils; // pointer to coils
|
||||||
uint16_t start_shift = 0; // shift in coils register
|
uint16_t start_shift = 0; // shift in coils register
|
||||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 1);
|
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 1);
|
||||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//----------WRITTING COILS-----------
|
//----------WRITTING COILS-----------
|
||||||
@@ -218,10 +263,10 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
|||||||
// get current coils
|
// get current coils
|
||||||
temp_reg = *(coils+ind);
|
temp_reg = *(coils+ind);
|
||||||
// set coils
|
// set coils
|
||||||
setted_coils = ByteSwap16(modbus_msg->MbData[ind]) << start_shift;
|
setted_coils = ByteSwap16(modbus_msg->DATA[ind]) << start_shift;
|
||||||
if(ind > 0)
|
if(ind > 0)
|
||||||
{
|
{
|
||||||
setted_coils |= ((ByteSwap16(modbus_msg->MbData[ind-1]) << start_shift) >> 16);
|
setted_coils |= ((ByteSwap16(modbus_msg->DATA[ind-1]) << start_shift) >> 16);
|
||||||
}
|
}
|
||||||
// write coils
|
// write coils
|
||||||
|
|
||||||
@@ -236,5 +281,14 @@ uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#else //MODBUS_ENABLE_COILS
|
||||||
|
|
||||||
#endif //MODBUS_ENABLE_COILS
|
|
||||||
|
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state) {return 0;}
|
||||||
|
MB_ExceptionTypeDef MB_Coil_Write_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal) {return ILLEGAL_FUNCTION;}
|
||||||
|
uint16_t MB_Coil_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception) {return 0;}
|
||||||
|
uint8_t MB_Process_Read_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
uint8_t MB_Process_Write_Single_Coil(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
uint8_t MB_Process_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @file modbus_core.c
|
* @file modbus_core.c
|
||||||
* @brief Базовая реализация ядра Modbus
|
* @brief Базовая реализация ядра Modbus (заглушка)
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* @details
|
* @details
|
||||||
В текущей реализации этот файл служит заглушкой для будущего расширения
|
В текущей реализации этот файл служит заглушкой для будущего расширения
|
||||||
@@ -29,11 +29,11 @@
|
|||||||
* @param Qnt Количество запрашиваемых элементов.
|
* @param Qnt Количество запрашиваемых элементов.
|
||||||
* @param R_ARR_ADDR Начальный адресс массива R_ARR.
|
* @param R_ARR_ADDR Начальный адресс массива R_ARR.
|
||||||
* @param R_ARR_NUMB Количество элементов в массиве R_ARR.
|
* @param R_ARR_NUMB Количество элементов в массиве R_ARR.
|
||||||
* @return ExceptionCode - ET_ILLEGAL_DATA_ADRESS если адресс недействителен, и ET_NO_ERRORS если все ок.
|
* @return ExceptionCode - ILLEGAL DATA ADRESS если адресс недействителен, и NO_ERRORS если все ок.
|
||||||
*
|
*
|
||||||
* @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
|
* @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
|
||||||
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR.
|
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR.
|
||||||
* Если адресс Addr находится за пределами адрессов массива R_ARR - ET_ILLEGAL_DATA_ADDRESSю.
|
* Если адресс Addr находится за пределами адрессов массива R_ARR - ILLEGAL_DATA_ADDRESSю.
|
||||||
*/
|
*/
|
||||||
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
|
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
|
||||||
{
|
{
|
||||||
@@ -43,14 +43,14 @@ MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16
|
|||||||
// if quantity too big return error
|
// if quantity too big return error
|
||||||
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
|
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
|
||||||
{
|
{
|
||||||
return ET_ILLEGAL_DATA_ADDRESS; // return exception code
|
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||||
}
|
}
|
||||||
// if all ok - return no errors
|
// if all ok - return no errors
|
||||||
return ET_NO_ERRORS;
|
return NO_ERRORS;
|
||||||
}
|
}
|
||||||
// if address isnt from this array return error
|
// if address isnt from this array return error
|
||||||
else
|
else
|
||||||
return ET_ILLEGAL_DATA_ADDRESS; // return exception code
|
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Define Address Origin for Input/Holding Registers
|
* @brief Define Address Origin for Input/Holding Registers
|
||||||
@@ -58,7 +58,7 @@ MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16
|
|||||||
* @param Addr Адрес начального регистра.
|
* @param Addr Адрес начального регистра.
|
||||||
* @param Qnt Количество запрашиваемых регистров.
|
* @param Qnt Количество запрашиваемых регистров.
|
||||||
* @param WriteFlag Флаг регистр нужны для чтения или записи.
|
* @param WriteFlag Флаг регистр нужны для чтения или записи.
|
||||||
* @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
|
* @return ExceptionCode Код исключения если есть, и NO_ERRORS если нет.
|
||||||
*
|
*
|
||||||
* @details Определение адреса начального регистра.
|
* @details Определение адреса начального регистра.
|
||||||
* @note WriteFlag пока не используется.
|
* @note WriteFlag пока не используется.
|
||||||
@@ -68,41 +68,41 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
|
|||||||
/* check quantity error */
|
/* check quantity error */
|
||||||
if (Qnt > DATA_SIZE)
|
if (Qnt > DATA_SIZE)
|
||||||
{
|
{
|
||||||
return ET_ILLEGAL_DATA_VALUE; // return exception code
|
return ILLEGAL_DATA_VALUE; // return exception code
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RegisterType == RegisterType_Holding)
|
if(RegisterType == RegisterType_Holding)
|
||||||
{
|
{
|
||||||
// Default holding registers
|
// Default holding registers
|
||||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_HOLDING_ADDR, R_HOLDING_QNT) == ET_NO_ERRORS)
|
if(MB_Check_Address_For_Arr(Addr, Qnt, R_HOLDING_ADDR, R_HOLDING_QNT) == NO_ERRORS)
|
||||||
{
|
{
|
||||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr - R_HOLDING_ADDR); // указатель на выбранный по Addr регистр
|
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr - R_HOLDING_ADDR); // указатель на выбранный по Addr регистр
|
||||||
}
|
}
|
||||||
// if address doesnt match any array - return illegal data address response
|
// if address doesnt match any array - return illegal data address response
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ET_ILLEGAL_DATA_ADDRESS;
|
return ILLEGAL_DATA_ADDRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(RegisterType == RegisterType_Input)
|
else if(RegisterType == RegisterType_Input)
|
||||||
{
|
{
|
||||||
// Default input registers
|
// Default input registers
|
||||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_INPUT_ADDR, R_INPUT_QNT) == ET_NO_ERRORS)
|
if(MB_Check_Address_For_Arr(Addr, Qnt, R_INPUT_ADDR, R_INPUT_QNT) == NO_ERRORS)
|
||||||
{
|
{
|
||||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr - R_INPUT_ADDR); // указатель на выбранный по Addr регистр
|
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr - R_INPUT_ADDR); // указатель на выбранный по Addr регистр
|
||||||
}
|
}
|
||||||
// if address doesnt match any array - return illegal data address response
|
// if address doesnt match any array - return illegal data address response
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ET_ILLEGAL_DATA_ADDRESS;
|
return ILLEGAL_DATA_ADDRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ET_ILLEGAL_FUNCTION;
|
return ILLEGAL_FUNCTION;
|
||||||
}
|
}
|
||||||
// if found requeried array return no err
|
// if found requeried array return no err
|
||||||
return ET_NO_ERRORS; // return no errors
|
return NO_ERRORS; // return no errors
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Define Address Origin for coils
|
* @brief Define Address Origin for coils
|
||||||
@@ -111,7 +111,7 @@ MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, u
|
|||||||
* @param Qnt Количество запрашиваемых коилов.
|
* @param Qnt Количество запрашиваемых коилов.
|
||||||
* @param start_shift Указатель на переменную содержащую сдвиг внутри регистра для начального коила.
|
* @param start_shift Указатель на переменную содержащую сдвиг внутри регистра для начального коила.
|
||||||
* @param WriteFlag Флаг коилы нужны для чтения или записи.
|
* @param WriteFlag Флаг коилы нужны для чтения или записи.
|
||||||
* @return ExceptionCode Код исключения если есть, и ET_NO_ERRORS если нет.
|
* @return ExceptionCode Код исключения если есть, и NO_ERRORS если нет.
|
||||||
*
|
*
|
||||||
* @details Определение адреса начального регистра запрашиваемых коилов.
|
* @details Определение адреса начального регистра запрашиваемых коилов.
|
||||||
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
|
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
|
||||||
@@ -121,21 +121,21 @@ MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint
|
|||||||
/* check quantity error */
|
/* check quantity error */
|
||||||
if (Qnt > 2000)
|
if (Qnt > 2000)
|
||||||
{
|
{
|
||||||
return ET_ILLEGAL_DATA_VALUE; // return exception code
|
return ILLEGAL_DATA_VALUE; // return exception code
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default coils
|
// Default coils
|
||||||
if(MB_Check_Address_For_Arr(Addr, Qnt, C_COILS_ADDR, C_COILS_QNT) == ET_NO_ERRORS)
|
if(MB_Check_Address_For_Arr(Addr, Qnt, C_COILS_ADDR, C_COILS_QNT) == NO_ERRORS)
|
||||||
{
|
{
|
||||||
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr - C_COILS_ADDR); // указатель на выбранный по Addr массив коилов
|
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr - C_COILS_ADDR); // указатель на выбранный по Addr массив коилов
|
||||||
}
|
}
|
||||||
// if address doesnt match any array - return illegal data address response
|
// if address doesnt match any array - return illegal data address response
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ET_ILLEGAL_DATA_ADDRESS;
|
return ILLEGAL_DATA_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
*start_shift = Addr % 16; // set shift to requested coil
|
*start_shift = Addr % 16; // set shift to requested coil
|
||||||
// if found requeried array return no err
|
// if found requeried array return no err
|
||||||
return ET_NO_ERRORS; // return no errors
|
return NO_ERRORS; // return no errors
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,132 @@
|
|||||||
MB_DeviceIdentificationsTypeDef MB_DEVID; ///< Глобальная структура идентификаторов устройства
|
MB_DeviceIdentificationsTypeDef MB_DEVID; ///< Глобальная структура идентификаторов устройства
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Получить количество объектов в сообщении
|
||||||
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
|
* @return int Количество объектов
|
||||||
|
*/
|
||||||
|
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg)
|
||||||
|
{
|
||||||
|
if(modbus_msg == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// Проверяем что ответ связан с диагностикой
|
||||||
|
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modbus_msg->DevId.NumbOfObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Найти объект по ID в сообщении
|
||||||
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
|
* @param obj_id ID искомого объекта
|
||||||
|
* @param obj_data Буфер для данных объекта (может быть NULL)
|
||||||
|
* @param obj_length Указатель для длины объекта
|
||||||
|
* @return int Найден ли объект (1 - да, 0 - нет)
|
||||||
|
*/
|
||||||
|
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length)
|
||||||
|
{
|
||||||
|
if((modbus_msg == NULL) || (obj_data == NULL))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Проверяем что ответ связан с диагностикой
|
||||||
|
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *data = (uint8_t*)modbus_msg->DATA;
|
||||||
|
unsigned ind = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < modbus_msg->DevId.NumbOfObj; i++)
|
||||||
|
{
|
||||||
|
uint8_t current_id = data[ind++];
|
||||||
|
uint8_t current_length = data[ind++];
|
||||||
|
|
||||||
|
if(current_id == obj_id)
|
||||||
|
{
|
||||||
|
if(obj_length)
|
||||||
|
*obj_length = current_length;
|
||||||
|
|
||||||
|
for(int j = 0; j < current_length; j++)
|
||||||
|
{
|
||||||
|
obj_data[j] = data[ind++];
|
||||||
|
}
|
||||||
|
obj_data[current_length] = '\0'; // добавляем \0
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Пропускаем данные этого объекта
|
||||||
|
ind += current_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Получить объект по индексу в сообщении
|
||||||
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
|
* @param index Индекс объекта (0..N-1)
|
||||||
|
* @param obj_id Указатель для ID объекта
|
||||||
|
* @param obj_data Буфер для данных объекта
|
||||||
|
* @param obj_length Указатель для длины объекта
|
||||||
|
* @return int Успешность получения (1 - получен, 0 - не найден)
|
||||||
|
*/
|
||||||
|
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length)
|
||||||
|
{
|
||||||
|
if((modbus_msg == NULL) || (obj_data == NULL))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Проверяем что ответ связан с диагностикой
|
||||||
|
if(modbus_msg->Func_Code != MB_R_DEVICE_INFO)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index >= modbus_msg->DevId.NumbOfObj)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint8_t *data = (uint8_t*)modbus_msg->DATA;
|
||||||
|
unsigned ind = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i <= index; i++)
|
||||||
|
{
|
||||||
|
uint8_t current_id = data[ind++];
|
||||||
|
uint8_t current_length = data[ind++];
|
||||||
|
|
||||||
|
if(obj_id)
|
||||||
|
*obj_id = current_id;
|
||||||
|
if(obj_length)
|
||||||
|
*obj_length = current_length;
|
||||||
|
|
||||||
|
if(i == index)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < current_length; j++)
|
||||||
|
{
|
||||||
|
obj_data[j] = data[ind++];
|
||||||
|
}
|
||||||
|
obj_data[current_length] = '\0'; // добавляем \0
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Пропускаем данные этого объекта
|
||||||
|
ind += current_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,16 +173,11 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
|||||||
{
|
{
|
||||||
MB_DeviceObjectTypeDef *obj = (MB_DeviceObjectTypeDef *)&MB_DEVID;
|
MB_DeviceObjectTypeDef *obj = (MB_DeviceObjectTypeDef *)&MB_DEVID;
|
||||||
unsigned objidtmp = modbus_msg->DevId.NextObjId;
|
unsigned objidtmp = modbus_msg->DevId.NextObjId;
|
||||||
modbus_msg->Except_Code = ET_NO_ERRORS;
|
|
||||||
|
|
||||||
/* Define number of object in one message */
|
/* Define number of object in one message */
|
||||||
unsigned lastobjid = 0;
|
unsigned lastobjid = 0;
|
||||||
for(int i = 0; i < DATA_SIZE*2;)
|
for(int i = 0; i < DATA_SIZE*2;)
|
||||||
{
|
{
|
||||||
/* Если объект за пределами допутимого - выходим из цикла */
|
|
||||||
if(objidtmp >= 0xFF + MODBUS_NUMB_OF_USEROBJECTS)
|
|
||||||
break;
|
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
i += obj[objidtmp].length;
|
i += obj[objidtmp].length;
|
||||||
/* Если все еще помещается в массив переходим на следующий объект */
|
/* Если все еще помещается в массив переходим на следующий объект */
|
||||||
@@ -64,7 +185,6 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
|||||||
{
|
{
|
||||||
objidtmp++;
|
objidtmp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Если объекты для записи закончились - выходим из цикла*/
|
/* Если объекты для записи закончились - выходим из цикла*/
|
||||||
if(objidtmp > maxidofobj)
|
if(objidtmp > maxidofobj)
|
||||||
break;
|
break;
|
||||||
@@ -73,7 +193,7 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
|||||||
|
|
||||||
|
|
||||||
/* Fill message with objects data */
|
/* Fill message with objects data */
|
||||||
char *mbdata = (char *)&modbus_msg->MbData;
|
char *mbdata = (char *)&modbus_msg->DATA;
|
||||||
unsigned ind = 0;
|
unsigned ind = 0;
|
||||||
unsigned objid = modbus_msg->DevId.NextObjId;
|
unsigned objid = modbus_msg->DevId.NextObjId;
|
||||||
for(; objid <= lastobjid; objid++)
|
for(; objid <= lastobjid; objid++)
|
||||||
@@ -82,9 +202,6 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
|||||||
MB_WriteSingleObjectToMessage(mbdata, &ind, &obj[objid]);
|
MB_WriteSingleObjectToMessage(mbdata, &ind, &obj[objid]);
|
||||||
}
|
}
|
||||||
objid--;
|
objid--;
|
||||||
|
|
||||||
if(modbus_msg->ByteCnt != 0)
|
|
||||||
{
|
|
||||||
modbus_msg->ByteCnt = ind;
|
modbus_msg->ByteCnt = ind;
|
||||||
modbus_msg->DevId.NextObjId = lastobjid+1;
|
modbus_msg->DevId.NextObjId = lastobjid+1;
|
||||||
if(objid == maxidofobj)
|
if(objid == maxidofobj)
|
||||||
@@ -96,11 +213,6 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
|||||||
modbus_msg->DevId.MoreFollows = 0xFF;
|
modbus_msg->DevId.MoreFollows = 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,11 +223,9 @@ void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj)
|
|||||||
*/
|
*/
|
||||||
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
||||||
{
|
{
|
||||||
modbus_msg->DevId.Conformity = MODBUS_DEVICE_CONFORMITY;
|
|
||||||
|
|
||||||
switch(modbus_msg->DevId.ReadDevId)
|
switch(modbus_msg->DevId.ReadDevId)
|
||||||
{
|
{
|
||||||
case RID_BASIC_IDENTIFICATIONS:
|
case MB_BASIC_IDENTIFICATIONS:
|
||||||
if (modbus_msg->DevId.NextObjId == 0)
|
if (modbus_msg->DevId.NextObjId == 0)
|
||||||
{
|
{
|
||||||
modbus_msg->DevId.NextObjId = 0;
|
modbus_msg->DevId.NextObjId = 0;
|
||||||
@@ -125,7 +235,7 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
|||||||
modbus_msg->DevId.NumbOfObj = 3;
|
modbus_msg->DevId.NumbOfObj = 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RID_REGULAR_IDENTIFICATIONS:
|
case MB_REGULAR_IDENTIFICATIONS:
|
||||||
if (modbus_msg->DevId.NextObjId == 0)
|
if (modbus_msg->DevId.NextObjId == 0)
|
||||||
{
|
{
|
||||||
modbus_msg->DevId.NextObjId = 3;
|
modbus_msg->DevId.NextObjId = 3;
|
||||||
@@ -135,11 +245,10 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
|||||||
modbus_msg->DevId.NumbOfObj = 4;
|
modbus_msg->DevId.NumbOfObj = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RID_EXTENDED_IDENTIFICATIONS:
|
case MB_EXTENDED_IDENTIFICATIONS:
|
||||||
if(MODBUS_NUMB_OF_USEROBJECTS <= 0 || MODBUS_NUMB_OF_USEROBJECTS > 128)
|
if(MODBUS_NUMB_OF_USEROBJECTS <= 0 || MODBUS_NUMB_OF_USEROBJECTS > 128)
|
||||||
{
|
{
|
||||||
modbus_msg->Except_Code = ET_ILLEGAL_DATA_VALUE;
|
return 0;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modbus_msg->DevId.NextObjId == 0)
|
if (modbus_msg->DevId.NextObjId == 0)
|
||||||
@@ -151,23 +260,15 @@ uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg)
|
|||||||
modbus_msg->DevId.NumbOfObj = MODBUS_NUMB_OF_USEROBJECTS;
|
modbus_msg->DevId.NumbOfObj = MODBUS_NUMB_OF_USEROBJECTS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RID_SPEDIFIC_IDENTIFICATIONS:
|
case MB_SPEDIFIC_IDENTIFICATIONS:
|
||||||
MB_WriteObjectsToMessage(modbus_msg, modbus_msg->DevId.NextObjId);
|
MB_WriteObjectsToMessage(modbus_msg, modbus_msg->DevId.NextObjId);
|
||||||
modbus_msg->DevId.NumbOfObj = 1;
|
modbus_msg->DevId.NumbOfObj = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -183,391 +284,402 @@ void MB_DeviceInentificationInit(void)
|
|||||||
MB_ObjectInit(&MB_DEVID.ProductName, MODBUS_PRODUCT_NAME);
|
MB_ObjectInit(&MB_DEVID.ProductName, MODBUS_PRODUCT_NAME);
|
||||||
MB_ObjectInit(&MB_DEVID.ModelName, MODBUS_MODEL_NAME);
|
MB_ObjectInit(&MB_DEVID.ModelName, MODBUS_MODEL_NAME);
|
||||||
|
|
||||||
#if defined(MODBUS_USEROBJECT_0_NAME) && MODBUS_NUMB_OF_USEROBJECTS>0
|
#ifdef MODBUS_USEROBJECT_0_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[0], MODBUS_USEROBJECT_0_NAME);
|
MB_ObjectInit(&MB_DEVID.User[0], MODBUS_USEROBJECT_0_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_1_NAME) && MODBUS_NUMB_OF_USEROBJECTS>1
|
#ifdef MODBUS_USEROBJECT_1_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[1], MODBUS_USEROBJECT_1_NAME);
|
MB_ObjectInit(&MB_DEVID.User[1], MODBUS_USEROBJECT_1_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_2_NAME) && MODBUS_NUMB_OF_USEROBJECTS>2
|
#ifdef MODBUS_USEROBJECT_2_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[2], MODBUS_USEROBJECT_2_NAME);
|
MB_ObjectInit(&MB_DEVID.User[2], MODBUS_USEROBJECT_2_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_3_NAME) && MODBUS_NUMB_OF_USEROBJECTS>3
|
#ifdef MODBUS_USEROBJECT_3_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[3], MODBUS_USEROBJECT_3_NAME);
|
MB_ObjectInit(&MB_DEVID.User[3], MODBUS_USEROBJECT_3_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_4_NAME) && MODBUS_NUMB_OF_USEROBJECTS>4
|
#ifdef MODBUS_USEROBJECT_4_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[4], MODBUS_USEROBJECT_4_NAME);
|
MB_ObjectInit(&MB_DEVID.User[4], MODBUS_USEROBJECT_4_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_5_NAME) && MODBUS_NUMB_OF_USEROBJECTS>5
|
#ifdef MODBUS_USEROBJECT_5_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[5], MODBUS_USEROBJECT_5_NAME);
|
MB_ObjectInit(&MB_DEVID.User[5], MODBUS_USEROBJECT_5_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_6_NAME) && MODBUS_NUMB_OF_USEROBJECTS>6
|
#ifdef MODBUS_USEROBJECT_6_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[6], MODBUS_USEROBJECT_6_NAME);
|
MB_ObjectInit(&MB_DEVID.User[6], MODBUS_USEROBJECT_6_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_7_NAME) && MODBUS_NUMB_OF_USEROBJECTS>7
|
#ifdef MODBUS_USEROBJECT_7_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[7], MODBUS_USEROBJECT_7_NAME);
|
MB_ObjectInit(&MB_DEVID.User[7], MODBUS_USEROBJECT_7_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_8_NAME) && MODBUS_NUMB_OF_USEROBJECTS>8
|
#ifdef MODBUS_USEROBJECT_8_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[8], MODBUS_USEROBJECT_8_NAME);
|
MB_ObjectInit(&MB_DEVID.User[8], MODBUS_USEROBJECT_8_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_9_NAME) && MODBUS_NUMB_OF_USEROBJECTS>9
|
#ifdef MODBUS_USEROBJECT_9_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[9], MODBUS_USEROBJECT_9_NAME);
|
MB_ObjectInit(&MB_DEVID.User[9], MODBUS_USEROBJECT_9_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_10_NAME) && MODBUS_NUMB_OF_USEROBJECTS>10
|
#ifdef MODBUS_USEROBJECT_10_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[10], MODBUS_USEROBJECT_10_NAME);
|
MB_ObjectInit(&MB_DEVID.User[10], MODBUS_USEROBJECT_10_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_11_NAME) && MODBUS_NUMB_OF_USEROBJECTS>11
|
#ifdef MODBUS_USEROBJECT_11_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[11], MODBUS_USEROBJECT_11_NAME);
|
MB_ObjectInit(&MB_DEVID.User[11], MODBUS_USEROBJECT_11_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_12_NAME) && MODBUS_NUMB_OF_USEROBJECTS>12
|
#ifdef MODBUS_USEROBJECT_12_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[12], MODBUS_USEROBJECT_12_NAME);
|
MB_ObjectInit(&MB_DEVID.User[12], MODBUS_USEROBJECT_12_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_13_NAME) && MODBUS_NUMB_OF_USEROBJECTS>13
|
#ifdef MODBUS_USEROBJECT_13_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[13], MODBUS_USEROBJECT_13_NAME);
|
MB_ObjectInit(&MB_DEVID.User[13], MODBUS_USEROBJECT_13_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_14_NAME) && MODBUS_NUMB_OF_USEROBJECTS>14
|
#ifdef MODBUS_USEROBJECT_14_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[14], MODBUS_USEROBJECT_14_NAME);
|
MB_ObjectInit(&MB_DEVID.User[14], MODBUS_USEROBJECT_14_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_15_NAME) && MODBUS_NUMB_OF_USEROBJECTS>15
|
#ifdef MODBUS_USEROBJECT_15_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[15], MODBUS_USEROBJECT_15_NAME);
|
MB_ObjectInit(&MB_DEVID.User[15], MODBUS_USEROBJECT_15_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_16_NAME) && MODBUS_NUMB_OF_USEROBJECTS>16
|
#ifdef MODBUS_USEROBJECT_16_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[16], MODBUS_USEROBJECT_16_NAME);
|
MB_ObjectInit(&MB_DEVID.User[16], MODBUS_USEROBJECT_16_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_17_NAME) && MODBUS_NUMB_OF_USEROBJECTS>17
|
#ifdef MODBUS_USEROBJECT_17_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[17], MODBUS_USEROBJECT_17_NAME);
|
MB_ObjectInit(&MB_DEVID.User[17], MODBUS_USEROBJECT_17_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_18_NAME) && MODBUS_NUMB_OF_USEROBJECTS>18
|
#ifdef MODBUS_USEROBJECT_18_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[18], MODBUS_USEROBJECT_18_NAME);
|
MB_ObjectInit(&MB_DEVID.User[18], MODBUS_USEROBJECT_18_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_19_NAME) && MODBUS_NUMB_OF_USEROBJECTS>19
|
#ifdef MODBUS_USEROBJECT_19_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[19], MODBUS_USEROBJECT_19_NAME);
|
MB_ObjectInit(&MB_DEVID.User[19], MODBUS_USEROBJECT_19_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_20_NAME) && MODBUS_NUMB_OF_USEROBJECTS>20
|
#ifdef MODBUS_USEROBJECT_20_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[20], MODBUS_USEROBJECT_20_NAME);
|
MB_ObjectInit(&MB_DEVID.User[20], MODBUS_USEROBJECT_20_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_21_NAME) && MODBUS_NUMB_OF_USEROBJECTS>21
|
#ifdef MODBUS_USEROBJECT_21_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[21], MODBUS_USEROBJECT_21_NAME);
|
MB_ObjectInit(&MB_DEVID.User[21], MODBUS_USEROBJECT_21_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_22_NAME) && MODBUS_NUMB_OF_USEROBJECTS>22
|
#ifdef MODBUS_USEROBJECT_22_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[22], MODBUS_USEROBJECT_22_NAME);
|
MB_ObjectInit(&MB_DEVID.User[22], MODBUS_USEROBJECT_22_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_23_NAME) && MODBUS_NUMB_OF_USEROBJECTS>23
|
#ifdef MODBUS_USEROBJECT_23_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[23], MODBUS_USEROBJECT_23_NAME);
|
MB_ObjectInit(&MB_DEVID.User[23], MODBUS_USEROBJECT_23_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_24_NAME) && MODBUS_NUMB_OF_USEROBJECTS>24
|
#ifdef MODBUS_USEROBJECT_24_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[24], MODBUS_USEROBJECT_24_NAME);
|
MB_ObjectInit(&MB_DEVID.User[24], MODBUS_USEROBJECT_24_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_25_NAME) && MODBUS_NUMB_OF_USEROBJECTS>25
|
#ifdef MODBUS_USEROBJECT_25_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[25], MODBUS_USEROBJECT_25_NAME);
|
MB_ObjectInit(&MB_DEVID.User[25], MODBUS_USEROBJECT_25_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_26_NAME) && MODBUS_NUMB_OF_USEROBJECTS>26
|
#ifdef MODBUS_USEROBJECT_26_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[26], MODBUS_USEROBJECT_26_NAME);
|
MB_ObjectInit(&MB_DEVID.User[26], MODBUS_USEROBJECT_26_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_27_NAME) && MODBUS_NUMB_OF_USEROBJECTS>27
|
#ifdef MODBUS_USEROBJECT_27_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[27], MODBUS_USEROBJECT_27_NAME);
|
MB_ObjectInit(&MB_DEVID.User[27], MODBUS_USEROBJECT_27_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_28_NAME) && MODBUS_NUMB_OF_USEROBJECTS>28
|
#ifdef MODBUS_USEROBJECT_28_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[28], MODBUS_USEROBJECT_28_NAME);
|
MB_ObjectInit(&MB_DEVID.User[28], MODBUS_USEROBJECT_28_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_29_NAME) && MODBUS_NUMB_OF_USEROBJECTS>29
|
#ifdef MODBUS_USEROBJECT_29_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[29], MODBUS_USEROBJECT_29_NAME);
|
MB_ObjectInit(&MB_DEVID.User[29], MODBUS_USEROBJECT_29_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_30_NAME) && MODBUS_NUMB_OF_USEROBJECTS>30
|
#ifdef MODBUS_USEROBJECT_30_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[30], MODBUS_USEROBJECT_30_NAME);
|
MB_ObjectInit(&MB_DEVID.User[30], MODBUS_USEROBJECT_30_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_31_NAME) && MODBUS_NUMB_OF_USEROBJECTS>31
|
#ifdef MODBUS_USEROBJECT_31_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[31], MODBUS_USEROBJECT_31_NAME);
|
MB_ObjectInit(&MB_DEVID.User[31], MODBUS_USEROBJECT_31_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_32_NAME) && MODBUS_NUMB_OF_USEROBJECTS>32
|
#ifdef MODBUS_USEROBJECT_32_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[32], MODBUS_USEROBJECT_32_NAME);
|
MB_ObjectInit(&MB_DEVID.User[32], MODBUS_USEROBJECT_32_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_33_NAME) && MODBUS_NUMB_OF_USEROBJECTS>33
|
#ifdef MODBUS_USEROBJECT_33_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[33], MODBUS_USEROBJECT_33_NAME);
|
MB_ObjectInit(&MB_DEVID.User[33], MODBUS_USEROBJECT_33_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_34_NAME) && MODBUS_NUMB_OF_USEROBJECTS>34
|
#ifdef MODBUS_USEROBJECT_34_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[34], MODBUS_USEROBJECT_34_NAME);
|
MB_ObjectInit(&MB_DEVID.User[34], MODBUS_USEROBJECT_34_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_35_NAME) && MODBUS_NUMB_OF_USEROBJECTS>35
|
#ifdef MODBUS_USEROBJECT_35_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[35], MODBUS_USEROBJECT_35_NAME);
|
MB_ObjectInit(&MB_DEVID.User[35], MODBUS_USEROBJECT_35_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_36_NAME) && MODBUS_NUMB_OF_USEROBJECTS>36
|
#ifdef MODBUS_USEROBJECT_36_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[36], MODBUS_USEROBJECT_36_NAME);
|
MB_ObjectInit(&MB_DEVID.User[36], MODBUS_USEROBJECT_36_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_37_NAME) && MODBUS_NUMB_OF_USEROBJECTS>37
|
#ifdef MODBUS_USEROBJECT_37_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[37], MODBUS_USEROBJECT_37_NAME);
|
MB_ObjectInit(&MB_DEVID.User[37], MODBUS_USEROBJECT_37_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_38_NAME) && MODBUS_NUMB_OF_USEROBJECTS>38
|
#ifdef MODBUS_USEROBJECT_38_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[38], MODBUS_USEROBJECT_38_NAME);
|
MB_ObjectInit(&MB_DEVID.User[38], MODBUS_USEROBJECT_38_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_39_NAME) && MODBUS_NUMB_OF_USEROBJECTS>39
|
#ifdef MODBUS_USEROBJECT_39_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[39], MODBUS_USEROBJECT_39_NAME);
|
MB_ObjectInit(&MB_DEVID.User[39], MODBUS_USEROBJECT_39_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_40_NAME) && MODBUS_NUMB_OF_USEROBJECTS>40
|
#ifdef MODBUS_USEROBJECT_40_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[40], MODBUS_USEROBJECT_40_NAME);
|
MB_ObjectInit(&MB_DEVID.User[40], MODBUS_USEROBJECT_40_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_41_NAME) && MODBUS_NUMB_OF_USEROBJECTS>41
|
#ifdef MODBUS_USEROBJECT_41_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[41], MODBUS_USEROBJECT_41_NAME);
|
MB_ObjectInit(&MB_DEVID.User[41], MODBUS_USEROBJECT_41_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_42_NAME) && MODBUS_NUMB_OF_USEROBJECTS>42
|
#ifdef MODBUS_USEROBJECT_42_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[42], MODBUS_USEROBJECT_42_NAME);
|
MB_ObjectInit(&MB_DEVID.User[42], MODBUS_USEROBJECT_42_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_43_NAME) && MODBUS_NUMB_OF_USEROBJECTS>43
|
#ifdef MODBUS_USEROBJECT_43_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[43], MODBUS_USEROBJECT_43_NAME);
|
MB_ObjectInit(&MB_DEVID.User[43], MODBUS_USEROBJECT_43_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_44_NAME) && MODBUS_NUMB_OF_USEROBJECTS>44
|
#ifdef MODBUS_USEROBJECT_44_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[44], MODBUS_USEROBJECT_44_NAME);
|
MB_ObjectInit(&MB_DEVID.User[44], MODBUS_USEROBJECT_44_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_45_NAME) && MODBUS_NUMB_OF_USEROBJECTS>45
|
#ifdef MODBUS_USEROBJECT_45_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[45], MODBUS_USEROBJECT_45_NAME);
|
MB_ObjectInit(&MB_DEVID.User[45], MODBUS_USEROBJECT_45_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_46_NAME) && MODBUS_NUMB_OF_USEROBJECTS>46
|
#ifdef MODBUS_USEROBJECT_46_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[46], MODBUS_USEROBJECT_46_NAME);
|
MB_ObjectInit(&MB_DEVID.User[46], MODBUS_USEROBJECT_46_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_47_NAME) && MODBUS_NUMB_OF_USEROBJECTS>47
|
#ifdef MODBUS_USEROBJECT_47_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[47], MODBUS_USEROBJECT_47_NAME);
|
MB_ObjectInit(&MB_DEVID.User[47], MODBUS_USEROBJECT_47_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_48_NAME) && MODBUS_NUMB_OF_USEROBJECTS>48
|
#ifdef MODBUS_USEROBJECT_48_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[48], MODBUS_USEROBJECT_48_NAME);
|
MB_ObjectInit(&MB_DEVID.User[48], MODBUS_USEROBJECT_48_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_49_NAME) && MODBUS_NUMB_OF_USEROBJECTS>49
|
#ifdef MODBUS_USEROBJECT_49_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[49], MODBUS_USEROBJECT_49_NAME);
|
MB_ObjectInit(&MB_DEVID.User[49], MODBUS_USEROBJECT_49_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_50_NAME) && MODBUS_NUMB_OF_USEROBJECTS>50
|
#ifdef MODBUS_USEROBJECT_50_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[50], MODBUS_USEROBJECT_50_NAME);
|
MB_ObjectInit(&MB_DEVID.User[50], MODBUS_USEROBJECT_50_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_51_NAME) && MODBUS_NUMB_OF_USEROBJECTS>51
|
#ifdef MODBUS_USEROBJECT_51_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[51], MODBUS_USEROBJECT_51_NAME);
|
MB_ObjectInit(&MB_DEVID.User[51], MODBUS_USEROBJECT_51_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_52_NAME) && MODBUS_NUMB_OF_USEROBJECTS>52
|
#ifdef MODBUS_USEROBJECT_52_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[52], MODBUS_USEROBJECT_52_NAME);
|
MB_ObjectInit(&MB_DEVID.User[52], MODBUS_USEROBJECT_52_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_53_NAME) && MODBUS_NUMB_OF_USEROBJECTS>53
|
#ifdef MODBUS_USEROBJECT_53_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[53], MODBUS_USEROBJECT_53_NAME);
|
MB_ObjectInit(&MB_DEVID.User[53], MODBUS_USEROBJECT_53_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_54_NAME) && MODBUS_NUMB_OF_USEROBJECTS>54
|
#ifdef MODBUS_USEROBJECT_54_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[54], MODBUS_USEROBJECT_54_NAME);
|
MB_ObjectInit(&MB_DEVID.User[54], MODBUS_USEROBJECT_54_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_55_NAME) && MODBUS_NUMB_OF_USEROBJECTS>55
|
#ifdef MODBUS_USEROBJECT_55_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[55], MODBUS_USEROBJECT_55_NAME);
|
MB_ObjectInit(&MB_DEVID.User[55], MODBUS_USEROBJECT_55_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_56_NAME) && MODBUS_NUMB_OF_USEROBJECTS>56
|
#ifdef MODBUS_USEROBJECT_56_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[56], MODBUS_USEROBJECT_56_NAME);
|
MB_ObjectInit(&MB_DEVID.User[56], MODBUS_USEROBJECT_56_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_57_NAME) && MODBUS_NUMB_OF_USEROBJECTS>57
|
#ifdef MODBUS_USEROBJECT_57_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[57], MODBUS_USEROBJECT_57_NAME);
|
MB_ObjectInit(&MB_DEVID.User[57], MODBUS_USEROBJECT_57_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_58_NAME) && MODBUS_NUMB_OF_USEROBJECTS>58
|
#ifdef MODBUS_USEROBJECT_58_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[58], MODBUS_USEROBJECT_58_NAME);
|
MB_ObjectInit(&MB_DEVID.User[58], MODBUS_USEROBJECT_58_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_59_NAME) && MODBUS_NUMB_OF_USEROBJECTS>59
|
#ifdef MODBUS_USEROBJECT_59_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[59], MODBUS_USEROBJECT_59_NAME);
|
MB_ObjectInit(&MB_DEVID.User[59], MODBUS_USEROBJECT_59_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_60_NAME) && MODBUS_NUMB_OF_USEROBJECTS>60
|
#ifdef MODBUS_USEROBJECT_60_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[60], MODBUS_USEROBJECT_60_NAME);
|
MB_ObjectInit(&MB_DEVID.User[60], MODBUS_USEROBJECT_60_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_61_NAME) && MODBUS_NUMB_OF_USEROBJECTS>61
|
#ifdef MODBUS_USEROBJECT_61_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[61], MODBUS_USEROBJECT_61_NAME);
|
MB_ObjectInit(&MB_DEVID.User[61], MODBUS_USEROBJECT_61_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_62_NAME) && MODBUS_NUMB_OF_USEROBJECTS>62
|
#ifdef MODBUS_USEROBJECT_62_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[62], MODBUS_USEROBJECT_62_NAME);
|
MB_ObjectInit(&MB_DEVID.User[62], MODBUS_USEROBJECT_62_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_63_NAME) && MODBUS_NUMB_OF_USEROBJECTS>63
|
#ifdef MODBUS_USEROBJECT_63_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[63], MODBUS_USEROBJECT_63_NAME);
|
MB_ObjectInit(&MB_DEVID.User[63], MODBUS_USEROBJECT_63_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_64_NAME) && MODBUS_NUMB_OF_USEROBJECTS>64
|
#ifdef MODBUS_USEROBJECT_64_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[64], MODBUS_USEROBJECT_64_NAME);
|
MB_ObjectInit(&MB_DEVID.User[64], MODBUS_USEROBJECT_64_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_65_NAME) && MODBUS_NUMB_OF_USEROBJECTS>65
|
#ifdef MODBUS_USEROBJECT_65_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[65], MODBUS_USEROBJECT_65_NAME);
|
MB_ObjectInit(&MB_DEVID.User[65], MODBUS_USEROBJECT_65_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_66_NAME) && MODBUS_NUMB_OF_USEROBJECTS>66
|
#ifdef MODBUS_USEROBJECT_66_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[66], MODBUS_USEROBJECT_66_NAME);
|
MB_ObjectInit(&MB_DEVID.User[66], MODBUS_USEROBJECT_66_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_67_NAME) && MODBUS_NUMB_OF_USEROBJECTS>67
|
#ifdef MODBUS_USEROBJECT_67_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[67], MODBUS_USEROBJECT_67_NAME);
|
MB_ObjectInit(&MB_DEVID.User[67], MODBUS_USEROBJECT_67_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_68_NAME) && MODBUS_NUMB_OF_USEROBJECTS>68
|
#ifdef MODBUS_USEROBJECT_68_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[68], MODBUS_USEROBJECT_68_NAME);
|
MB_ObjectInit(&MB_DEVID.User[68], MODBUS_USEROBJECT_68_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_69_NAME) && MODBUS_NUMB_OF_USEROBJECTS>69
|
#ifdef MODBUS_USEROBJECT_69_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[69], MODBUS_USEROBJECT_69_NAME);
|
MB_ObjectInit(&MB_DEVID.User[69], MODBUS_USEROBJECT_69_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_70_NAME) && MODBUS_NUMB_OF_USEROBJECTS>70
|
#ifdef MODBUS_USEROBJECT_70_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[70], MODBUS_USEROBJECT_70_NAME);
|
MB_ObjectInit(&MB_DEVID.User[70], MODBUS_USEROBJECT_70_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_71_NAME) && MODBUS_NUMB_OF_USEROBJECTS>71
|
#ifdef MODBUS_USEROBJECT_71_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[71], MODBUS_USEROBJECT_71_NAME);
|
MB_ObjectInit(&MB_DEVID.User[71], MODBUS_USEROBJECT_71_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_72_NAME) && MODBUS_NUMB_OF_USEROBJECTS>72
|
#ifdef MODBUS_USEROBJECT_72_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[72], MODBUS_USEROBJECT_72_NAME);
|
MB_ObjectInit(&MB_DEVID.User[72], MODBUS_USEROBJECT_72_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_73_NAME) && MODBUS_NUMB_OF_USEROBJECTS>73
|
#ifdef MODBUS_USEROBJECT_73_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[73], MODBUS_USEROBJECT_73_NAME);
|
MB_ObjectInit(&MB_DEVID.User[73], MODBUS_USEROBJECT_73_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_74_NAME) && MODBUS_NUMB_OF_USEROBJECTS>74
|
#ifdef MODBUS_USEROBJECT_74_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[74], MODBUS_USEROBJECT_74_NAME);
|
MB_ObjectInit(&MB_DEVID.User[74], MODBUS_USEROBJECT_74_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_75_NAME) && MODBUS_NUMB_OF_USEROBJECTS>75
|
#ifdef MODBUS_USEROBJECT_75_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[75], MODBUS_USEROBJECT_75_NAME);
|
MB_ObjectInit(&MB_DEVID.User[75], MODBUS_USEROBJECT_75_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_76_NAME) && MODBUS_NUMB_OF_USEROBJECTS>76
|
#ifdef MODBUS_USEROBJECT_76_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[76], MODBUS_USEROBJECT_76_NAME);
|
MB_ObjectInit(&MB_DEVID.User[76], MODBUS_USEROBJECT_76_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_77_NAME) && MODBUS_NUMB_OF_USEROBJECTS>77
|
#ifdef MODBUS_USEROBJECT_77_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[77], MODBUS_USEROBJECT_77_NAME);
|
MB_ObjectInit(&MB_DEVID.User[77], MODBUS_USEROBJECT_77_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_78_NAME) && MODBUS_NUMB_OF_USEROBJECTS>78
|
#ifdef MODBUS_USEROBJECT_78_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[78], MODBUS_USEROBJECT_78_NAME);
|
MB_ObjectInit(&MB_DEVID.User[78], MODBUS_USEROBJECT_78_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_79_NAME) && MODBUS_NUMB_OF_USEROBJECTS>79
|
#ifdef MODBUS_USEROBJECT_79_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[79], MODBUS_USEROBJECT_79_NAME);
|
MB_ObjectInit(&MB_DEVID.User[79], MODBUS_USEROBJECT_79_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_80_NAME) && MODBUS_NUMB_OF_USEROBJECTS>80
|
#ifdef MODBUS_USEROBJECT_80_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[80], MODBUS_USEROBJECT_80_NAME);
|
MB_ObjectInit(&MB_DEVID.User[80], MODBUS_USEROBJECT_80_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_81_NAME) && MODBUS_NUMB_OF_USEROBJECTS>81
|
#ifdef MODBUS_USEROBJECT_81_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[81], MODBUS_USEROBJECT_81_NAME);
|
MB_ObjectInit(&MB_DEVID.User[81], MODBUS_USEROBJECT_81_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_82_NAME) && MODBUS_NUMB_OF_USEROBJECTS>82
|
#ifdef MODBUS_USEROBJECT_82_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[82], MODBUS_USEROBJECT_82_NAME);
|
MB_ObjectInit(&MB_DEVID.User[82], MODBUS_USEROBJECT_82_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_83_NAME) && MODBUS_NUMB_OF_USEROBJECTS>83
|
#ifdef MODBUS_USEROBJECT_83_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[83], MODBUS_USEROBJECT_83_NAME);
|
MB_ObjectInit(&MB_DEVID.User[83], MODBUS_USEROBJECT_83_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_84_NAME) && MODBUS_NUMB_OF_USEROBJECTS>84
|
#ifdef MODBUS_USEROBJECT_84_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[84], MODBUS_USEROBJECT_84_NAME);
|
MB_ObjectInit(&MB_DEVID.User[84], MODBUS_USEROBJECT_84_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_85_NAME) && MODBUS_NUMB_OF_USEROBJECTS>85
|
#ifdef MODBUS_USEROBJECT_85_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[85], MODBUS_USEROBJECT_85_NAME);
|
MB_ObjectInit(&MB_DEVID.User[85], MODBUS_USEROBJECT_85_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_86_NAME) && MODBUS_NUMB_OF_USEROBJECTS>86
|
#ifdef MODBUS_USEROBJECT_86_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[86], MODBUS_USEROBJECT_86_NAME);
|
MB_ObjectInit(&MB_DEVID.User[86], MODBUS_USEROBJECT_86_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_87_NAME) && MODBUS_NUMB_OF_USEROBJECTS>87
|
#ifdef MODBUS_USEROBJECT_87_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[87], MODBUS_USEROBJECT_87_NAME);
|
MB_ObjectInit(&MB_DEVID.User[87], MODBUS_USEROBJECT_87_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_88_NAME) && MODBUS_NUMB_OF_USEROBJECTS>88
|
#ifdef MODBUS_USEROBJECT_88_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[88], MODBUS_USEROBJECT_88_NAME);
|
MB_ObjectInit(&MB_DEVID.User[88], MODBUS_USEROBJECT_88_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_89_NAME) && MODBUS_NUMB_OF_USEROBJECTS>89
|
#ifdef MODBUS_USEROBJECT_89_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[89], MODBUS_USEROBJECT_89_NAME);
|
MB_ObjectInit(&MB_DEVID.User[89], MODBUS_USEROBJECT_89_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_90_NAME) && MODBUS_NUMB_OF_USEROBJECTS>90
|
#ifdef MODBUS_USEROBJECT_90_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[90], MODBUS_USEROBJECT_90_NAME);
|
MB_ObjectInit(&MB_DEVID.User[90], MODBUS_USEROBJECT_90_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_91_NAME) && MODBUS_NUMB_OF_USEROBJECTS>91
|
#ifdef MODBUS_USEROBJECT_91_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[91], MODBUS_USEROBJECT_91_NAME);
|
MB_ObjectInit(&MB_DEVID.User[91], MODBUS_USEROBJECT_91_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_92_NAME) && MODBUS_NUMB_OF_USEROBJECTS>92
|
#ifdef MODBUS_USEROBJECT_92_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[92], MODBUS_USEROBJECT_92_NAME);
|
MB_ObjectInit(&MB_DEVID.User[92], MODBUS_USEROBJECT_92_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_93_NAME) && MODBUS_NUMB_OF_USEROBJECTS>93
|
#ifdef MODBUS_USEROBJECT_93_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[93], MODBUS_USEROBJECT_93_NAME);
|
MB_ObjectInit(&MB_DEVID.User[93], MODBUS_USEROBJECT_93_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_94_NAME) && MODBUS_NUMB_OF_USEROBJECTS>94
|
#ifdef MODBUS_USEROBJECT_94_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[94], MODBUS_USEROBJECT_94_NAME);
|
MB_ObjectInit(&MB_DEVID.User[94], MODBUS_USEROBJECT_94_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_95_NAME) && MODBUS_NUMB_OF_USEROBJECTS>95
|
#ifdef MODBUS_USEROBJECT_95_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[95], MODBUS_USEROBJECT_95_NAME);
|
MB_ObjectInit(&MB_DEVID.User[95], MODBUS_USEROBJECT_95_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_96_NAME) && MODBUS_NUMB_OF_USEROBJECTS>96
|
#ifdef MODBUS_USEROBJECT_96_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[96], MODBUS_USEROBJECT_96_NAME);
|
MB_ObjectInit(&MB_DEVID.User[96], MODBUS_USEROBJECT_96_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_97_NAME) && MODBUS_NUMB_OF_USEROBJECTS>97
|
#ifdef MODBUS_USEROBJECT_97_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[97], MODBUS_USEROBJECT_97_NAME);
|
MB_ObjectInit(&MB_DEVID.User[97], MODBUS_USEROBJECT_97_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_98_NAME) && MODBUS_NUMB_OF_USEROBJECTS>98
|
#ifdef MODBUS_USEROBJECT_98_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[98], MODBUS_USEROBJECT_98_NAME);
|
MB_ObjectInit(&MB_DEVID.User[98], MODBUS_USEROBJECT_98_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_99_NAME) && MODBUS_NUMB_OF_USEROBJECTS>99
|
#ifdef MODBUS_USEROBJECT_99_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[99], MODBUS_USEROBJECT_99_NAME);
|
MB_ObjectInit(&MB_DEVID.User[99], MODBUS_USEROBJECT_99_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_100_NAME) && MODBUS_NUMB_OF_USEROBJECTS>100
|
#ifdef MODBUS_USEROBJECT_100_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[100], MODBUS_USEROBJECT_100_NAME);
|
MB_ObjectInit(&MB_DEVID.User[100], MODBUS_USEROBJECT_100_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_101_NAME) && MODBUS_NUMB_OF_USEROBJECTS>101
|
#ifdef MODBUS_USEROBJECT_101_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[101], MODBUS_USEROBJECT_101_NAME);
|
MB_ObjectInit(&MB_DEVID.User[101], MODBUS_USEROBJECT_101_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_102_NAME) && MODBUS_NUMB_OF_USEROBJECTS>102
|
#ifdef MODBUS_USEROBJECT_102_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[102], MODBUS_USEROBJECT_102_NAME);
|
MB_ObjectInit(&MB_DEVID.User[102], MODBUS_USEROBJECT_102_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_103_NAME) && MODBUS_NUMB_OF_USEROBJECTS>103
|
#ifdef MODBUS_USEROBJECT_103_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[103], MODBUS_USEROBJECT_103_NAME);
|
MB_ObjectInit(&MB_DEVID.User[103], MODBUS_USEROBJECT_103_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_104_NAME) && MODBUS_NUMB_OF_USEROBJECTS>104
|
#ifdef MODBUS_USEROBJECT_104_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[104], MODBUS_USEROBJECT_104_NAME);
|
MB_ObjectInit(&MB_DEVID.User[104], MODBUS_USEROBJECT_104_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_105_NAME) && MODBUS_NUMB_OF_USEROBJECTS>105
|
#ifdef MODBUS_USEROBJECT_105_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[105], MODBUS_USEROBJECT_105_NAME);
|
MB_ObjectInit(&MB_DEVID.User[105], MODBUS_USEROBJECT_105_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_106_NAME) && MODBUS_NUMB_OF_USEROBJECTS>106
|
#ifdef MODBUS_USEROBJECT_106_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[106], MODBUS_USEROBJECT_106_NAME);
|
MB_ObjectInit(&MB_DEVID.User[106], MODBUS_USEROBJECT_106_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_107_NAME) && MODBUS_NUMB_OF_USEROBJECTS>107
|
#ifdef MODBUS_USEROBJECT_107_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[107], MODBUS_USEROBJECT_107_NAME);
|
MB_ObjectInit(&MB_DEVID.User[107], MODBUS_USEROBJECT_107_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_108_NAME) && MODBUS_NUMB_OF_USEROBJECTS>108
|
#ifdef MODBUS_USEROBJECT_108_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[108], MODBUS_USEROBJECT_108_NAME);
|
MB_ObjectInit(&MB_DEVID.User[108], MODBUS_USEROBJECT_108_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_109_NAME) && MODBUS_NUMB_OF_USEROBJECTS>109
|
#ifdef MODBUS_USEROBJECT_109_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[109], MODBUS_USEROBJECT_109_NAME);
|
MB_ObjectInit(&MB_DEVID.User[109], MODBUS_USEROBJECT_109_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_110_NAME) && MODBUS_NUMB_OF_USEROBJECTS>110
|
#ifdef MODBUS_USEROBJECT_110_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[110], MODBUS_USEROBJECT_110_NAME);
|
MB_ObjectInit(&MB_DEVID.User[110], MODBUS_USEROBJECT_110_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_111_NAME) && MODBUS_NUMB_OF_USEROBJECTS>111
|
#ifdef MODBUS_USEROBJECT_111_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[111], MODBUS_USEROBJECT_111_NAME);
|
MB_ObjectInit(&MB_DEVID.User[111], MODBUS_USEROBJECT_111_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_112_NAME) && MODBUS_NUMB_OF_USEROBJECTS>112
|
#ifdef MODBUS_USEROBJECT_112_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[112], MODBUS_USEROBJECT_112_NAME);
|
MB_ObjectInit(&MB_DEVID.User[112], MODBUS_USEROBJECT_112_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_113_NAME) && MODBUS_NUMB_OF_USEROBJECTS>113
|
#ifdef MODBUS_USEROBJECT_113_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[113], MODBUS_USEROBJECT_113_NAME);
|
MB_ObjectInit(&MB_DEVID.User[113], MODBUS_USEROBJECT_113_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_114_NAME) && MODBUS_NUMB_OF_USEROBJECTS>114
|
#ifdef MODBUS_USEROBJECT_114_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[114], MODBUS_USEROBJECT_114_NAME);
|
MB_ObjectInit(&MB_DEVID.User[114], MODBUS_USEROBJECT_114_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_115_NAME) && MODBUS_NUMB_OF_USEROBJECTS>115
|
#ifdef MODBUS_USEROBJECT_115_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[115], MODBUS_USEROBJECT_115_NAME);
|
MB_ObjectInit(&MB_DEVID.User[115], MODBUS_USEROBJECT_115_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_116_NAME) && MODBUS_NUMB_OF_USEROBJECTS>116
|
#ifdef MODBUS_USEROBJECT_116_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[116], MODBUS_USEROBJECT_116_NAME);
|
MB_ObjectInit(&MB_DEVID.User[116], MODBUS_USEROBJECT_116_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_117_NAME) && MODBUS_NUMB_OF_USEROBJECTS>117
|
#ifdef MODBUS_USEROBJECT_117_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[117], MODBUS_USEROBJECT_117_NAME);
|
MB_ObjectInit(&MB_DEVID.User[117], MODBUS_USEROBJECT_117_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_118_NAME) && MODBUS_NUMB_OF_USEROBJECTS>118
|
#ifdef MODBUS_USEROBJECT_118_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[118], MODBUS_USEROBJECT_118_NAME);
|
MB_ObjectInit(&MB_DEVID.User[118], MODBUS_USEROBJECT_118_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_119_NAME) && MODBUS_NUMB_OF_USEROBJECTS>119
|
#ifdef MODBUS_USEROBJECT_119_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[119], MODBUS_USEROBJECT_119_NAME);
|
MB_ObjectInit(&MB_DEVID.User[119], MODBUS_USEROBJECT_119_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_120_NAME) && MODBUS_NUMB_OF_USEROBJECTS>120
|
#ifdef MODBUS_USEROBJECT_120_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[120], MODBUS_USEROBJECT_120_NAME);
|
MB_ObjectInit(&MB_DEVID.User[120], MODBUS_USEROBJECT_120_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_121_NAME) && MODBUS_NUMB_OF_USEROBJECTS>121
|
#ifdef MODBUS_USEROBJECT_121_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[121], MODBUS_USEROBJECT_121_NAME);
|
MB_ObjectInit(&MB_DEVID.User[121], MODBUS_USEROBJECT_121_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_122_NAME) && MODBUS_NUMB_OF_USEROBJECTS>122
|
#ifdef MODBUS_USEROBJECT_122_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[122], MODBUS_USEROBJECT_122_NAME);
|
MB_ObjectInit(&MB_DEVID.User[122], MODBUS_USEROBJECT_122_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_123_NAME) && MODBUS_NUMB_OF_USEROBJECTS>123
|
#ifdef MODBUS_USEROBJECT_123_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[123], MODBUS_USEROBJECT_123_NAME);
|
MB_ObjectInit(&MB_DEVID.User[123], MODBUS_USEROBJECT_123_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_124_NAME) && MODBUS_NUMB_OF_USEROBJECTS>124
|
#ifdef MODBUS_USEROBJECT_124_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[124], MODBUS_USEROBJECT_124_NAME);
|
MB_ObjectInit(&MB_DEVID.User[124], MODBUS_USEROBJECT_124_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_125_NAME) && MODBUS_NUMB_OF_USEROBJECTS>125
|
#ifdef MODBUS_USEROBJECT_125_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[125], MODBUS_USEROBJECT_125_NAME);
|
MB_ObjectInit(&MB_DEVID.User[125], MODBUS_USEROBJECT_125_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_126_NAME) && MODBUS_NUMB_OF_USEROBJECTS>126
|
#ifdef MODBUS_USEROBJECT_126_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[126], MODBUS_USEROBJECT_126_NAME);
|
MB_ObjectInit(&MB_DEVID.User[126], MODBUS_USEROBJECT_126_NAME);
|
||||||
#endif
|
#endif
|
||||||
#if defined(MODBUS_USEROBJECT_127_NAME) && MODBUS_NUMB_OF_USEROBJECTS>127
|
#ifdef MODBUS_USEROBJECT_127_NAME
|
||||||
MB_ObjectInit(&MB_DEVID.User[127], MODBUS_USEROBJECT_127_NAME);
|
MB_ObjectInit(&MB_DEVID.User[127], MODBUS_USEROBJECT_127_NAME);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
|
||||||
|
#else //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
||||||
|
|
||||||
|
/* Получить количество объектов в сообщении */
|
||||||
|
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
|
||||||
|
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length) {return 0;}
|
||||||
|
void MB_WriteSingleObjectToMessage(char *mbdata, unsigned *ind, MB_DeviceObjectTypeDef *obj) {}
|
||||||
|
void MB_WriteObjectsToMessage(RS_MsgTypeDef *modbus_msg, unsigned maxidofobj) {}
|
||||||
|
uint8_t MB_Process_Read_Device_Identifications(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
void MB_DeviceInentificationInit(void) {}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -36,6 +36,29 @@ void MB_DiagnosticsInit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Получить данные диагностики из сообщения (DATA[1])
|
||||||
|
* @param modbus_msg Указатель на структуру сообщения
|
||||||
|
* @param data Указатель куда положить данные
|
||||||
|
* @return 1 - успех, 0 - ошибка
|
||||||
|
*/
|
||||||
|
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
|
||||||
|
{
|
||||||
|
if(modbus_msg == NULL || data == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Проверяем что ответ связан с диагностикой
|
||||||
|
if(modbus_msg->Func_Code != MB_R_DIAGNOSTIC)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*data = modbus_msg->DATA[1];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Выставить бит в регистре диагностике
|
* @brief Выставить бит в регистре диагностике
|
||||||
* @param bit_num Номер бита для выставления (1-15, 0 бит нельзя выставить)
|
* @param bit_num Номер бита для выставления (1-15, 0 бит нельзя выставить)
|
||||||
@@ -74,8 +97,8 @@ int MB_Diagnostics_GetBit(int bit_num)
|
|||||||
*/
|
*/
|
||||||
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
||||||
{
|
{
|
||||||
uint16_t sub_function = modbus_msg->MbData[0];
|
uint16_t sub_function = modbus_msg->DATA[0];
|
||||||
uint16_t request_data = modbus_msg->MbData[1];
|
uint16_t request_data = modbus_msg->DATA[1];
|
||||||
|
|
||||||
// Если устройство в режиме Listen Only, отвечаем только на sub-function 0x01
|
// Если устройство в режиме Listen Only, отвечаем только на sub-function 0x01
|
||||||
if (MB_DIAG.DeviceMode == MODBUS_LISTEN_ONLY_MODE && sub_function != 0x0001)
|
if (MB_DIAG.DeviceMode == MODBUS_LISTEN_ONLY_MODE && sub_function != 0x0001)
|
||||||
@@ -87,8 +110,8 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
|||||||
{
|
{
|
||||||
case 0x0000: // Return Query Data
|
case 0x0000: // Return Query Data
|
||||||
// Эхо-ответ с теми же данными
|
// Эхо-ответ с теми же данными
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = request_data;
|
modbus_msg->DATA[1] = request_data;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -114,21 +137,21 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
|||||||
MB_DIAG.Counters.BusCharacterOverrun = 0;
|
MB_DIAG.Counters.BusCharacterOverrun = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = request_data;
|
modbus_msg->DATA[1] = request_data;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0002: // Return Diagnostic Register
|
case 0x0002: // Return Diagnostic Register
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.DiagnosticRegister;
|
modbus_msg->DATA[1] = MB_DIAG.DiagnosticRegister;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0003: // Change ASCII Input Delimiter
|
case 0x0003: // Change ASCII Input Delimiter
|
||||||
// В RTU режиме не поддерживается
|
// В RTU режиме не поддерживается
|
||||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||||
modbus_msg->Except_Code = ET_ILLEGAL_FUNCTION;
|
modbus_msg->Except_Code = ILLEGAL_FUNCTION;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x0004: // Force Listen Only Mode
|
case 0x0004: // Force Listen Only Mode
|
||||||
@@ -138,56 +161,56 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
|||||||
|
|
||||||
case 0x000A: // Clear Counters and Diagnostic Register
|
case 0x000A: // Clear Counters and Diagnostic Register
|
||||||
MB_DiagnosticsInit(); // Полный сброс
|
MB_DiagnosticsInit(); // Полный сброс
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = 0;
|
modbus_msg->DATA[1] = 0;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x000B: // Return Bus Message Count
|
case 0x000B: // Return Bus Message Count
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.Counters.BusMessage;
|
modbus_msg->DATA[1] = MB_DIAG.Counters.BusMessage;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x000C: // Return Bus Communication Error Count
|
case 0x000C: // Return Bus Communication Error Count
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.Counters.BusCommunicationErr;
|
modbus_msg->DATA[1] = MB_DIAG.Counters.BusCommunicationErr;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x000D: // Return Bus Exception Error Count
|
case 0x000D: // Return Bus Exception Error Count
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.Counters.BusExceptionErr;
|
modbus_msg->DATA[1] = MB_DIAG.Counters.BusExceptionErr;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x000E: // Return Server Message Count
|
case 0x000E: // Return Server Message Count
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveMessage;
|
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveMessage;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x000F: // Return Slave No Response Count
|
case 0x000F: // Return Slave No Response Count
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveNoResponse;
|
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveNoResponse;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0010: // Return Slave NAK Count
|
case 0x0010: // Return Slave NAK Count
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveNAK;
|
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveNAK;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0011: // Return Slave Busy Count
|
case 0x0011: // Return Slave Busy Count
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.Counters.SlaveBusy;
|
modbus_msg->DATA[1] = MB_DIAG.Counters.SlaveBusy;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0012: // Return Bus Character Overrun Count
|
case 0x0012: // Return Bus Character Overrun Count
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = MB_DIAG.Counters.BusCharacterOverrun;
|
modbus_msg->DATA[1] = MB_DIAG.Counters.BusCharacterOverrun;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -195,14 +218,14 @@ uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg)
|
|||||||
MB_DIAG.Counters.BusCharacterOverrun = 0;
|
MB_DIAG.Counters.BusCharacterOverrun = 0;
|
||||||
// Сбрасываем флаг переполнения в DiagnosticRegister
|
// Сбрасываем флаг переполнения в DiagnosticRegister
|
||||||
MB_DIAG.DiagnosticRegister &= ~(1<<0);
|
MB_DIAG.DiagnosticRegister &= ~(1<<0);
|
||||||
modbus_msg->MbData[0] = sub_function;
|
modbus_msg->DATA[0] = sub_function;
|
||||||
modbus_msg->MbData[1] = 0;
|
modbus_msg->DATA[1] = 0;
|
||||||
modbus_msg->ByteCnt = 4;
|
modbus_msg->ByteCnt = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||||
modbus_msg->Except_Code = ET_ILLEGAL_FUNCTION;
|
modbus_msg->Except_Code = ILLEGAL_FUNCTION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,4 +316,21 @@ MB_DeviceModeTypeDef MB_GetDeviceMode(void)
|
|||||||
return MB_DIAG.DeviceMode;
|
return MB_DIAG.DeviceMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
#else //MODBUS_ENABLE_DIAGNOSTICS
|
||||||
|
|
||||||
|
void MB_DiagnosticsInit(void) {}
|
||||||
|
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data) {return 0;}
|
||||||
|
int MB_Diagnostics_WriteBit(int bit_num, int bit_state) {return 0;}
|
||||||
|
int MB_Diagnostics_GetBit(int bit_num) {return 0;}
|
||||||
|
uint8_t MB_Process_Diagnostics(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
void MB_Diagnostics_BusMessageCnt(void) {}
|
||||||
|
void MB_Diagnostics_CommunicationErrorCnt(void) {}
|
||||||
|
void MB_Diagnostics_ExceptionErrorCnt(void) {}
|
||||||
|
void MB_Diagnostics_CharacterOverrunCnt(void) {}
|
||||||
|
void MB_Diagnostics_SlaveMessageCnt(void) {}
|
||||||
|
void MB_Diagnostics_SlaveNoResponseCnt(void) {}
|
||||||
|
void MB_Diagnostics_SlaveNAKCnt(void) {}
|
||||||
|
void MB_Diagnostics_SlaveBusyCnt(void) {}
|
||||||
|
MB_DeviceModeTypeDef MB_GetDeviceMode(void) {return MODBUS_NORMAL_MODE;}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -24,66 +24,6 @@
|
|||||||
#ifdef MODBUS_ENABLE_HOLDINGS
|
#ifdef MODBUS_ENABLE_HOLDINGS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Записать регистр хранения по глобальному адресу.
|
|
||||||
* @param Addr Адрес регистра.
|
|
||||||
* @param WriteVal Число для записи.
|
|
||||||
* @return ExceptionCode Код исключения если регистра по адресу не существует, и ET_NO_ERRORS если все ок.
|
|
||||||
*
|
|
||||||
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
|
|
||||||
Вне зависимости от того как регистры размещены в памяти.
|
|
||||||
*/
|
|
||||||
MB_ExceptionTypeDef MB_Holding_Write_Global(uint16_t Addr, uint16_t WriteVal)
|
|
||||||
{
|
|
||||||
//---------CHECK FOR ERRORS----------
|
|
||||||
MB_ExceptionTypeDef Exception = ET_NO_ERRORS;
|
|
||||||
uint16_t *pHoldRegs;
|
|
||||||
|
|
||||||
//------------WRITE COIL-------------
|
|
||||||
Exception = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
|
|
||||||
if(Exception == ET_NO_ERRORS)
|
|
||||||
{
|
|
||||||
*(pHoldRegs) = WriteVal;
|
|
||||||
}
|
|
||||||
return Exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Считать регистр хранения по глобальному адресу.
|
|
||||||
* @param Addr Адрес регистра.
|
|
||||||
* @param Exception Указатель на переменную для кода исключения, в случае неудачи при чтении.
|
|
||||||
* @return uint16_t Возвращает значение регистра.
|
|
||||||
*
|
|
||||||
* @details Позволяет обратиться к любому регистру по его глобальному адрессу.
|
|
||||||
Вне зависимости от того как регистры размещены в памяти.
|
|
||||||
*/
|
|
||||||
uint16_t MB_Holding_Read_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
|
||||||
{
|
|
||||||
//---------CHECK FOR ERRORS----------
|
|
||||||
MB_ExceptionTypeDef Exception_tmp = 0;
|
|
||||||
|
|
||||||
uint16_t *pHoldRegs;
|
|
||||||
|
|
||||||
//------------READ COIL--------------
|
|
||||||
Exception_tmp = MB_DefineRegistersAddress(&pHoldRegs, Addr, 1, RegisterType_Holding);
|
|
||||||
|
|
||||||
if(Exception) // if exception is not given to func fill it
|
|
||||||
*Exception = Exception_tmp;
|
|
||||||
|
|
||||||
if(Exception_tmp == ET_NO_ERRORS)
|
|
||||||
{
|
|
||||||
return *(pHoldRegs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Обработать функцию Read Holding Registers (03 - 0x03).
|
* @brief Обработать функцию Read Holding Registers (03 - 0x03).
|
||||||
* @param modbus_msg Указатель на структуру собщения modbus.
|
* @param modbus_msg Указатель на структуру собщения modbus.
|
||||||
@@ -96,7 +36,7 @@ uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
|
|||||||
// get origin address for data
|
// get origin address for data
|
||||||
uint16_t *pHoldRegs;
|
uint16_t *pHoldRegs;
|
||||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -107,7 +47,7 @@ uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i<modbus_msg->Qnt; i++)
|
for (i = 0; i<modbus_msg->Qnt; i++)
|
||||||
{
|
{
|
||||||
modbus_msg->MbData[i] = *(pHoldRegs++);
|
modbus_msg->DATA[i] = *(pHoldRegs++);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -123,7 +63,7 @@ uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
|
|||||||
// get origin address for data
|
// get origin address for data
|
||||||
uint16_t *pHoldRegs;
|
uint16_t *pHoldRegs;
|
||||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров
|
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров
|
||||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//-----------WRITTING REG------------
|
//-----------WRITTING REG------------
|
||||||
@@ -148,15 +88,22 @@ uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
|
|||||||
// get origin address for data
|
// get origin address for data
|
||||||
uint16_t *pHoldRegs;
|
uint16_t *pHoldRegs;
|
||||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||||||
if(modbus_msg->Except_Code != ET_NO_ERRORS)
|
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//-----------WRITTING REGS-----------
|
//-----------WRITTING REGS-----------
|
||||||
for (int i = 0; i<modbus_msg->Qnt; i++)
|
for (int i = 0; i<modbus_msg->Qnt; i++)
|
||||||
{
|
{
|
||||||
*(pHoldRegs++) = modbus_msg->MbData[i];
|
*(pHoldRegs++) = modbus_msg->DATA[i];
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //MODBUS_ENABLE_HOLDINGS
|
|
||||||
|
#else //MODBUS_ENABLE_HOLDINGS
|
||||||
|
|
||||||
|
uint8_t MB_Process_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
uint8_t MB_Process_Write_Single_Reg(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
uint8_t MB_Process_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
|
||||||
|
#endif
|
||||||
52
Modbus/Src/modbus_inputregs.c
Normal file
52
Modbus/Src/modbus_inputregs.c
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file modbus_inputregs.c
|
||||||
|
* @brief Реализация работы с входными регистрами Modbus
|
||||||
|
******************************************************************************
|
||||||
|
* @details
|
||||||
|
Модуль обработки команды чтения input registers (0x04):
|
||||||
|
- Чтение множественных входных регистров
|
||||||
|
Копирование данных из структур устройства в буфер ответа
|
||||||
|
- Поддержка знаковых и беззнаковых значений
|
||||||
|
******************************************************************************/
|
||||||
|
#include "modbus_inputregs.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MODBUS_ENABLE_INPUTS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Обработать функцию Read Input Registers (04 - 0x04).
|
||||||
|
* @param modbus_msg Указатель на структуру собщения modbus.
|
||||||
|
* @return fMessageHandled Статус о результате обработки комманды.
|
||||||
|
* @details Обработка команды Read Input Registers.
|
||||||
|
*/
|
||||||
|
uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
|
||||||
|
{
|
||||||
|
//---------CHECK FOR ERRORS----------
|
||||||
|
// get origin address for data
|
||||||
|
uint16_t *pInRegs;
|
||||||
|
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pInRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Input); // определение адреса регистров
|
||||||
|
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
//-----------READING REGS------------
|
||||||
|
// setup output message data size
|
||||||
|
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
|
||||||
|
// read data
|
||||||
|
int i;
|
||||||
|
for (i = 0; i<modbus_msg->Qnt; i++)
|
||||||
|
{
|
||||||
|
if(*((int16_t *)pInRegs) > 0)
|
||||||
|
modbus_msg->DATA[i] = (*pInRegs++);
|
||||||
|
else
|
||||||
|
modbus_msg->DATA[i] = (*pInRegs++);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else //MODBUS_ENABLE_INPUTS
|
||||||
|
|
||||||
|
uint8_t MB_Process_Read_Input_Regs(RS_MsgTypeDef *modbus_msg) {return 0;}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -29,9 +29,9 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Проверяем что ответ связан с регистрами
|
// Проверяем что ответ связан с регистрами
|
||||||
if((modbus_msg->FuncCode != FC_R_DISC_IN) &&
|
if((modbus_msg->Func_Code != MB_R_DISC_IN) &&
|
||||||
(modbus_msg->FuncCode != FC_R_HOLD_REGS) &&
|
(modbus_msg->Func_Code != MB_R_HOLD_REGS) &&
|
||||||
(modbus_msg->FuncCode != FC_R_IN_REGS))
|
(modbus_msg->Func_Code != MB_R_IN_REGS))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -48,208 +48,11 @@ int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint1
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Получаем значение регистра
|
// Получаем значение регистра
|
||||||
*reg_value = modbus_msg->MbData[reg_index];
|
*reg_value = modbus_msg->DATA[reg_index];
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Получить состояние coil в ответе по его адресу
|
|
||||||
* @param modbus_msg Указатель на структуру сообщения
|
|
||||||
* @param coil_addr Адрес coil, состояние которого нужно получить
|
|
||||||
* @param coil_state Указатель для состояния coil (1 - ON, 0 - OFF)
|
|
||||||
* @return 1 - успех, 0 - ошибка или coil_addr вне диапазона запроса
|
|
||||||
*/
|
|
||||||
int MB_RespGet_CoilState(RS_MsgTypeDef *modbus_msg, uint16_t coil_addr, int *coil_state)
|
|
||||||
{
|
|
||||||
if(modbus_msg == NULL || coil_state == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Проверяем что ответ связан с коилами
|
|
||||||
if(modbus_msg->FuncCode != FC_R_COILS)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверяем что coil_addr в пределах запрошенного диапазона
|
|
||||||
if(coil_addr < modbus_msg->Addr || coil_addr >= modbus_msg->Addr + modbus_msg->Qnt)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Вычисляем индекс coil в полученных данных
|
|
||||||
uint16_t coil_index = coil_addr - modbus_msg->Addr;
|
|
||||||
|
|
||||||
// Вычисляем байт и бит
|
|
||||||
uint8_t byte_index = coil_index / 8;
|
|
||||||
uint8_t data_index = coil_index / 16;
|
|
||||||
uint8_t bit_index = coil_index % 16;
|
|
||||||
|
|
||||||
// Проверяем что байт существует в данных
|
|
||||||
if(byte_index >= modbus_msg->ByteCnt)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Получаем байт и проверяем бит
|
|
||||||
if(bit_index < 8)
|
|
||||||
*coil_state = (modbus_msg->MbData[data_index] >> (bit_index+8)) & 0x01;
|
|
||||||
else
|
|
||||||
*coil_state = ((modbus_msg->MbData[data_index]&0xFF) >> bit_index-8) & 0x01;
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Получить количество объектов в сообщении
|
|
||||||
* @param modbus_msg Указатель на структуру сообщения
|
|
||||||
* @return int Количество объектов
|
|
||||||
*/
|
|
||||||
int MB_RespGet_NumberOfObjects(RS_MsgTypeDef *modbus_msg)
|
|
||||||
{
|
|
||||||
if(modbus_msg == NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Проверяем что ответ связан с диагностикой
|
|
||||||
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return modbus_msg->DevId.NumbOfObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Найти объект по ID в сообщении
|
|
||||||
* @param modbus_msg Указатель на структуру сообщения
|
|
||||||
* @param obj_id ID искомого объекта
|
|
||||||
* @param obj_data Буфер для данных объекта (может быть NULL)
|
|
||||||
* @param obj_length Указатель для длины объекта
|
|
||||||
* @return int Найден ли объект (1 - да, 0 - нет)
|
|
||||||
*/
|
|
||||||
int MB_RespGet_ObjectById(RS_MsgTypeDef *modbus_msg, uint8_t obj_id, char *obj_data, uint8_t *obj_length)
|
|
||||||
{
|
|
||||||
if((modbus_msg == NULL) || (obj_data == NULL))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Проверяем что ответ связан с диагностикой
|
|
||||||
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *data = (uint8_t*)modbus_msg->MbData;
|
|
||||||
unsigned ind = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < modbus_msg->DevId.NumbOfObj; i++)
|
|
||||||
{
|
|
||||||
uint8_t current_id = data[ind++];
|
|
||||||
uint8_t current_length = data[ind++];
|
|
||||||
|
|
||||||
if(current_id == obj_id)
|
|
||||||
{
|
|
||||||
if(obj_length)
|
|
||||||
*obj_length = current_length;
|
|
||||||
|
|
||||||
for(int j = 0; j < current_length; j++)
|
|
||||||
{
|
|
||||||
obj_data[j] = data[ind++];
|
|
||||||
}
|
|
||||||
obj_data[current_length] = '\0'; // добавляем \0
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Пропускаем данные этого объекта
|
|
||||||
ind += current_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Получить объект по индексу в сообщении
|
|
||||||
* @param modbus_msg Указатель на структуру сообщения
|
|
||||||
* @param index Индекс объекта (0..N-1)
|
|
||||||
* @param obj_id Указатель для ID объекта
|
|
||||||
* @param obj_data Буфер для данных объекта
|
|
||||||
* @param obj_length Указатель для длины объекта
|
|
||||||
* @return int Успешность получения (1 - получен, 0 - не найден)
|
|
||||||
*/
|
|
||||||
int MB_RespGet_ObjectByIndex(RS_MsgTypeDef *modbus_msg, int index, uint8_t *obj_id, char *obj_data, uint8_t *obj_length)
|
|
||||||
{
|
|
||||||
if((modbus_msg == NULL) || (obj_data == NULL))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Проверяем что ответ связан с диагностикой
|
|
||||||
if(modbus_msg->FuncCode != FC_R_DEVICE_ID)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(index >= modbus_msg->DevId.NumbOfObj)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
uint8_t *data = (uint8_t*)modbus_msg->MbData;
|
|
||||||
unsigned ind = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i <= index; i++)
|
|
||||||
{
|
|
||||||
uint8_t current_id = data[ind++];
|
|
||||||
uint8_t current_length = data[ind++];
|
|
||||||
|
|
||||||
if(obj_id)
|
|
||||||
*obj_id = current_id;
|
|
||||||
if(obj_length)
|
|
||||||
*obj_length = current_length;
|
|
||||||
|
|
||||||
if(i == index)
|
|
||||||
{
|
|
||||||
for(int j = 0; j < current_length; j++)
|
|
||||||
{
|
|
||||||
obj_data[j] = data[ind++];
|
|
||||||
}
|
|
||||||
obj_data[current_length] = '\0'; // добавляем \0
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Пропускаем данные этого объекта
|
|
||||||
ind += current_length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Получить данные диагностики из сообщения (MbData[1])
|
|
||||||
* @param modbus_msg Указатель на структуру сообщения
|
|
||||||
* @param data Указатель куда положить данные
|
|
||||||
* @return 1 - успех, 0 - ошибка
|
|
||||||
*/
|
|
||||||
int MB_RespGet_Diagnostic(RS_MsgTypeDef *modbus_msg, uint16_t *data)
|
|
||||||
{
|
|
||||||
if(modbus_msg == NULL || data == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Проверяем что ответ связан с диагностикой
|
|
||||||
if(modbus_msg->FuncCode != FC_R_DIAGNOSTICS)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*data = modbus_msg->MbData[1];
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Определить размер модбас запроса (МАСТЕР версия).
|
* @brief Определить размер модбас запроса (МАСТЕР версия).
|
||||||
* @param hRS Указатель на хендлер RS.
|
* @param hRS Указатель на хендлер RS.
|
||||||
@@ -264,24 +67,24 @@ static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *
|
|||||||
|
|
||||||
|
|
||||||
// Master mode - calculating response size from slave
|
// Master mode - calculating response size from slave
|
||||||
if (modbus_msg->FuncCode & FC_ERR_VALUES_START)
|
if (modbus_msg->Func_Code & ERR_VALUES_START)
|
||||||
{
|
{
|
||||||
// Error response: [Addr][Func|0x80][ExceptCode][CRC]
|
// Error response: [Addr][Func|0x80][ExceptCode][CRC]
|
||||||
mb_func_size = -1; // Only Exception Code
|
mb_func_size = -1; // Only Exception Code
|
||||||
}
|
}
|
||||||
else if (modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
else if (modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||||
{
|
{
|
||||||
// Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
// Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||||||
mb_func_size = 1;
|
mb_func_size = 1;
|
||||||
}
|
}
|
||||||
else if (modbus_msg->FuncCode == FC_R_DEVICE_ID)
|
else if (modbus_msg->Func_Code == MB_R_DEVICE_INFO)
|
||||||
{
|
{
|
||||||
// Device identifications: variable size, need to read first to determine
|
// Device identifications: variable size, need to read first to determine
|
||||||
mb_func_size = 0; // Will be determined after reading header
|
mb_func_size = 0; // Will be determined after reading header
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (modbus_msg->FuncCode & ~FC_ERR_VALUES_START)
|
switch (modbus_msg->Func_Code & ~ERR_VALUES_START)
|
||||||
{
|
{
|
||||||
case 0x01: // Read Coils
|
case 0x01: // Read Coils
|
||||||
case 0x02: // Read Discrete Inputs
|
case 0x02: // Read Discrete Inputs
|
||||||
@@ -329,30 +132,25 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
|
|||||||
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
||||||
|
|
||||||
// set function code
|
// set function code
|
||||||
modbus_uart_buff[ind++] = modbus_msg->FuncCode;
|
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
|
||||||
|
|
||||||
if(modbus_msg->FuncCode < FC_ERR_VALUES_START) // if no error occur
|
if(modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
|
||||||
{
|
{
|
||||||
// fill modbus header
|
// fill modbus header
|
||||||
if(0) {}
|
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // device identifications request
|
||||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
|
||||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // device identifications request
|
|
||||||
{
|
{
|
||||||
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
||||||
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
||||||
modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId;
|
modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId;
|
||||||
}
|
}
|
||||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
|
||||||
{
|
{
|
||||||
// Diagnostics: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
// Diagnostics: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbData[0] >> 8; // Sub-function HI
|
modbus_uart_buff[ind++] = modbus_msg->DATA[0] >> 8; // Sub-function HI
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbData[0] & 0xFF; // Sub-function LO
|
modbus_uart_buff[ind++] = modbus_msg->DATA[0] & 0xFF; // Sub-function LO
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbData[1] >> 8; // Data HI
|
modbus_uart_buff[ind++] = modbus_msg->DATA[1] >> 8; // Data HI
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbData[1] & 0xFF; // Data LO
|
modbus_uart_buff[ind++] = modbus_msg->DATA[1] & 0xFF; // Data LO
|
||||||
}
|
}
|
||||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
else // classic modbus request
|
else // classic modbus request
|
||||||
{
|
{
|
||||||
// set address
|
// set address
|
||||||
@@ -364,12 +162,12 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
|
|||||||
modbus_uart_buff[ind++] = modbus_msg->Qnt & 0xFF;
|
modbus_uart_buff[ind++] = modbus_msg->Qnt & 0xFF;
|
||||||
|
|
||||||
// for write multiple functions
|
// for write multiple functions
|
||||||
if((modbus_msg->FuncCode == 0x0F) || (modbus_msg->FuncCode == 0x10))
|
if((modbus_msg->Func_Code == 0x0F) || (modbus_msg->Func_Code == 0x10))
|
||||||
{
|
{
|
||||||
modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
|
modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
|
||||||
|
|
||||||
// write data bytes
|
// write data bytes
|
||||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->MbData;
|
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||||||
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
||||||
{
|
{
|
||||||
modbus_uart_buff[ind++] = tmp_data_addr[i];
|
modbus_uart_buff[ind++] = tmp_data_addr[i];
|
||||||
@@ -384,7 +182,7 @@ RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgType
|
|||||||
//---------------CRC----------------
|
//---------------CRC----------------
|
||||||
//---------[last 2 bytes]----------
|
//---------[last 2 bytes]----------
|
||||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||||
modbus_msg->MbCRC = CRC_VALUE;
|
modbus_msg->MB_CRC = CRC_VALUE;
|
||||||
modbus_uart_buff[ind++] = CRC_VALUE & 0xFF;
|
modbus_uart_buff[ind++] = CRC_VALUE & 0xFF;
|
||||||
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
||||||
|
|
||||||
@@ -409,17 +207,15 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
|||||||
modbus_msg->MbAddr = modbus_uart_buff[ind++];
|
modbus_msg->MbAddr = modbus_uart_buff[ind++];
|
||||||
|
|
||||||
// get function code (check if error response)
|
// get function code (check if error response)
|
||||||
modbus_msg->FuncCode = modbus_uart_buff[ind++];
|
modbus_msg->Func_Code = modbus_uart_buff[ind++];
|
||||||
|
|
||||||
if(modbus_msg->FuncCode & FC_ERR_VALUES_START) // error response
|
if(modbus_msg->Func_Code & ERR_VALUES_START) // error response
|
||||||
{
|
{
|
||||||
modbus_msg->Except_Code = modbus_uart_buff[ind++];
|
modbus_msg->Except_Code = modbus_uart_buff[ind++];
|
||||||
}
|
}
|
||||||
else if(modbus_msg->FuncCode < FC_ERR_VALUES_START) // normal response
|
else if(modbus_msg->Func_Code < ERR_VALUES_START) // normal response
|
||||||
{
|
{
|
||||||
if(0) {}
|
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // device identifications response
|
||||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
|
||||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // device identifications response
|
|
||||||
{
|
{
|
||||||
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
||||||
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
||||||
@@ -431,7 +227,7 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
|||||||
modbus_msg->ByteCnt = 0;
|
modbus_msg->ByteCnt = 0;
|
||||||
|
|
||||||
// Парсинг объектов идентификации устройства
|
// Парсинг объектов идентификации устройства
|
||||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->MbData;
|
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||||||
int data_index = 0;
|
int data_index = 0;
|
||||||
|
|
||||||
for(int obj = 0; obj < modbus_msg->DevId.NumbOfObj; obj++)
|
for(int obj = 0; obj < modbus_msg->DevId.NumbOfObj; obj++)
|
||||||
@@ -453,27 +249,24 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
|||||||
modbus_msg->ByteCnt += (2 + object_length); // ID + длина + данные
|
modbus_msg->ByteCnt += (2 + object_length); // ID + длина + данные
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
|
||||||
{
|
{
|
||||||
// Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
// Diagnostics response: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||||||
modbus_msg->MbData[0] = modbus_uart_buff[ind++] << 8;
|
modbus_msg->DATA[0] = modbus_uart_buff[ind++] << 8;
|
||||||
modbus_msg->MbData[0] |= modbus_uart_buff[ind++];
|
modbus_msg->DATA[0] |= modbus_uart_buff[ind++];
|
||||||
modbus_msg->MbData[1] = modbus_uart_buff[ind++] << 8;
|
modbus_msg->DATA[1] = modbus_uart_buff[ind++] << 8;
|
||||||
modbus_msg->MbData[1] |= modbus_uart_buff[ind++];
|
modbus_msg->DATA[1] |= modbus_uart_buff[ind++];
|
||||||
}
|
}
|
||||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
else // classic modbus response
|
else // classic modbus response
|
||||||
{
|
{
|
||||||
// get byte count for read functions
|
// get byte count for read functions
|
||||||
if((modbus_msg->FuncCode == 0x01) || (modbus_msg->FuncCode == 0x02) ||
|
if((modbus_msg->Func_Code == 0x01) || (modbus_msg->Func_Code == 0x02) ||
|
||||||
(modbus_msg->FuncCode == 0x03) || (modbus_msg->FuncCode == 0x04))
|
(modbus_msg->Func_Code == 0x03) || (modbus_msg->Func_Code == 0x04))
|
||||||
{
|
{
|
||||||
modbus_msg->ByteCnt = modbus_uart_buff[ind++];
|
modbus_msg->ByteCnt = modbus_uart_buff[ind++];
|
||||||
|
|
||||||
// read data bytes
|
// read data bytes
|
||||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
|
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||||
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
||||||
{
|
{
|
||||||
if(i % 2 == 0) // HI byte
|
if(i % 2 == 0) // HI byte
|
||||||
@@ -483,8 +276,8 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// for write functions - echo address and quantity
|
// for write functions - echo address and quantity
|
||||||
else if((modbus_msg->FuncCode == 0x05) || (modbus_msg->FuncCode == 0x06) ||
|
else if((modbus_msg->Func_Code == 0x05) || (modbus_msg->Func_Code == 0x06) ||
|
||||||
(modbus_msg->FuncCode == 0x0F) || (modbus_msg->FuncCode == 0x10))
|
(modbus_msg->Func_Code == 0x0F) || (modbus_msg->Func_Code == 0x10))
|
||||||
{
|
{
|
||||||
modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
|
modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
|
||||||
modbus_msg->Addr |= modbus_uart_buff[ind++];
|
modbus_msg->Addr |= modbus_uart_buff[ind++];
|
||||||
@@ -498,10 +291,10 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
|||||||
//---------------CRC----------------
|
//---------------CRC----------------
|
||||||
//----------[last 2 bytes]----------
|
//----------[last 2 bytes]----------
|
||||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||||
modbus_msg->MbCRC = modbus_uart_buff[ind++];
|
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
|
||||||
modbus_msg->MbCRC |= modbus_uart_buff[ind++] << 8;
|
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
|
||||||
|
|
||||||
if(modbus_msg->MbCRC != CRC_VALUE)
|
if(modbus_msg->MB_CRC != CRC_VALUE)
|
||||||
{
|
{
|
||||||
TrackerCnt_Err(hmodbus->rs_err);
|
TrackerCnt_Err(hmodbus->rs_err);
|
||||||
return RS_PARSE_MSG_ERR;
|
return RS_PARSE_MSG_ERR;
|
||||||
@@ -517,58 +310,58 @@ RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDe
|
|||||||
/** @brief Сформировать запрос на чтение коилов */
|
/** @brief Сформировать запрос на чтение коилов */
|
||||||
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Сформировать запрос на чтение дискретных регистров */
|
/** @brief Сформировать запрос на чтение дискретных регистров */
|
||||||
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DISC_IN, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_DISC_IN, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Сформировать запрос на чтение холдинг регистров */
|
/** @brief Сформировать запрос на чтение холдинг регистров */
|
||||||
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Сформировать запрос на чтение инпут регистров */
|
/** @brief Сформировать запрос на чтение инпут регистров */
|
||||||
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_IN_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_IN_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Сформировать запрос на запись одного коила */
|
/** @brief Сформировать запрос на запись одного коила */
|
||||||
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value)
|
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_W_COIL, {0}, coil_addr, (value ? 0xFF00 : 0x0000), 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_W_COIL, {0}, coil_addr, (value ? 0xFF00 : 0x0000), 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Сформировать запрос на запись одного регистра */
|
/** @brief Сформировать запрос на запись одного регистра */
|
||||||
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value)
|
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_W_HOLD_REG, {0}, reg_addr, value, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REG, {0}, reg_addr, value, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Сформировать запрос на запись нескольких регистров */
|
/** @brief Сформировать запрос на запись нескольких регистров */
|
||||||
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data)
|
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_W_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_W_COILS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||||
|
|
||||||
// Calculate byte count and prepare data
|
// Calculate byte count and prepare data
|
||||||
uint8_t byte_count = (quantity + 7) / 8;
|
uint8_t byte_count = (quantity + 7) / 8;
|
||||||
msg.ByteCnt = byte_count;
|
msg.ByteCnt = byte_count;
|
||||||
|
|
||||||
// Copy coil data to message MbData array
|
// Copy coil data to message DATA array
|
||||||
for(int i = 0; i < byte_count; i++) {
|
for(int i = 0; i < byte_count; i++) {
|
||||||
if(i < DATA_SIZE) {
|
if(i < DATA_SIZE) {
|
||||||
msg.MbData[i] = coils_data[i];
|
msg.DATA[i] = coils_data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,13 +371,13 @@ RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start
|
|||||||
/** @brief Сформировать запрос на запись нескольких коилов */
|
/** @brief Сформировать запрос на запись нескольких коилов */
|
||||||
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data)
|
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_W_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_W_HOLD_REGS, {0}, start_addr, quantity, 0, {0}, 0, 0};
|
||||||
|
|
||||||
msg.ByteCnt = quantity * 2; // Each register is 2 bytes
|
msg.ByteCnt = quantity * 2; // Each register is 2 bytes
|
||||||
|
|
||||||
// Copy register data to message MbData array
|
// Copy register data to message DATA array
|
||||||
for(int i = 0; i < quantity && i < DATA_SIZE; i++) {
|
for(int i = 0; i < quantity && i < DATA_SIZE; i++) {
|
||||||
msg.MbData[i] = regs_data[i];
|
msg.DATA[i] = regs_data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
@@ -593,7 +386,7 @@ RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_
|
|||||||
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
|
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
|
||||||
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data)
|
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DIAGNOSTICS, {0}, 0, 0, 0, {sub_function, data}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_DIAGNOSTIC, {0}, 0, 0, 0, {sub_function, data}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr)
|
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr)
|
||||||
@@ -664,26 +457,71 @@ RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr)
|
|||||||
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
|
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
|
||||||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr)
|
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DEVICE_ID, {0x0E, 0x01, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x01, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr)
|
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DEVICE_ID, {0x0E, 0x02, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x02, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr)
|
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DEVICE_ID, {0x0E, 0x03, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x03, 0x00, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id)
|
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id)
|
||||||
{
|
{
|
||||||
RS_MsgTypeDef msg = {slave_addr, FC_R_DEVICE_ID, {0x0E, 0x04, object_id, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
RS_MsgTypeDef msg = {slave_addr, MB_R_DEVICE_INFO, {0x0E, 0x04, object_id, 0, 0, 0}, 0, 0, 0, {0}, 0, 0};
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //MODBUS_ENABLE_MASTER
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
RS_MsgTypeDef msg_dummy = {0};
|
||||||
|
|
||||||
|
int MB_RespGet_RegisterValue(RS_MsgTypeDef *modbus_msg, uint16_t reg_addr, uint16_t *reg_value) {return 0;}
|
||||||
|
|
||||||
|
RS_MsgTypeDef MB_REQUEST_READ_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_READ_DISCRETE_INPUTS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_READ_HOLDING_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_READ_INPUT_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_COIL(uint8_t slave_addr, uint16_t coil_addr, uint8_t value) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_WRITE_SINGLE_REG(uint8_t slave_addr, uint16_t reg_addr, uint16_t value) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_COILS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint8_t *coils_data) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_WRITE_MULTIPLE_REGS(uint8_t slave_addr, uint16_t start_addr, uint16_t quantity, uint16_t *regs_data) {return msg_dummy;}
|
||||||
|
|
||||||
|
//---------ДИАГНОСТИЧЕСКИЕ ДАННЫЕ-----------
|
||||||
|
RS_MsgTypeDef MB_REQUEST_DIAGNOSTIC_QUERY(uint8_t slave_addr, uint16_t sub_function, uint16_t data) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_QUERY_DATA(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RESTART_COMMUNICATIONS(uint8_t slave_addr, uint16_t data) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_DIAGNOSTIC_REGISTER(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_FORCE_LISTEN_ONLY_MODE(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_CLEAR_COUNTERS_AND_DIAGNOSTIC_REGISTER(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_MESSAGE_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_COMMUNICATION_ERROR_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_EXCEPTION_ERROR_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_MESSAGE_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NO_RESPONSE_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_NAK_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_SLAVE_BUSY_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_RETURN_BUS_CHARACTER_OVERRUN_COUNT(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
|
||||||
|
//---------ИДЕНТИФИКАТОРЫ МОДБАС-----------
|
||||||
|
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_BASIC(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_REGULAR(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_EXTENDED(uint8_t slave_addr) {return msg_dummy;}
|
||||||
|
RS_MsgTypeDef MB_REQUEST_READ_DEVICE_ID_SPECIFIC(uint8_t slave_addr, uint8_t object_id) {return msg_dummy;}
|
||||||
|
|
||||||
|
RS_StatusTypeDef MB_Master_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
|
||||||
|
RS_StatusTypeDef MB_Master_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -37,26 +37,26 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
|||||||
}
|
}
|
||||||
MB_Diagnostics_SlaveMessageCnt();
|
MB_Diagnostics_SlaveMessageCnt();
|
||||||
|
|
||||||
if(modbus_msg->FuncCode < FC_ERR_VALUES_START)// if no errors after parsing
|
if(modbus_msg->Func_Code < ERR_VALUES_START)// if no errors after parsing
|
||||||
{
|
{
|
||||||
switch (modbus_msg->FuncCode)
|
switch (modbus_msg->Func_Code)
|
||||||
{
|
{
|
||||||
// Read Coils
|
// Read Coils
|
||||||
case FC_R_COILS:
|
case MB_R_COILS:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Read_Coils(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Read_Coils(hmodbus->pMessagePtr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Read Hodling Registers
|
// Read Hodling Registers
|
||||||
case FC_R_HOLD_REGS:
|
case MB_R_HOLD_REGS:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Read_Hold_Regs(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Read_Hold_Regs(hmodbus->pMessagePtr);
|
||||||
break;
|
break;
|
||||||
case FC_R_IN_REGS:
|
case MB_R_IN_REGS:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Read_Input_Regs(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Read_Input_Regs(hmodbus->pMessagePtr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
// Write Single Coils
|
// Write Single Coils
|
||||||
case FC_W_COIL:
|
case MB_W_COIL:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Write_Single_Coil(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Write_Single_Coil(hmodbus->pMessagePtr);
|
||||||
if(hmodbus->f.MessageHandled)
|
if(hmodbus->f.MessageHandled)
|
||||||
{
|
{
|
||||||
@@ -66,7 +66,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FC_W_HOLD_REG:
|
case MB_W_HOLD_REG:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Write_Single_Reg(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Write_Single_Reg(hmodbus->pMessagePtr);
|
||||||
if(hmodbus->f.MessageHandled)
|
if(hmodbus->f.MessageHandled)
|
||||||
{
|
{
|
||||||
@@ -77,7 +77,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Write Multiple Coils
|
// Write Multiple Coils
|
||||||
case FC_W_COILS:
|
case MB_W_COILS:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Coils(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Coils(hmodbus->pMessagePtr);
|
||||||
if(hmodbus->f.MessageHandled)
|
if(hmodbus->f.MessageHandled)
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Write Multiple Registers
|
// Write Multiple Registers
|
||||||
case FC_W_HOLD_REGS:
|
case MB_W_HOLD_REGS:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Regs(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Write_Miltuple_Regs(hmodbus->pMessagePtr);
|
||||||
if(hmodbus->f.MessageHandled)
|
if(hmodbus->f.MessageHandled)
|
||||||
{
|
{
|
||||||
@@ -98,12 +98,12 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FC_R_DEVICE_ID:
|
case MB_R_DEVICE_INFO:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Read_Device_Identifications(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Read_Device_Identifications(hmodbus->pMessagePtr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Добавить в switch-case после других case:
|
// Добавить в switch-case после других case:
|
||||||
case FC_R_DIAGNOSTICS:
|
case MB_R_DIAGNOSTIC:
|
||||||
hmodbus->f.MessageHandled = MB_Process_Diagnostics(hmodbus->pMessagePtr);
|
hmodbus->f.MessageHandled = MB_Process_Diagnostics(hmodbus->pMessagePtr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *mod
|
|||||||
{
|
{
|
||||||
MB_Diagnostics_ExceptionErrorCnt();
|
MB_Diagnostics_ExceptionErrorCnt();
|
||||||
TrackerCnt_Warn(hmodbus->rs_err);
|
TrackerCnt_Warn(hmodbus->rs_err);
|
||||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -173,29 +173,17 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//------INFO ABOUT DATA/MESSAGE------
|
//------INFO ABOUT DATA/MESSAGE------
|
||||||
#ifdef MODBUS_PROTOCOL_TCP
|
|
||||||
modbus_uart_buff[ind++] = modbus_msg->TransactionID >> 8;
|
|
||||||
modbus_uart_buff[ind++] = modbus_msg->TransactionID& 0xFF;
|
|
||||||
|
|
||||||
modbus_uart_buff[ind++] = modbus_msg->ProtocolID >> 8;
|
|
||||||
modbus_uart_buff[ind++] = modbus_msg->ProtocolID& 0xFF;
|
|
||||||
|
|
||||||
modbus_uart_buff[ind++] = modbus_msg->PDULength >> 8;
|
|
||||||
modbus_uart_buff[ind++] = modbus_msg->PDULength& 0xFF;
|
|
||||||
#endif
|
|
||||||
//-----------[first bytes]-----------
|
//-----------[first bytes]-----------
|
||||||
// set ID of message/user
|
// set ID of message/user
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
||||||
|
|
||||||
// set dat or err response
|
// set dat or err response
|
||||||
modbus_uart_buff[ind++] = modbus_msg->FuncCode;
|
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
|
||||||
|
|
||||||
if (modbus_msg->FuncCode < FC_ERR_VALUES_START) // if no error occur
|
if (modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
|
||||||
{
|
{
|
||||||
// fill modbus header
|
// fill modbus header
|
||||||
if(0) {}
|
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // devide identifications header
|
||||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
|
||||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // devide identifications header
|
|
||||||
{
|
{
|
||||||
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
||||||
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
||||||
@@ -213,7 +201,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
|||||||
|
|
||||||
//---------------DATA----------------
|
//---------------DATA----------------
|
||||||
//-----------[data bytes]------------
|
//-----------[data bytes]------------
|
||||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->MbData;
|
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
||||||
{ // set data
|
{ // set data
|
||||||
modbus_uart_buff[ind++] = *tmp_data_addr;
|
modbus_uart_buff[ind++] = *tmp_data_addr;
|
||||||
@@ -221,17 +209,14 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
|
||||||
{
|
{
|
||||||
// Diagnostics special format: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
// Diagnostics special format: [SubFunc_HI][SubFunc_LO][Data_HI][Data_LO]
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbData[0] >> 8; // Sub-function HI
|
modbus_uart_buff[ind++] = modbus_msg->DATA[0] >> 8; // Sub-function HI
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbData[0] & 0xFF; // Sub-function LO
|
modbus_uart_buff[ind++] = modbus_msg->DATA[0] & 0xFF; // Sub-function LO
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbData[1] >> 8; // Data HI
|
modbus_uart_buff[ind++] = modbus_msg->DATA[1] >> 8; // Data HI
|
||||||
modbus_uart_buff[ind++] = modbus_msg->MbData[1] & 0xFF; // Data LO
|
modbus_uart_buff[ind++] = modbus_msg->DATA[1] & 0xFF; // Data LO
|
||||||
}
|
}
|
||||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
else // modbus data header
|
else // modbus data header
|
||||||
{
|
{
|
||||||
// set size of received data
|
// set size of received data
|
||||||
@@ -245,7 +230,7 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
|||||||
|
|
||||||
//---------------DATA----------------
|
//---------------DATA----------------
|
||||||
//-----------[data bytes]------------
|
//-----------[data bytes]------------
|
||||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
|
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
||||||
{ // set data
|
{ // set data
|
||||||
if (i%2 == 0) // HI byte
|
if (i%2 == 0) // HI byte
|
||||||
@@ -270,14 +255,12 @@ RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeD
|
|||||||
|
|
||||||
//---------------CRC----------------
|
//---------------CRC----------------
|
||||||
//---------[last 16 bytes]----------
|
//---------[last 16 bytes]----------
|
||||||
#ifndef MODBUS_PROTOCOL_TCP
|
|
||||||
// calc crc of received data
|
// calc crc of received data
|
||||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||||
// write crc to message structure and modbus-uart buffer
|
// write crc to message structure and modbus-uart buffer
|
||||||
modbus_msg->MbCRC = CRC_VALUE;
|
modbus_msg->MB_CRC = CRC_VALUE;
|
||||||
modbus_uart_buff[ind++] = CRC_VALUE;
|
modbus_uart_buff[ind++] = CRC_VALUE;
|
||||||
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
||||||
#endif
|
|
||||||
|
|
||||||
hmodbus->RS_Message_Size = ind;
|
hmodbus->RS_Message_Size = ind;
|
||||||
|
|
||||||
@@ -296,15 +279,15 @@ static int MB_Define_Size_of_Function(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *
|
|||||||
RS_StatusTypeDef MB_RES = 0;
|
RS_StatusTypeDef MB_RES = 0;
|
||||||
int mb_func_size = 0;
|
int mb_func_size = 0;
|
||||||
|
|
||||||
if (modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
if (modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||||
{
|
{
|
||||||
mb_func_size = 1;
|
mb_func_size = 1;
|
||||||
}
|
}
|
||||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID)
|
else if(modbus_msg->Func_Code == MB_R_DEVICE_INFO)
|
||||||
{
|
{
|
||||||
mb_func_size = 0;
|
mb_func_size = 0;
|
||||||
}
|
}
|
||||||
else if ((modbus_msg->FuncCode & ~FC_ERR_VALUES_START) < 0x0F)
|
else if ((modbus_msg->Func_Code & ~ERR_VALUES_START) < 0x0F)
|
||||||
{
|
{
|
||||||
mb_func_size = 1;
|
mb_func_size = 1;
|
||||||
}
|
}
|
||||||
@@ -334,16 +317,6 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
|||||||
hmodbus->f.RX_Continue = 0;
|
hmodbus->f.RX_Continue = 0;
|
||||||
int expected_size = 0;
|
int expected_size = 0;
|
||||||
//-----INFO ABOUT DATA/MESSAGE-------
|
//-----INFO ABOUT DATA/MESSAGE-------
|
||||||
#ifdef MODBUS_PROTOCOL_TCP
|
|
||||||
modbus_msg->TransactionID =modbus_uart_buff[ind++]<<8;
|
|
||||||
modbus_msg->TransactionID |=modbus_uart_buff[ind++];
|
|
||||||
|
|
||||||
modbus_msg->ProtocolID =modbus_uart_buff[ind++]<<8;
|
|
||||||
modbus_msg->ProtocolID |=modbus_uart_buff[ind++];
|
|
||||||
|
|
||||||
modbus_msg->PDULength =modbus_uart_buff[ind++]<<8;
|
|
||||||
modbus_msg->PDULength |=modbus_uart_buff[ind++];
|
|
||||||
#endif
|
|
||||||
//-----------[first bits]------------
|
//-----------[first bits]------------
|
||||||
// get ID of message/user
|
// get ID of message/user
|
||||||
if(modbus_uart_buff[ind] != hmodbus->ID)
|
if(modbus_uart_buff[ind] != hmodbus->ID)
|
||||||
@@ -357,38 +330,33 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get func code
|
// get func code
|
||||||
modbus_msg->FuncCode = modbus_uart_buff[ind++];
|
modbus_msg->Func_Code = modbus_uart_buff[ind++];
|
||||||
if(modbus_msg->FuncCode & FC_ERR_VALUES_START) // явная херня
|
if(modbus_msg->Func_Code & ERR_VALUES_START) // явная херня
|
||||||
{
|
{
|
||||||
MB_Diagnostics_SlaveNAKCnt();
|
MB_Diagnostics_SlaveNAKCnt();
|
||||||
modbus_msg->MbAddr = 0;
|
modbus_msg->MbAddr = 0;
|
||||||
return RS_SKIP;
|
return RS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0) {}
|
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // if it device identifications request
|
||||||
#ifdef MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
|
||||||
else if(modbus_msg->FuncCode == FC_R_DEVICE_ID) // if it device identifications request
|
|
||||||
{
|
{
|
||||||
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
||||||
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
||||||
modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
|
modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
|
||||||
modbus_msg->ByteCnt = 0;
|
modbus_msg->ByteCnt = 0;
|
||||||
}
|
}
|
||||||
#endif //MODBUS_ENABLE_DEVICE_IDENTIFICATIONS
|
else if(modbus_msg->Func_Code == MB_R_DIAGNOSTIC)
|
||||||
#ifdef MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
else if(modbus_msg->FuncCode == FC_R_DIAGNOSTICS)
|
|
||||||
{
|
{
|
||||||
// Diagnostics: читаем 4 байта в MbData[0] и MbData[1]
|
// Diagnostics: читаем 4 байта в DATA[0] и DATA[1]
|
||||||
// Sub-function
|
// Sub-function
|
||||||
modbus_msg->MbData[0] = modbus_uart_buff[ind++] << 8;
|
modbus_msg->DATA[0] = modbus_uart_buff[ind++] << 8;
|
||||||
modbus_msg->MbData[0] |= modbus_uart_buff[ind++];
|
modbus_msg->DATA[0] |= modbus_uart_buff[ind++];
|
||||||
// Data
|
// Data
|
||||||
modbus_msg->MbData[1] = modbus_uart_buff[ind++] << 8;
|
modbus_msg->DATA[1] = modbus_uart_buff[ind++] << 8;
|
||||||
modbus_msg->MbData[1] |= modbus_uart_buff[ind++];
|
modbus_msg->DATA[1] |= modbus_uart_buff[ind++];
|
||||||
modbus_msg->Addr = 0; // не использует Addr
|
modbus_msg->Addr = 0; // не использует Addr
|
||||||
modbus_msg->Qnt = 0; // не использует Qnt
|
modbus_msg->Qnt = 0; // не использует Qnt
|
||||||
}
|
}
|
||||||
#endif //MODBUS_ENABLE_DIAGNOSTICS
|
|
||||||
else // if its classic modbus request
|
else // if its classic modbus request
|
||||||
{
|
{
|
||||||
// get address from CMD
|
// get address from CMD
|
||||||
@@ -400,7 +368,7 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
|||||||
modbus_msg->Qnt |= modbus_uart_buff[ind++];
|
modbus_msg->Qnt |= modbus_uart_buff[ind++];
|
||||||
}
|
}
|
||||||
|
|
||||||
if((hmodbus->pMessagePtr->FuncCode == 0x0F) || (hmodbus->pMessagePtr->FuncCode == 0x10))
|
if((hmodbus->pMessagePtr->Func_Code == 0x0F) || (hmodbus->pMessagePtr->Func_Code == 0x10))
|
||||||
hmodbus->pMessagePtr->ByteCnt = modbus_uart_buff[ind++];
|
hmodbus->pMessagePtr->ByteCnt = modbus_uart_buff[ind++];
|
||||||
else
|
else
|
||||||
hmodbus->pMessagePtr->ByteCnt = 0;
|
hmodbus->pMessagePtr->ByteCnt = 0;
|
||||||
@@ -427,11 +395,11 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
|||||||
if (modbus_msg->ByteCnt > DATA_SIZE*2)
|
if (modbus_msg->ByteCnt > DATA_SIZE*2)
|
||||||
{
|
{
|
||||||
TrackerCnt_Err(hmodbus->rs_err);
|
TrackerCnt_Err(hmodbus->rs_err);
|
||||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||||
MB_Diagnostics_CommunicationErrorCnt();
|
MB_Diagnostics_CommunicationErrorCnt();
|
||||||
return RS_PARSE_MSG_ERR;
|
return RS_PARSE_MSG_ERR;
|
||||||
}
|
}
|
||||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->MbData;
|
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||||
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
for(int i = 0; i < modbus_msg->ByteCnt; i++)
|
||||||
{ // set data
|
{ // set data
|
||||||
if (i%2 == 0)
|
if (i%2 == 0)
|
||||||
@@ -446,22 +414,24 @@ RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef
|
|||||||
|
|
||||||
//---------------CRC----------------
|
//---------------CRC----------------
|
||||||
//----------[last 16 bits]----------
|
//----------[last 16 bits]----------
|
||||||
#ifndef MODBUS_PROTOCOL_TCP
|
|
||||||
// calc crc of received data
|
// calc crc of received data
|
||||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||||
// get crc of received data
|
// get crc of received data
|
||||||
modbus_msg->MbCRC = modbus_uart_buff[ind++];
|
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
|
||||||
modbus_msg->MbCRC |= modbus_uart_buff[ind++] << 8;
|
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
|
||||||
// compare crc
|
// compare crc
|
||||||
if (modbus_msg->MbCRC != CRC_VALUE)
|
if (modbus_msg->MB_CRC != CRC_VALUE)
|
||||||
{
|
{
|
||||||
MB_Diagnostics_CommunicationErrorCnt();
|
MB_Diagnostics_CommunicationErrorCnt();
|
||||||
TrackerCnt_Err(hmodbus->rs_err);
|
TrackerCnt_Err(hmodbus->rs_err);
|
||||||
modbus_msg->FuncCode |= FC_ERR_VALUES_START;
|
modbus_msg->Func_Code |= ERR_VALUES_START;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return RS_OK;
|
return RS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //MODBUS_ENABLE_SLAVE
|
#else // MODBUS_ENABLE_SLAVE
|
||||||
|
RS_StatusTypeDef MB_Slave_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg) {return RS_ERR;}
|
||||||
|
RS_StatusTypeDef MB_Slave_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
|
||||||
|
RS_StatusTypeDef MB_Slave_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff) {return RS_ERR;}
|
||||||
|
#endif
|
||||||
@@ -323,7 +323,6 @@ void RS_UART_Handler(RS_HandleTypeDef *hRS)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RS_UART_Handler_ENTER();
|
|
||||||
//-------------CHECK IDLE FLAG FIRST-------------
|
//-------------CHECK IDLE FLAG FIRST-------------
|
||||||
/* Проверяем флаг IDLE в первую очередь - это гарантирует обработку только после idle */
|
/* Проверяем флаг IDLE в первую очередь - это гарантирует обработку только после idle */
|
||||||
if(__HAL_UART_GET_FLAG(hRS->huart, UART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(hRS->huart, UART_IT_IDLE))
|
if(__HAL_UART_GET_FLAG(hRS->huart, UART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(hRS->huart, UART_IT_IDLE))
|
||||||
@@ -349,24 +348,22 @@ void RS_UART_Handler(RS_HandleTypeDef *hRS)
|
|||||||
RS_Set_RX_End(hRS);
|
RS_Set_RX_End(hRS);
|
||||||
|
|
||||||
// Парсим наше сообщение
|
// Парсим наше сообщение
|
||||||
hRS->RS_STATUS = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr);
|
RS_StatusTypeDef parse_res = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr);
|
||||||
|
|
||||||
// Если сообещине принято корректно
|
// Если сообещине принято корректно
|
||||||
if(hRS->RS_STATUS == RS_OK)
|
if(parse_res == RS_OK)
|
||||||
{
|
{
|
||||||
RS_Timeout_Stop(hRS);
|
RS_Timeout_Stop(hRS);
|
||||||
|
|
||||||
hRS->lastPacketTick = local_time();
|
hRS->lastPacketTick = uwTick;
|
||||||
if(hRS->sRS_Mode < RS_MASTER_MODE_START)
|
if(hRS->sRS_Mode < RS_MASTER_MODE_START)
|
||||||
{
|
|
||||||
RS_Response(hRS, hRS->pMessagePtr); // отвечаем на запрос
|
RS_Response(hRS, hRS->pMessagePtr); // отвечаем на запрос
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RS_Set_Free(hRS); // освобожднаем RS
|
|
||||||
if(hRS->pCallback)
|
if(hRS->pCallback)
|
||||||
{
|
{
|
||||||
hRS->pCallback(hRS, hRS->pMessagePtr); // обрабатываем ответ
|
hRS->pCallback(hRS, hRS->pMessagePtr); // обрабатываем ответ
|
||||||
|
RS_Set_Free(hRS); // освобожднаем RS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -420,7 +417,6 @@ void RS_UART_Handler(RS_HandleTypeDef *hRS)
|
|||||||
|
|
||||||
// later, maybe, will be added specific handlers for err
|
// later, maybe, will be added specific handlers for err
|
||||||
}
|
}
|
||||||
RS_UART_Handler_EXIT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -436,30 +432,20 @@ void RS_TIM_Handler(RS_HandleTypeDef *hRS)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RS_TIM_Handler_ENTER();
|
|
||||||
|
|
||||||
HAL_TIM_IRQHandler(hRS->htim);
|
HAL_TIM_IRQHandler(hRS->htim);
|
||||||
|
|
||||||
RS_Abort(hRS, ABORT_RS);
|
RS_Abort(hRS, ABORT_RS);
|
||||||
|
|
||||||
hRS->RS_STATUS = RS_TIMEOUT;
|
|
||||||
|
|
||||||
if(hRS->sRS_Mode < RS_MASTER_MODE_START)
|
|
||||||
if(hRS->pMessagePtr->MbAddr == hRS->ID) // ошибка если таймаут по нашему сообщению
|
if(hRS->pMessagePtr->MbAddr == hRS->ID) // ошибка если таймаут по нашему сообщению
|
||||||
TrackerCnt_Err(hRS->rs_err);
|
TrackerCnt_Err(hRS->rs_err);
|
||||||
|
|
||||||
if(hRS->sRS_Mode >= RS_MASTER_MODE_START)
|
if(hRS->sRS_Mode == RS_MASTER_REQUEST) {
|
||||||
{ // Мастер: коллбек и освобождение для нового запроса
|
// Мастер: таймаут ответа -> освобождаем для нового запроса
|
||||||
RS_Set_Free(hRS);
|
RS_Set_Free(hRS);
|
||||||
if(hRS->pCallback)
|
|
||||||
{
|
|
||||||
hRS->pCallback(hRS, hRS->pMessagePtr); // обрабатываем ответ
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Слейв: перезапускаем прием
|
// Слейв: перезапускаем прием
|
||||||
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||||
}
|
}
|
||||||
RS_TIM_Handler_EXIT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
137
README.md
137
README.md
@@ -1,64 +1,17 @@
|
|||||||
# Инструкция по подключению релиза библиотеки `STM Modbus`
|
# STM Modbus: подключение и использование
|
||||||
|
|
||||||
Данная библиотека подключается напрямую из Git, как субмодуль. Позволяя при желании обновлять её напрямую через git.
|
Библиотека реализует Modbus RTU Slave для STM32 с использованием HAL. Работает в прерываниях с детектированием конца фрейма по IDLE линии и таймаутами через прерывание таймера.
|
||||||
|
|
||||||
## Структура библиотеки
|
## Быстрый старт
|
||||||
|
_Note: Здесь описано подключение просто архива c исходниками. Если надо подключить библиотеку как субмодуль: см. ветку **release** в этом репозитории._
|
||||||
|
|
||||||
*Note: Файлы начинающиеся с `__` и которых **нет** в этом дереве являются **внутренними/непротестированными/недокументированными***
|
### 1. Настройка периферии
|
||||||
```
|
|
||||||
Modbus/ Иерархия модулей:
|
|
||||||
│ inc/ modbus
|
|
||||||
│ ├── modbus.h # Главный заголовочный файл modbus_slave
|
|
||||||
│ ├── modbus_core.h # Базовые определения и структуры modbus_master
|
|
||||||
│ ├── modbus_coils.h # Работа с дискретными выходами ├── modbus_coils
|
|
||||||
│ ├── modbus_holdregs.h # Работа с регистрами хранения ├── modbus_inputregs
|
|
||||||
│ ├── modbus_inputregs.h # Работа с входными регистрами ├── modbus_inputregs
|
|
||||||
│ ├── modbus_devid.h # Идентификация устройства ├── modbus_devid
|
|
||||||
│ ├── rs_message.h # Драйвер обмена по RS/UART ├── modbus_diag
|
|
||||||
├── src/ └── rs_message
|
|
||||||
│ ├── modbus.c # Основная логика Modbus │
|
|
||||||
│ ├── modbus_slave.c # Основная логика Slave Modbus └── modbus_core (единое ядро)
|
|
||||||
│ ├── modbus_master.c # Основная логика Master Modbus ├── modbus_config
|
|
||||||
│ ├── modbus_coils.c # Реализация работы с coils ├── modbus_data
|
|
||||||
│ ├── modbus_holdregs.c # Реализация регистров хранения └── __crc_algs
|
|
||||||
│ ├── modbus_inputregs.c # Реализация входных регистров
|
|
||||||
│ ├── modbus_devid.c # Реализация идентификации устройства
|
|
||||||
│ ├── modbus_data.c # Функции доступа к данным
|
|
||||||
│ └── rs_message.c # Реализация драйвера RS
|
|
||||||
├── __modbus_config.h # Конфигурация Modbus (надо заменить)
|
|
||||||
├── __modbus_data.h # Структуры данных (надо заменить)
|
|
||||||
└── __modbus_data.c # Функции доступа (надо заменить)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Инструкция по подключению
|
|
||||||
|
|
||||||
1. **Склонируйте субмодуль** в ваш проект:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git submodule add https://git.arktika.cyou/set506/STM32_Modbus path/to/Modbus
|
|
||||||
git submodule update --init --recursive
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Скопируйте файлы конфигурации** в отдельную папку в вашем проекте (вне субмодуля) и удалите `__` из имени файлов:
|
|
||||||
|
|
||||||
```
|
|
||||||
ProjectRoot/
|
|
||||||
├── Configs/
|
|
||||||
│ ├── modbus_config.h # скопировать из __modbus_config.h
|
|
||||||
│ ├── modbus_data.h # скопировать из __modbus_data.h
|
|
||||||
│ └── modbus_data.c # скопировать из __modbus_data.c
|
|
||||||
└── Modbus/ # Субмодуль
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Настройте конфигурацию** под ваш проект:
|
|
||||||
|
|
||||||
3.1. Настройка периферии
|
|
||||||
|
|
||||||
- **UART**: Настройте в режиме Asynchronous, нужная скорость (9600, 19200, etc), 8N1
|
- **UART**: Настройте в режиме Asynchronous, нужная скорость (9600, 19200, etc), 8N1
|
||||||
- **TIM**: Настройте таймер для генерации прерываний (например, 1ms tick)
|
- **TIM**: Настройте таймер для генерации прерываний (например, 1ms tick)
|
||||||
- **Включите прерывания** для UART и TIM
|
- **Включите прерывания** для UART и TIM
|
||||||
|
|
||||||
3.2. Подключение обработчиков прерываний
|
### 2. Подключение обработчиков прерываний
|
||||||
|
|
||||||
Подключите обработчики прерываний **UART** и **TIM** в свои IRQ обработчики ***вместо*** HAL-обработчиков:
|
Подключите обработчики прерываний **UART** и **TIM** в свои IRQ обработчики ***вместо*** HAL-обработчиков:
|
||||||
|
|
||||||
@@ -80,9 +33,42 @@ ProjectRoot/
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
3.3. В `modbus_config.h` укажите параметры устройства
|
### 3. Настройка конфигурации
|
||||||
|
|
||||||
3.4. Инициализация в коде
|
В `modbus_config.h` укажите параметры устройства:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// MODBUS PARAMS
|
||||||
|
#define MODBUS_DEVICE_ID 1 ///< Адрес устройства в сети Modbus
|
||||||
|
#define MODBUS_TIMEOUT 5000 ///< Таймаут в тиках таймера
|
||||||
|
|
||||||
|
// Строковые идентификаторы устройства
|
||||||
|
#define MODBUS_VENDOR_NAME "NIO-12"
|
||||||
|
#define MODBUS_PRODUCT_CODE ""
|
||||||
|
#define MODBUS_REVISION "Ver. 1.0"
|
||||||
|
#define MODBUS_VENDOR_URL ""
|
||||||
|
#define MODBUS_PRODUCT_NAME ""
|
||||||
|
#define MODBUS_MODEL_NAME "STM32F103"
|
||||||
|
#define MODBUS_USER_APPLICATION_NAME ""
|
||||||
|
#define MODBUS_NUMB_OF_USEROBJECTS 0
|
||||||
|
|
||||||
|
// Периферия
|
||||||
|
#define mb_huart huart1 // Удобный дефайн для модбасовского UART
|
||||||
|
#define mb_htim htim3 // Удобный дефайн для модбасовского таймера
|
||||||
|
|
||||||
|
// Модули modbus
|
||||||
|
#define MODBUS_ENABLE_SLAVE ///< Включить обработку МАСТЕР режима
|
||||||
|
//#define MODBUS_ENABLE_MASTER ///< Включить обработку СЛЕЙВ режима
|
||||||
|
|
||||||
|
#define MODBUS_ENABLE_COILS ///< Включить обработку коилов
|
||||||
|
#define MODBUS_ENABLE_HOLDINGS ///< Включить обработку регистров хранения
|
||||||
|
#define MODBUS_ENABLE_INPUTS ///< Включить обработку входных регистров
|
||||||
|
#define MODBUS_ENABLE_DEVICE_IDENTIFICATIONS ///< Включить обработку идентификаторы устройства
|
||||||
|
#define MODBUS_ENABLE_DIAGNOSTICS ///< Включить обработку диагностики модбас
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Инициализация в коде
|
||||||
|
|
||||||
Чтобы настроить Slave-режим `main()` после инициализации HAL:
|
Чтобы настроить Slave-режим `main()` после инициализации HAL:
|
||||||
|
|
||||||
@@ -116,15 +102,13 @@ ProjectRoot/
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
#include "modbus.h"
|
#include "modbus.h"
|
||||||
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
|
||||||
RS_MsgTypeDef read_hold_cmd = MB_REQUEST_READ_HOLDING_REGS(1, 0, 10);
|
|
||||||
// коллбек, вызовется при получении ответа от слейва
|
|
||||||
read_hold[10];
|
read_hold[10];
|
||||||
|
// Запрос на 1 ID, считать холдинг регистры с 0 адреса 10 штук
|
||||||
|
RS_MsgTypeDef read_hold_cmd = MB_MASTER_READ_HOLDING_REGS(1, 0, 10);
|
||||||
|
// коллбек, вызовется при получении ответа от слейва
|
||||||
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
void callback_func(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||||||
{
|
{
|
||||||
// MB_RespGet_... Чтобы достать нужные данные из ответа
|
// MB_RespGet_... Чтобы достать нужные данные из ответа
|
||||||
if(hmodbus->RS_STATUS == RS_OK)
|
|
||||||
{
|
|
||||||
for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
|
for(int addr = MODBUS_MSG.Addr; addr < MODBUS_MSG.Addr + MODBUS_MSG.Qnt; addr++)
|
||||||
{
|
{
|
||||||
uint16_t value;
|
uint16_t value;
|
||||||
@@ -134,7 +118,6 @@ ProjectRoot/
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// Инициализация HAL
|
// Инициализация HAL
|
||||||
@@ -153,11 +136,11 @@ ProjectRoot/
|
|||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
3.5. Настройка карты данных
|
### 5. Настройка карты данных
|
||||||
|
|
||||||
В `modbus_data.h` настройте регистры и coils под ваше устройство:
|
В `modbus_data.h` настройте регистры и coils под ваше устройство:
|
||||||
|
|
||||||
**Input Registers (только чтение)**
|
#### Input Registers (только чтение)
|
||||||
```c
|
```c
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -171,7 +154,7 @@ ProjectRoot/
|
|||||||
#define R_INPUT_QNT 4 // Количество Input регистров
|
#define R_INPUT_QNT 4 // Количество Input регистров
|
||||||
```
|
```
|
||||||
|
|
||||||
**Holding Registers (чтение/запись)**
|
#### Holding Registers (чтение/запись)
|
||||||
```c
|
```c
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -184,7 +167,7 @@ ProjectRoot/
|
|||||||
#define R_HOLDING_QNT 3 // Количество Holding регистров
|
#define R_HOLDING_QNT 3 // Количество Holding регистров
|
||||||
```
|
```
|
||||||
|
|
||||||
**Coils (1-битные)**
|
#### Coils (1-битные)
|
||||||
```c
|
```c
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -199,8 +182,7 @@ ProjectRoot/
|
|||||||
#define C_COILS_QNT 4 // Количество Coils
|
#define C_COILS_QNT 4 // Количество Coils
|
||||||
```
|
```
|
||||||
|
|
||||||
3.6. Доступ к данным в коде
|
### 6. Доступ к данным в коде
|
||||||
|
|
||||||
|
|
||||||
В режиме слейва есть дефайны для удобного выставления Коилов. На случай если они не упакованы в битовые поля
|
В режиме слейва есть дефайны для удобного выставления Коилов. На случай если они не упакованы в битовые поля
|
||||||
```c
|
```c
|
||||||
@@ -255,13 +237,16 @@ ProjectRoot/
|
|||||||
printf("First object - ID: 0x%02X, Data: %s\n", obj_id, obj_data);
|
printf("First object - ID: 0x%02X, Data: %s\n", obj_id, obj_data);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
## Поддерживаемые функции Modbus
|
||||||
|
|
||||||
|
| Функция | Код | Описание |
|
||||||
|
|---------|-----|-----------|
|
||||||
5. **Обновление библиотеки**:
|
| Read Coils | 0x01 | Чтение дискретных выходов |
|
||||||
|
| Read Input Registers | 0x04 | Чтение входных регистров |
|
||||||
После обновления субмодуля из Git, исходные файлы библиотеки будут обновлены, и ваши конфиги вне субмодуля не перезапишутся:
|
| Read Holding Registers | 0x03 | Чтение регистров хранения |
|
||||||
|
| Write Single Coil | 0x05 | Запись одиночного coil |
|
||||||
```bash
|
| Write Single Register | 0x06 | Запись одиночного регистра |
|
||||||
git submodule update --remote
|
| Diagnostics (Serial Line only) | 0x08 | Чтение диагностически и управление режимом работы |
|
||||||
```
|
| Write Multiple Coils | 0x0F | Запись множественных coils |
|
||||||
|
| Write Multiple Registers | 0x10 | Запись множественных регистров |
|
||||||
|
| Read Device Identification | 0x2B | Чтение идентификации устройства |
|
||||||
|
|||||||
36
STM32F103_Example/.mxproject
Normal file
36
STM32F103_Example/.mxproject
Normal file
File diff suppressed because one or more lines are too long
49
STM32F103_Example/Core/Inc/gpio.h
Normal file
49
STM32F103_Example/Core/Inc/gpio.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file gpio.h
|
||||||
|
* @brief This file contains all the function prototypes for
|
||||||
|
* the gpio.c file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __GPIO_H__
|
||||||
|
#define __GPIO_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Private defines */
|
||||||
|
|
||||||
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
|
void MX_GPIO_Init(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Prototypes */
|
||||||
|
|
||||||
|
/* USER CODE END Prototypes */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /*__ GPIO_H__ */
|
||||||
|
|
||||||
69
STM32F103_Example/Core/Inc/main.h
Normal file
69
STM32F103_Example/Core/Inc/main.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : main.h
|
||||||
|
* @brief : Header for main.c file.
|
||||||
|
* This file contains the common defines of the application.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __MAIN_H
|
||||||
|
#define __MAIN_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
|
/* Private includes ----------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN ET */
|
||||||
|
|
||||||
|
/* USER CODE END ET */
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN EC */
|
||||||
|
|
||||||
|
/* USER CODE END EC */
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN EM */
|
||||||
|
|
||||||
|
/* USER CODE END EM */
|
||||||
|
|
||||||
|
/* Exported functions prototypes ---------------------------------------------*/
|
||||||
|
void Error_Handler(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN EFP */
|
||||||
|
|
||||||
|
/* USER CODE END EFP */
|
||||||
|
|
||||||
|
/* Private defines -----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Private defines */
|
||||||
|
|
||||||
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __MAIN_H */
|
||||||
391
STM32F103_Example/Core/Inc/stm32f1xx_hal_conf.h
Normal file
391
STM32F103_Example/Core/Inc/stm32f1xx_hal_conf.h
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f1xx_hal_conf.h
|
||||||
|
* @brief HAL configuration file.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F1xx_HAL_CONF_H
|
||||||
|
#define __STM32F1xx_HAL_CONF_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ########################## Module Selection ############################## */
|
||||||
|
/**
|
||||||
|
* @brief This is the list of modules to be used in the HAL driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define HAL_MODULE_ENABLED
|
||||||
|
/*#define HAL_ADC_MODULE_ENABLED */
|
||||||
|
/*#define HAL_CRYP_MODULE_ENABLED */
|
||||||
|
/*#define HAL_CAN_MODULE_ENABLED */
|
||||||
|
/*#define HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||||
|
/*#define HAL_CEC_MODULE_ENABLED */
|
||||||
|
/*#define HAL_CORTEX_MODULE_ENABLED */
|
||||||
|
/*#define HAL_CRC_MODULE_ENABLED */
|
||||||
|
/*#define HAL_DAC_MODULE_ENABLED */
|
||||||
|
/*#define HAL_DMA_MODULE_ENABLED */
|
||||||
|
/*#define HAL_ETH_MODULE_ENABLED */
|
||||||
|
/*#define HAL_FLASH_MODULE_ENABLED */
|
||||||
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
|
/*#define HAL_I2C_MODULE_ENABLED */
|
||||||
|
/*#define HAL_I2S_MODULE_ENABLED */
|
||||||
|
/*#define HAL_IRDA_MODULE_ENABLED */
|
||||||
|
/*#define HAL_IWDG_MODULE_ENABLED */
|
||||||
|
/*#define HAL_NOR_MODULE_ENABLED */
|
||||||
|
/*#define HAL_NAND_MODULE_ENABLED */
|
||||||
|
/*#define HAL_PCCARD_MODULE_ENABLED */
|
||||||
|
/*#define HAL_PCD_MODULE_ENABLED */
|
||||||
|
/*#define HAL_HCD_MODULE_ENABLED */
|
||||||
|
/*#define HAL_PWR_MODULE_ENABLED */
|
||||||
|
/*#define HAL_RCC_MODULE_ENABLED */
|
||||||
|
/*#define HAL_RTC_MODULE_ENABLED */
|
||||||
|
/*#define HAL_SD_MODULE_ENABLED */
|
||||||
|
/*#define HAL_MMC_MODULE_ENABLED */
|
||||||
|
/*#define HAL_SDRAM_MODULE_ENABLED */
|
||||||
|
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
||||||
|
/*#define HAL_SPI_MODULE_ENABLED */
|
||||||
|
/*#define HAL_SRAM_MODULE_ENABLED */
|
||||||
|
#define HAL_TIM_MODULE_ENABLED
|
||||||
|
#define HAL_UART_MODULE_ENABLED
|
||||||
|
/*#define HAL_USART_MODULE_ENABLED */
|
||||||
|
/*#define HAL_WWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#define HAL_CORTEX_MODULE_ENABLED
|
||||||
|
#define HAL_DMA_MODULE_ENABLED
|
||||||
|
#define HAL_FLASH_MODULE_ENABLED
|
||||||
|
#define HAL_EXTI_MODULE_ENABLED
|
||||||
|
#define HAL_GPIO_MODULE_ENABLED
|
||||||
|
#define HAL_PWR_MODULE_ENABLED
|
||||||
|
#define HAL_RCC_MODULE_ENABLED
|
||||||
|
|
||||||
|
/* ########################## Oscillator Values adaptation ####################*/
|
||||||
|
/**
|
||||||
|
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||||
|
* This value is used by the RCC HAL module to compute the system frequency
|
||||||
|
* (when HSE is used as system clock source, directly or through the PLL).
|
||||||
|
*/
|
||||||
|
#if !defined (HSE_VALUE)
|
||||||
|
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
|
||||||
|
#endif /* HSE_VALUE */
|
||||||
|
|
||||||
|
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||||
|
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||||
|
#endif /* HSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal High Speed oscillator (HSI) value.
|
||||||
|
* This value is used by the RCC HAL module to compute the system frequency
|
||||||
|
* (when HSI is used as system clock source, directly or through the PLL).
|
||||||
|
*/
|
||||||
|
#if !defined (HSI_VALUE)
|
||||||
|
#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz*/
|
||||||
|
#endif /* HSI_VALUE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal Low Speed oscillator (LSI) value.
|
||||||
|
*/
|
||||||
|
#if !defined (LSI_VALUE)
|
||||||
|
#define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */
|
||||||
|
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||||
|
The real value may vary depending on the variations
|
||||||
|
in voltage and temperature. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief External Low Speed oscillator (LSE) value.
|
||||||
|
* This value is used by the UART, RTC HAL module to compute the system frequency
|
||||||
|
*/
|
||||||
|
#if !defined (LSE_VALUE)
|
||||||
|
#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/
|
||||||
|
#endif /* LSE_VALUE */
|
||||||
|
|
||||||
|
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||||
|
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||||
|
#endif /* LSE_STARTUP_TIMEOUT */
|
||||||
|
|
||||||
|
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||||
|
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||||
|
|
||||||
|
/* ########################### System Configuration ######################### */
|
||||||
|
/**
|
||||||
|
* @brief This is the HAL system configuration section
|
||||||
|
*/
|
||||||
|
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||||
|
#define TICK_INT_PRIORITY 15U /*!< tick interrupt priority (lowest by default) */
|
||||||
|
#define USE_RTOS 0U
|
||||||
|
#define PREFETCH_ENABLE 1U
|
||||||
|
|
||||||
|
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||||
|
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||||
|
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||||
|
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||||
|
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||||
|
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||||
|
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||||
|
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||||
|
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||||
|
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||||
|
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||||
|
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
|
||||||
|
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||||
|
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||||
|
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||||
|
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||||
|
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||||
|
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||||
|
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||||
|
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||||
|
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||||
|
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||||
|
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||||
|
|
||||||
|
/* ########################## Assert Selection ############################## */
|
||||||
|
/**
|
||||||
|
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||||
|
* HAL drivers code
|
||||||
|
*/
|
||||||
|
/* #define USE_FULL_ASSERT 1U */
|
||||||
|
|
||||||
|
/* ################## Ethernet peripheral configuration ##################### */
|
||||||
|
|
||||||
|
/* Section 1 : Ethernet peripheral configuration */
|
||||||
|
|
||||||
|
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||||
|
#define MAC_ADDR0 2U
|
||||||
|
#define MAC_ADDR1 0U
|
||||||
|
#define MAC_ADDR2 0U
|
||||||
|
#define MAC_ADDR3 0U
|
||||||
|
#define MAC_ADDR4 0U
|
||||||
|
#define MAC_ADDR5 0U
|
||||||
|
|
||||||
|
/* Definition of the Ethernet driver buffers size and count */
|
||||||
|
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||||
|
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||||
|
#define ETH_RXBUFNB 8U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||||
|
#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||||
|
|
||||||
|
/* Section 2: PHY configuration section */
|
||||||
|
|
||||||
|
/* DP83848_PHY_ADDRESS Address*/
|
||||||
|
#define DP83848_PHY_ADDRESS 0x01U
|
||||||
|
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||||
|
#define PHY_RESET_DELAY 0x000000FFU
|
||||||
|
/* PHY Configuration delay */
|
||||||
|
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||||
|
|
||||||
|
#define PHY_READ_TO 0x0000FFFFU
|
||||||
|
#define PHY_WRITE_TO 0x0000FFFFU
|
||||||
|
|
||||||
|
/* Section 3: Common PHY Registers */
|
||||||
|
|
||||||
|
#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
|
||||||
|
#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
|
||||||
|
|
||||||
|
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||||
|
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||||
|
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||||
|
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||||
|
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||||
|
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||||
|
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||||
|
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||||
|
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||||
|
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||||
|
|
||||||
|
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||||
|
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||||
|
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||||
|
|
||||||
|
/* Section 4: Extended PHY Registers */
|
||||||
|
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
|
||||||
|
|
||||||
|
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
|
||||||
|
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
|
||||||
|
|
||||||
|
/* ################## SPI peripheral configuration ########################## */
|
||||||
|
|
||||||
|
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||||
|
* Activated: CRC code is present inside driver
|
||||||
|
* Deactivated: CRC code cleaned from driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USE_SPI_CRC 0U
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief Include module's header file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAL_RCC_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_rcc.h"
|
||||||
|
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_gpio.h"
|
||||||
|
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_exti.h"
|
||||||
|
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DMA_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_dma.h"
|
||||||
|
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_ETH_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_eth.h"
|
||||||
|
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CAN_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_can.h"
|
||||||
|
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||||
|
#include "Legacy/stm32f1xx_hal_can_legacy.h"
|
||||||
|
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CEC_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_cec.h"
|
||||||
|
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_cortex.h"
|
||||||
|
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_ADC_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_adc.h"
|
||||||
|
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_CRC_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_crc.h"
|
||||||
|
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_DAC_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_dac.h"
|
||||||
|
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_flash.h"
|
||||||
|
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_sram.h"
|
||||||
|
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_NOR_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_nor.h"
|
||||||
|
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_I2C_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_i2c.h"
|
||||||
|
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_I2S_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_i2s.h"
|
||||||
|
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_iwdg.h"
|
||||||
|
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PWR_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_pwr.h"
|
||||||
|
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_RTC_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_rtc.h"
|
||||||
|
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_pccard.h"
|
||||||
|
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SD_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_sd.h"
|
||||||
|
#endif /* HAL_SD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_NAND_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_nand.h"
|
||||||
|
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SPI_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_spi.h"
|
||||||
|
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_TIM_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_tim.h"
|
||||||
|
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_UART_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_uart.h"
|
||||||
|
#endif /* HAL_UART_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_USART_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_usart.h"
|
||||||
|
#endif /* HAL_USART_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_irda.h"
|
||||||
|
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_smartcard.h"
|
||||||
|
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_wwdg.h"
|
||||||
|
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_PCD_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_pcd.h"
|
||||||
|
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_HCD_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_hcd.h"
|
||||||
|
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||||
|
|
||||||
|
#ifdef HAL_MMC_MODULE_ENABLED
|
||||||
|
#include "stm32f1xx_hal_mmc.h"
|
||||||
|
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
#ifdef USE_FULL_ASSERT
|
||||||
|
/**
|
||||||
|
* @brief The assert_param macro is used for function's parameters check.
|
||||||
|
* @param expr If expr is false, it calls assert_failed function
|
||||||
|
* which reports the name of the source file and the source
|
||||||
|
* line number of the call that failed.
|
||||||
|
* If expr is true, it returns no value.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||||
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
void assert_failed(uint8_t* file, uint32_t line);
|
||||||
|
#else
|
||||||
|
#define assert_param(expr) ((void)0U)
|
||||||
|
#endif /* USE_FULL_ASSERT */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F1xx_HAL_CONF_H */
|
||||||
|
|
||||||
68
STM32F103_Example/Core/Inc/stm32f1xx_it.h
Normal file
68
STM32F103_Example/Core/Inc/stm32f1xx_it.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f1xx_it.h
|
||||||
|
* @brief This file contains the headers of the interrupt handlers.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __STM32F1xx_IT_H
|
||||||
|
#define __STM32F1xx_IT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Private includes ----------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN ET */
|
||||||
|
|
||||||
|
/* USER CODE END ET */
|
||||||
|
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN EC */
|
||||||
|
|
||||||
|
/* USER CODE END EC */
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN EM */
|
||||||
|
|
||||||
|
/* USER CODE END EM */
|
||||||
|
|
||||||
|
/* Exported functions prototypes ---------------------------------------------*/
|
||||||
|
void NMI_Handler(void);
|
||||||
|
void HardFault_Handler(void);
|
||||||
|
void MemManage_Handler(void);
|
||||||
|
void BusFault_Handler(void);
|
||||||
|
void UsageFault_Handler(void);
|
||||||
|
void SVC_Handler(void);
|
||||||
|
void DebugMon_Handler(void);
|
||||||
|
void PendSV_Handler(void);
|
||||||
|
void SysTick_Handler(void);
|
||||||
|
void TIM3_IRQHandler(void);
|
||||||
|
void USART1_IRQHandler(void);
|
||||||
|
/* USER CODE BEGIN EFP */
|
||||||
|
|
||||||
|
/* USER CODE END EFP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STM32F1xx_IT_H */
|
||||||
52
STM32F103_Example/Core/Inc/tim.h
Normal file
52
STM32F103_Example/Core/Inc/tim.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file tim.h
|
||||||
|
* @brief This file contains all the function prototypes for
|
||||||
|
* the tim.c file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __TIM_H__
|
||||||
|
#define __TIM_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
extern TIM_HandleTypeDef htim3;
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Private defines */
|
||||||
|
|
||||||
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
|
void MX_TIM3_Init(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Prototypes */
|
||||||
|
|
||||||
|
/* USER CODE END Prototypes */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __TIM_H__ */
|
||||||
|
|
||||||
52
STM32F103_Example/Core/Inc/usart.h
Normal file
52
STM32F103_Example/Core/Inc/usart.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usart.h
|
||||||
|
* @brief This file contains all the function prototypes for
|
||||||
|
* the usart.c file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef __USART_H__
|
||||||
|
#define __USART_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
extern UART_HandleTypeDef huart1;
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Private defines */
|
||||||
|
|
||||||
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
|
void MX_USART1_UART_Init(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Prototypes */
|
||||||
|
|
||||||
|
/* USER CODE END Prototypes */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __USART_H__ */
|
||||||
|
|
||||||
53
STM32F103_Example/Core/Src/gpio.c
Normal file
53
STM32F103_Example/Core/Src/gpio.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file gpio.c
|
||||||
|
* @brief This file provides code for the configuration
|
||||||
|
* of all used GPIO pins.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/* Configure GPIO */
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
|
/** Configure pins as
|
||||||
|
* Analog
|
||||||
|
* Input
|
||||||
|
* Output
|
||||||
|
* EVENT_OUT
|
||||||
|
* EXTI
|
||||||
|
*/
|
||||||
|
void MX_GPIO_Init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* GPIO Ports Clock Enable */
|
||||||
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
|
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
|
||||||
|
/* USER CODE END 2 */
|
||||||
201
STM32F103_Example/Core/Src/main.c
Normal file
201
STM32F103_Example/Core/Src/main.c
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file : main.c
|
||||||
|
* @brief : Main program body
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "tim.h"
|
||||||
|
#include "usart.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* Private includes ----------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
#include "modbus.h"
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PTD */
|
||||||
|
|
||||||
|
/* USER CODE END PTD */
|
||||||
|
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PD */
|
||||||
|
|
||||||
|
/* USER CODE END PD */
|
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PM */
|
||||||
|
|
||||||
|
/* USER CODE END PM */
|
||||||
|
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* USER CODE BEGIN PV */
|
||||||
|
|
||||||
|
/* USER CODE END PV */
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
void SystemClock_Config(void);
|
||||||
|
/* USER CODE BEGIN PFP */
|
||||||
|
|
||||||
|
/* USER CODE END PFP */
|
||||||
|
|
||||||
|
/* Private user code ---------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
int coil_to_toggle = 0;
|
||||||
|
int coil_state = 0;
|
||||||
|
int coil_real_state = 0;
|
||||||
|
void master_callback(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *msg)
|
||||||
|
{
|
||||||
|
if(MB_RespGet_CoilState(msg, coil_to_toggle, &coil_real_state))
|
||||||
|
{
|
||||||
|
coil_state = coil_real_state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The application entry point.
|
||||||
|
* @retval int
|
||||||
|
*/
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
|
/* MCU Configuration--------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||||
|
HAL_Init();
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Init */
|
||||||
|
|
||||||
|
/* USER CODE END Init */
|
||||||
|
|
||||||
|
/* Configure the system clock */
|
||||||
|
SystemClock_Config();
|
||||||
|
|
||||||
|
/* USER CODE BEGIN SysInit */
|
||||||
|
|
||||||
|
/* USER CODE END SysInit */
|
||||||
|
|
||||||
|
/* Initialize all configured peripherals */
|
||||||
|
MX_GPIO_Init();
|
||||||
|
MX_USART1_UART_Init();
|
||||||
|
MX_TIM3_Init();
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
MODBUS_FirstInit(&hmodbus1, &huart1, &htim3);
|
||||||
|
#ifdef MODBUS_MODE_MASTER
|
||||||
|
MODBUS_Config(&hmodbus1, 0, MODBUS_TIMEOUT, MODBUS_MODE_MASTER);
|
||||||
|
#else
|
||||||
|
MODBUS_Config(&hmodbus1, MODBUS_DEVICE_ID, MODBUS_TIMEOUT, MODBUS_MODE_SLAVE);
|
||||||
|
MODBUS_SlaveStart(&hmodbus1, NULL);
|
||||||
|
#endif
|
||||||
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
|
/* Infinite loop */
|
||||||
|
/* USER CODE BEGIN WHILE */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
#ifdef MODBUS_MODE_MASTER
|
||||||
|
HAL_Delay(1000);
|
||||||
|
MODBUS_MSG = MB_REQUEST_READ_COILS(1, 0, 5);
|
||||||
|
MODBUS_MasterRequest(&hmodbus1, &MODBUS_MSG, &master_callback);
|
||||||
|
HAL_Delay(1000);
|
||||||
|
MODBUS_MSG = MB_REQUEST_WRITE_SINGLE_COIL(1, coil_to_toggle, !coil_state);
|
||||||
|
MODBUS_MasterRequest(&hmodbus1, &MODBUS_MSG, &master_callback);
|
||||||
|
#endif
|
||||||
|
/* USER CODE END WHILE */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 3 */
|
||||||
|
}
|
||||||
|
/* USER CODE END 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System Clock Configuration
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void SystemClock_Config(void)
|
||||||
|
{
|
||||||
|
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||||
|
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||||
|
|
||||||
|
/** Initializes the RCC Oscillators according to the specified parameters
|
||||||
|
* in the RCC_OscInitTypeDef structure.
|
||||||
|
*/
|
||||||
|
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
|
||||||
|
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||||
|
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
|
||||||
|
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
|
||||||
|
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Initializes the CPU, AHB and APB buses clocks
|
||||||
|
*/
|
||||||
|
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||||
|
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||||
|
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
|
||||||
|
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||||
|
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||||
|
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||||
|
|
||||||
|
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 4 */
|
||||||
|
|
||||||
|
/* USER CODE END 4 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is executed in case of error occurrence.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void Error_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN Error_Handler_Debug */
|
||||||
|
/* User can add his own implementation to report the HAL error return state */
|
||||||
|
__disable_irq();
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/* USER CODE END Error_Handler_Debug */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_FULL_ASSERT
|
||||||
|
/**
|
||||||
|
* @brief Reports the name of the source file and the source line number
|
||||||
|
* where the assert_param error has occurred.
|
||||||
|
* @param file: pointer to the source file name
|
||||||
|
* @param line: assert_param error line source number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void assert_failed(uint8_t *file, uint32_t line)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN 6 */
|
||||||
|
/* User can add his own implementation to report the file name and line number,
|
||||||
|
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||||
|
/* USER CODE END 6 */
|
||||||
|
}
|
||||||
|
#endif /* USE_FULL_ASSERT */
|
||||||
87
STM32F103_Example/Core/Src/stm32f1xx_hal_msp.c
Normal file
87
STM32F103_Example/Core/Src/stm32f1xx_hal_msp.c
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f1xx_hal_msp.c
|
||||||
|
* @brief This file provides code for the MSP Initialization
|
||||||
|
* and de-Initialization codes.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "main.h"
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN TD */
|
||||||
|
|
||||||
|
/* USER CODE END TD */
|
||||||
|
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN Define */
|
||||||
|
|
||||||
|
/* USER CODE END Define */
|
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN Macro */
|
||||||
|
|
||||||
|
/* USER CODE END Macro */
|
||||||
|
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PV */
|
||||||
|
|
||||||
|
/* USER CODE END PV */
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PFP */
|
||||||
|
|
||||||
|
/* USER CODE END PFP */
|
||||||
|
|
||||||
|
/* External functions --------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN ExternalFunctions */
|
||||||
|
|
||||||
|
/* USER CODE END ExternalFunctions */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
/**
|
||||||
|
* Initializes the Global MSP.
|
||||||
|
*/
|
||||||
|
void HAL_MspInit(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END MspInit 0 */
|
||||||
|
|
||||||
|
__HAL_RCC_AFIO_CLK_ENABLE();
|
||||||
|
__HAL_RCC_PWR_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* System interrupt init*/
|
||||||
|
|
||||||
|
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
|
||||||
|
*/
|
||||||
|
__HAL_AFIO_REMAP_SWJ_NOJTAG();
|
||||||
|
|
||||||
|
/* USER CODE BEGIN MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END MspInit 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
|
/* USER CODE END 1 */
|
||||||
233
STM32F103_Example/Core/Src/stm32f1xx_it.c
Normal file
233
STM32F103_Example/Core/Src/stm32f1xx_it.c
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f1xx_it.c
|
||||||
|
* @brief Interrupt Service Routines.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "stm32f1xx_it.h"
|
||||||
|
/* Private includes ----------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
#include "rs_message.h"
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN TD */
|
||||||
|
|
||||||
|
/* USER CODE END TD */
|
||||||
|
|
||||||
|
/* Private define ------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PD */
|
||||||
|
|
||||||
|
/* USER CODE END PD */
|
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PM */
|
||||||
|
|
||||||
|
/* USER CODE END PM */
|
||||||
|
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PV */
|
||||||
|
|
||||||
|
/* USER CODE END PV */
|
||||||
|
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN PFP */
|
||||||
|
|
||||||
|
/* USER CODE END PFP */
|
||||||
|
|
||||||
|
/* Private user code ---------------------------------------------------------*/
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
/* External variables --------------------------------------------------------*/
|
||||||
|
extern TIM_HandleTypeDef htim3;
|
||||||
|
extern UART_HandleTypeDef huart1;
|
||||||
|
/* USER CODE BEGIN EV */
|
||||||
|
|
||||||
|
/* USER CODE END EV */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
||||||
|
/******************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief This function handles Non maskable interrupt.
|
||||||
|
*/
|
||||||
|
void NMI_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||||
|
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles Hard fault interrupt.
|
||||||
|
*/
|
||||||
|
void HardFault_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||||
|
return;
|
||||||
|
/* USER CODE END HardFault_IRQn 0 */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||||
|
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles Memory management fault.
|
||||||
|
*/
|
||||||
|
void MemManage_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END MemoryManagement_IRQn 0 */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||||
|
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles Prefetch fault, memory access fault.
|
||||||
|
*/
|
||||||
|
void BusFault_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN BusFault_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END BusFault_IRQn 0 */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||||||
|
/* USER CODE END W1_BusFault_IRQn 0 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles Undefined instruction or illegal state.
|
||||||
|
*/
|
||||||
|
void UsageFault_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END UsageFault_IRQn 0 */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||||||
|
/* USER CODE END W1_UsageFault_IRQn 0 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles System service call via SWI instruction.
|
||||||
|
*/
|
||||||
|
void SVC_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN SVCall_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END SVCall_IRQn 0 */
|
||||||
|
/* USER CODE BEGIN SVCall_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END SVCall_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles Debug monitor.
|
||||||
|
*/
|
||||||
|
void DebugMon_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END DebugMonitor_IRQn 0 */
|
||||||
|
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END DebugMonitor_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles Pendable request for system service.
|
||||||
|
*/
|
||||||
|
void PendSV_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN PendSV_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END PendSV_IRQn 0 */
|
||||||
|
/* USER CODE BEGIN PendSV_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END PendSV_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles System tick timer.
|
||||||
|
*/
|
||||||
|
void SysTick_Handler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||||
|
|
||||||
|
/* USER CODE END SysTick_IRQn 0 */
|
||||||
|
HAL_IncTick();
|
||||||
|
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END SysTick_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
/* STM32F1xx Peripheral Interrupt Handlers */
|
||||||
|
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||||
|
/* For the available peripheral interrupt handler names, */
|
||||||
|
/* please refer to the startup file (startup_stm32f1xx.s). */
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles TIM3 global interrupt.
|
||||||
|
*/
|
||||||
|
void TIM3_IRQHandler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN TIM3_IRQn 0 */
|
||||||
|
RS_TIM_Handler(&hmodbus1);
|
||||||
|
return;
|
||||||
|
/* USER CODE END TIM3_IRQn 0 */
|
||||||
|
HAL_TIM_IRQHandler(&htim3);
|
||||||
|
/* USER CODE BEGIN TIM3_IRQn 1 */
|
||||||
|
/* USER CODE END TIM3_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function handles USART1 global interrupt.
|
||||||
|
*/
|
||||||
|
void USART1_IRQHandler(void)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USART1_IRQn 0 */
|
||||||
|
RS_UART_Handler(&hmodbus1);
|
||||||
|
return;
|
||||||
|
/* USER CODE END USART1_IRQn 0 */
|
||||||
|
HAL_UART_IRQHandler(&huart1);
|
||||||
|
/* USER CODE BEGIN USART1_IRQn 1 */
|
||||||
|
/* USER CODE END USART1_IRQn 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
|
/* USER CODE END 1 */
|
||||||
406
STM32F103_Example/Core/Src/system_stm32f1xx.c
Normal file
406
STM32F103_Example/Core/Src/system_stm32f1xx.c
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file system_stm32f1xx.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
|
||||||
|
*
|
||||||
|
* 1. This file provides two functions and one global variable to be called from
|
||||||
|
* user application:
|
||||||
|
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
|
||||||
|
* factors, AHB/APBx prescalers and Flash settings).
|
||||||
|
* This function is called at startup just after reset and
|
||||||
|
* before branch to main program. This call is made inside
|
||||||
|
* the "startup_stm32f1xx_xx.s" file.
|
||||||
|
*
|
||||||
|
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||||
|
* by the user application to setup the SysTick
|
||||||
|
* timer or configure other parameters.
|
||||||
|
*
|
||||||
|
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||||
|
* be called whenever the core clock is changed
|
||||||
|
* during program execution.
|
||||||
|
*
|
||||||
|
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
|
||||||
|
* Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
|
||||||
|
* configure the system clock before to branch to main program.
|
||||||
|
*
|
||||||
|
* 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
|
||||||
|
* the product used), refer to "HSE_VALUE".
|
||||||
|
* When HSE is used as system clock source, directly or through PLL, and you
|
||||||
|
* are using different crystal you have to adapt the HSE value to your own
|
||||||
|
* configuration.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2021 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup CMSIS
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup stm32f1xx_system
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_System_Private_Includes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stm32f1xx.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_System_Private_Defines
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined (HSE_VALUE)
|
||||||
|
#define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
|
||||||
|
This value can be provided and adapted by the user application. */
|
||||||
|
#endif /* HSE_VALUE */
|
||||||
|
|
||||||
|
#if !defined (HSI_VALUE)
|
||||||
|
#define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
|
||||||
|
This value can be provided and adapted by the user application. */
|
||||||
|
#endif /* HSI_VALUE */
|
||||||
|
|
||||||
|
/*!< Uncomment the following line if you need to use external SRAM */
|
||||||
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
|
/* #define DATA_IN_ExtSRAM */
|
||||||
|
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||||
|
|
||||||
|
/* Note: Following vector table addresses must be defined in line with linker
|
||||||
|
configuration. */
|
||||||
|
/*!< Uncomment the following line if you need to relocate the vector table
|
||||||
|
anywhere in Flash or Sram, else the vector table is kept at the automatic
|
||||||
|
remap of boot address selected */
|
||||||
|
/* #define USER_VECT_TAB_ADDRESS */
|
||||||
|
|
||||||
|
#if defined(USER_VECT_TAB_ADDRESS)
|
||||||
|
/*!< Uncomment the following line if you need to relocate your vector Table
|
||||||
|
in Sram else user remap will be done in Flash. */
|
||||||
|
/* #define VECT_TAB_SRAM */
|
||||||
|
#if defined(VECT_TAB_SRAM)
|
||||||
|
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
|
||||||
|
This value must be a multiple of 0x200. */
|
||||||
|
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||||
|
This value must be a multiple of 0x200. */
|
||||||
|
#else
|
||||||
|
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||||
|
This value must be a multiple of 0x200. */
|
||||||
|
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||||
|
This value must be a multiple of 0x200. */
|
||||||
|
#endif /* VECT_TAB_SRAM */
|
||||||
|
#endif /* USER_VECT_TAB_ADDRESS */
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_System_Private_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_System_Private_Variables
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This variable is updated in three ways:
|
||||||
|
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||||
|
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||||
|
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||||
|
Note: If you use this function to configure the system clock; then there
|
||||||
|
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||||
|
variable is updated automatically.
|
||||||
|
*/
|
||||||
|
uint32_t SystemCoreClock = 8000000;
|
||||||
|
const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||||
|
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
|
#ifdef DATA_IN_ExtSRAM
|
||||||
|
static void SystemInit_ExtMemCtl(void);
|
||||||
|
#endif /* DATA_IN_ExtSRAM */
|
||||||
|
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_System_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setup the microcontroller system
|
||||||
|
* Initialize the Embedded Flash Interface, the PLL and update the
|
||||||
|
* SystemCoreClock variable.
|
||||||
|
* @note This function should be used only after reset.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void SystemInit (void)
|
||||||
|
{
|
||||||
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
|
#ifdef DATA_IN_ExtSRAM
|
||||||
|
SystemInit_ExtMemCtl();
|
||||||
|
#endif /* DATA_IN_ExtSRAM */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Configure the Vector Table location -------------------------------------*/
|
||||||
|
#if defined(USER_VECT_TAB_ADDRESS)
|
||||||
|
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
|
||||||
|
#endif /* USER_VECT_TAB_ADDRESS */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||||
|
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||||
|
* be used by the user application to setup the SysTick timer or configure
|
||||||
|
* other parameters.
|
||||||
|
*
|
||||||
|
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||||
|
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||||
|
* based on this variable will be incorrect.
|
||||||
|
*
|
||||||
|
* @note - The system frequency computed by this function is not the real
|
||||||
|
* frequency in the chip. It is calculated based on the predefined
|
||||||
|
* constant and the selected clock source:
|
||||||
|
*
|
||||||
|
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||||
|
*
|
||||||
|
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||||
|
*
|
||||||
|
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||||
|
* or HSI_VALUE(*) multiplied by the PLL factors.
|
||||||
|
*
|
||||||
|
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||||
|
* 8 MHz) but the real value may vary depending on the variations
|
||||||
|
* in voltage and temperature.
|
||||||
|
*
|
||||||
|
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||||
|
* 8 MHz or 25 MHz, depending on the product used), user has to ensure
|
||||||
|
* that HSE_VALUE is same as the real frequency of the crystal used.
|
||||||
|
* Otherwise, this function may have wrong result.
|
||||||
|
*
|
||||||
|
* - The result of this function could be not correct when using fractional
|
||||||
|
* value for HSE crystal.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void SystemCoreClockUpdate (void)
|
||||||
|
{
|
||||||
|
uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
|
||||||
|
|
||||||
|
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||||
|
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
|
||||||
|
#endif /* STM32F105xC */
|
||||||
|
|
||||||
|
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||||
|
uint32_t prediv1factor = 0U;
|
||||||
|
#endif /* STM32F100xB or STM32F100xE */
|
||||||
|
|
||||||
|
/* Get SYSCLK source -------------------------------------------------------*/
|
||||||
|
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||||
|
|
||||||
|
switch (tmp)
|
||||||
|
{
|
||||||
|
case 0x00U: /* HSI used as system clock */
|
||||||
|
SystemCoreClock = HSI_VALUE;
|
||||||
|
break;
|
||||||
|
case 0x04U: /* HSE used as system clock */
|
||||||
|
SystemCoreClock = HSE_VALUE;
|
||||||
|
break;
|
||||||
|
case 0x08U: /* PLL used as system clock */
|
||||||
|
|
||||||
|
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||||
|
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
||||||
|
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||||
|
|
||||||
|
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||||
|
pllmull = ( pllmull >> 18U) + 2U;
|
||||||
|
|
||||||
|
if (pllsource == 0x00U)
|
||||||
|
{
|
||||||
|
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||||
|
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||||
|
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||||
|
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||||
|
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||||
|
#else
|
||||||
|
/* HSE selected as PLL clock entry */
|
||||||
|
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
|
||||||
|
{/* HSE oscillator clock divided by 2 */
|
||||||
|
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SystemCoreClock = HSE_VALUE * pllmull;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
pllmull = pllmull >> 18U;
|
||||||
|
|
||||||
|
if (pllmull != 0x0DU)
|
||||||
|
{
|
||||||
|
pllmull += 2U;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* PLL multiplication factor = PLL input clock * 6.5 */
|
||||||
|
pllmull = 13U / 2U;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pllsource == 0x00U)
|
||||||
|
{
|
||||||
|
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||||
|
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{/* PREDIV1 selected as PLL clock entry */
|
||||||
|
|
||||||
|
/* Get PREDIV1 clock source and division factor */
|
||||||
|
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
|
||||||
|
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||||
|
|
||||||
|
if (prediv1source == 0U)
|
||||||
|
{
|
||||||
|
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||||
|
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{/* PLL2 clock selected as PREDIV1 clock entry */
|
||||||
|
|
||||||
|
/* Get PREDIV2 division factor and PLL2 multiplication factor */
|
||||||
|
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
|
||||||
|
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
|
||||||
|
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* STM32F105xC */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SystemCoreClock = HSI_VALUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute HCLK clock frequency ----------------*/
|
||||||
|
/* Get HCLK prescaler */
|
||||||
|
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
||||||
|
/* HCLK clock frequency */
|
||||||
|
SystemCoreClock >>= tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
|
/**
|
||||||
|
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
|
||||||
|
* before jump to __main
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#ifdef DATA_IN_ExtSRAM
|
||||||
|
/**
|
||||||
|
* @brief Setup the external memory controller.
|
||||||
|
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
|
||||||
|
* This function configures the external SRAM mounted on STM3210E-EVAL
|
||||||
|
* board (STM32 High density devices). This SRAM will be used as program
|
||||||
|
* data memory (including heap and stack).
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void SystemInit_ExtMemCtl(void)
|
||||||
|
{
|
||||||
|
__IO uint32_t tmpreg;
|
||||||
|
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
|
||||||
|
required, then adjust the Register Addresses */
|
||||||
|
|
||||||
|
/* Enable FSMC clock */
|
||||||
|
RCC->AHBENR = 0x00000114U;
|
||||||
|
|
||||||
|
/* Delay after an RCC peripheral clock enabling */
|
||||||
|
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
|
||||||
|
|
||||||
|
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
||||||
|
RCC->APB2ENR = 0x000001E0U;
|
||||||
|
|
||||||
|
/* Delay after an RCC peripheral clock enabling */
|
||||||
|
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
|
||||||
|
|
||||||
|
(void)(tmpreg);
|
||||||
|
|
||||||
|
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
|
||||||
|
/*---------------- SRAM Address lines configuration -------------------------*/
|
||||||
|
/*---------------- NOE and NWE configuration --------------------------------*/
|
||||||
|
/*---------------- NE3 configuration ----------------------------------------*/
|
||||||
|
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
|
||||||
|
|
||||||
|
GPIOD->CRL = 0x44BB44BBU;
|
||||||
|
GPIOD->CRH = 0xBBBBBBBBU;
|
||||||
|
|
||||||
|
GPIOE->CRL = 0xB44444BBU;
|
||||||
|
GPIOE->CRH = 0xBBBBBBBBU;
|
||||||
|
|
||||||
|
GPIOF->CRL = 0x44BBBBBBU;
|
||||||
|
GPIOF->CRH = 0xBBBB4444U;
|
||||||
|
|
||||||
|
GPIOG->CRL = 0x44BBBBBBU;
|
||||||
|
GPIOG->CRH = 0x444B4B44U;
|
||||||
|
|
||||||
|
/*---------------- FSMC Configuration ---------------------------------------*/
|
||||||
|
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
|
||||||
|
|
||||||
|
FSMC_Bank1->BTCR[4U] = 0x00001091U;
|
||||||
|
FSMC_Bank1->BTCR[5U] = 0x00110212U;
|
||||||
|
}
|
||||||
|
#endif /* DATA_IN_ExtSRAM */
|
||||||
|
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
111
STM32F103_Example/Core/Src/tim.c
Normal file
111
STM32F103_Example/Core/Src/tim.c
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file tim.c
|
||||||
|
* @brief This file provides code for the configuration
|
||||||
|
* of the TIM instances.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "tim.h"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
TIM_HandleTypeDef htim3;
|
||||||
|
|
||||||
|
/* TIM3 init function */
|
||||||
|
void MX_TIM3_Init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN TIM3_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_Init 0 */
|
||||||
|
|
||||||
|
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
|
||||||
|
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||||
|
|
||||||
|
/* USER CODE BEGIN TIM3_Init 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_Init 1 */
|
||||||
|
htim3.Instance = TIM3;
|
||||||
|
htim3.Init.Prescaler = 8-1;
|
||||||
|
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
|
htim3.Init.Period = 65535;
|
||||||
|
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||||
|
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||||
|
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||||
|
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||||
|
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||||
|
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
/* USER CODE BEGIN TIM3_Init 2 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_Init 2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(tim_baseHandle->Instance==TIM3)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN TIM3_MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_MspInit 0 */
|
||||||
|
/* TIM3 clock enable */
|
||||||
|
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||||
|
|
||||||
|
/* TIM3 interrupt Init */
|
||||||
|
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(TIM3_IRQn);
|
||||||
|
/* USER CODE BEGIN TIM3_MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_MspInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(tim_baseHandle->Instance==TIM3)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN TIM3_MspDeInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_MspDeInit 0 */
|
||||||
|
/* Peripheral clock disable */
|
||||||
|
__HAL_RCC_TIM3_CLK_DISABLE();
|
||||||
|
|
||||||
|
/* TIM3 interrupt Deinit */
|
||||||
|
HAL_NVIC_DisableIRQ(TIM3_IRQn);
|
||||||
|
/* USER CODE BEGIN TIM3_MspDeInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM3_MspDeInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
|
/* USER CODE END 1 */
|
||||||
124
STM32F103_Example/Core/Src/usart.c
Normal file
124
STM32F103_Example/Core/Src/usart.c
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file usart.c
|
||||||
|
* @brief This file provides code for the configuration
|
||||||
|
* of the USART instances.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2025 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
|
* in the root directory of this software component.
|
||||||
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
/* USER CODE END Header */
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "usart.h"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
UART_HandleTypeDef huart1;
|
||||||
|
|
||||||
|
/* USART1 init function */
|
||||||
|
|
||||||
|
void MX_USART1_UART_Init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USART1_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USART1_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN USART1_Init 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USART1_Init 1 */
|
||||||
|
huart1.Instance = USART1;
|
||||||
|
huart1.Init.BaudRate = 115200;
|
||||||
|
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||||
|
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||||
|
huart1.Init.Parity = UART_PARITY_NONE;
|
||||||
|
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||||
|
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||||
|
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||||
|
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||||
|
{
|
||||||
|
Error_Handler();
|
||||||
|
}
|
||||||
|
/* USER CODE BEGIN USART1_Init 2 */
|
||||||
|
|
||||||
|
/* USER CODE END USART1_Init 2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||||
|
{
|
||||||
|
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||||
|
if(uartHandle->Instance==USART1)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USART1_MspInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USART1_MspInit 0 */
|
||||||
|
/* USART1 clock enable */
|
||||||
|
__HAL_RCC_USART1_CLK_ENABLE();
|
||||||
|
|
||||||
|
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||||
|
/**USART1 GPIO Configuration
|
||||||
|
PB6 ------> USART1_TX
|
||||||
|
PB7 ------> USART1_RX
|
||||||
|
*/
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_6;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_7;
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||||
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
__HAL_AFIO_REMAP_USART1_ENABLE();
|
||||||
|
|
||||||
|
/* USART1 interrupt Init */
|
||||||
|
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
|
||||||
|
HAL_NVIC_EnableIRQ(USART1_IRQn);
|
||||||
|
/* USER CODE BEGIN USART1_MspInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USART1_MspInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(uartHandle->Instance==USART1)
|
||||||
|
{
|
||||||
|
/* USER CODE BEGIN USART1_MspDeInit 0 */
|
||||||
|
|
||||||
|
/* USER CODE END USART1_MspDeInit 0 */
|
||||||
|
/* Peripheral clock disable */
|
||||||
|
__HAL_RCC_USART1_CLK_DISABLE();
|
||||||
|
|
||||||
|
/**USART1 GPIO Configuration
|
||||||
|
PB6 ------> USART1_TX
|
||||||
|
PB7 ------> USART1_RX
|
||||||
|
*/
|
||||||
|
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
|
||||||
|
|
||||||
|
/* USART1 interrupt Deinit */
|
||||||
|
HAL_NVIC_DisableIRQ(USART1_IRQn);
|
||||||
|
/* USER CODE BEGIN USART1_MspDeInit 1 */
|
||||||
|
|
||||||
|
/* USER CODE END USART1_MspDeInit 1 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
|
/* USER CODE END 1 */
|
||||||
865
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_armcc.h
Normal file
865
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_armcc.h
Normal file
@@ -0,0 +1,865 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file cmsis_armcc.h
|
||||||
|
* @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
|
||||||
|
* @version V5.0.4
|
||||||
|
* @date 10. January 2018
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CMSIS_ARMCC_H
|
||||||
|
#define __CMSIS_ARMCC_H
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
|
||||||
|
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CMSIS compiler control architecture macros */
|
||||||
|
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
|
||||||
|
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
|
||||||
|
#define __ARM_ARCH_6M__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
|
||||||
|
#define __ARM_ARCH_7M__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
|
||||||
|
#define __ARM_ARCH_7EM__ 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* __ARM_ARCH_8M_BASE__ not applicable */
|
||||||
|
/* __ARM_ARCH_8M_MAIN__ not applicable */
|
||||||
|
|
||||||
|
|
||||||
|
/* CMSIS compiler specific defines */
|
||||||
|
#ifndef __ASM
|
||||||
|
#define __ASM __asm
|
||||||
|
#endif
|
||||||
|
#ifndef __INLINE
|
||||||
|
#define __INLINE __inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_INLINE
|
||||||
|
#define __STATIC_INLINE static __inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_FORCEINLINE
|
||||||
|
#define __STATIC_FORCEINLINE static __forceinline
|
||||||
|
#endif
|
||||||
|
#ifndef __NO_RETURN
|
||||||
|
#define __NO_RETURN __declspec(noreturn)
|
||||||
|
#endif
|
||||||
|
#ifndef __USED
|
||||||
|
#define __USED __attribute__((used))
|
||||||
|
#endif
|
||||||
|
#ifndef __WEAK
|
||||||
|
#define __WEAK __attribute__((weak))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED
|
||||||
|
#define __PACKED __attribute__((packed))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_STRUCT
|
||||||
|
#define __PACKED_STRUCT __packed struct
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_UNION
|
||||||
|
#define __PACKED_UNION __packed union
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||||
|
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_WRITE
|
||||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_READ
|
||||||
|
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_WRITE
|
||||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_READ
|
||||||
|
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
|
||||||
|
#endif
|
||||||
|
#ifndef __ALIGNED
|
||||||
|
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||||
|
#endif
|
||||||
|
#ifndef __RESTRICT
|
||||||
|
#define __RESTRICT __restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ########################### Core Function Access ########################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable IRQ Interrupts
|
||||||
|
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
/* intrinsic void __enable_irq(); */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable IRQ Interrupts
|
||||||
|
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
/* intrinsic void __disable_irq(); */
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Control Register
|
||||||
|
\details Returns the content of the Control Register.
|
||||||
|
\return Control Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regControl __ASM("control");
|
||||||
|
return(__regControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Control Register
|
||||||
|
\details Writes the given value to the Control Register.
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||||
|
{
|
||||||
|
register uint32_t __regControl __ASM("control");
|
||||||
|
__regControl = control;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get IPSR Register
|
||||||
|
\details Returns the content of the IPSR Register.
|
||||||
|
\return IPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regIPSR __ASM("ipsr");
|
||||||
|
return(__regIPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get APSR Register
|
||||||
|
\details Returns the content of the APSR Register.
|
||||||
|
\return APSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regAPSR __ASM("apsr");
|
||||||
|
return(__regAPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get xPSR Register
|
||||||
|
\details Returns the content of the xPSR Register.
|
||||||
|
\return xPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regXPSR __ASM("xpsr");
|
||||||
|
return(__regXPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer
|
||||||
|
\details Returns the current value of the Process Stack Pointer (PSP).
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||||
|
return(__regProcessStackPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer
|
||||||
|
\details Assigns the given value to the Process Stack Pointer (PSP).
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||||
|
__regProcessStackPointer = topOfProcStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer
|
||||||
|
\details Returns the current value of the Main Stack Pointer (MSP).
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regMainStackPointer __ASM("msp");
|
||||||
|
return(__regMainStackPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer
|
||||||
|
\details Assigns the given value to the Main Stack Pointer (MSP).
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
register uint32_t __regMainStackPointer __ASM("msp");
|
||||||
|
__regMainStackPointer = topOfMainStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Priority Mask
|
||||||
|
\details Returns the current state of the priority mask bit from the Priority Mask Register.
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regPriMask __ASM("primask");
|
||||||
|
return(__regPriMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Priority Mask
|
||||||
|
\details Assigns the given value to the Priority Mask Register.
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||||
|
{
|
||||||
|
register uint32_t __regPriMask __ASM("primask");
|
||||||
|
__regPriMask = (priMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable FIQ
|
||||||
|
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __enable_fault_irq __enable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable FIQ
|
||||||
|
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __disable_fault_irq __disable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Base Priority
|
||||||
|
\details Returns the current value of the Base Priority register.
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePri __ASM("basepri");
|
||||||
|
return(__regBasePri);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority
|
||||||
|
\details Assigns the given value to the Base Priority register.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePri __ASM("basepri");
|
||||||
|
__regBasePri = (basePri & 0xFFU);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority with condition
|
||||||
|
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||||
|
or the new value increases the BASEPRI priority level.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePriMax __ASM("basepri_max");
|
||||||
|
__regBasePriMax = (basePri & 0xFFU);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Fault Mask
|
||||||
|
\details Returns the current value of the Fault Mask register.
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regFaultMask __ASM("faultmask");
|
||||||
|
return(__regFaultMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Fault Mask
|
||||||
|
\details Assigns the given value to the Fault Mask register.
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
register uint32_t __regFaultMask __ASM("faultmask");
|
||||||
|
__regFaultMask = (faultMask & (uint32_t)1U);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get FPSCR
|
||||||
|
\details Returns the current value of the Floating Point Status/Control register.
|
||||||
|
\return Floating Point Status/Control register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||||
|
{
|
||||||
|
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||||
|
register uint32_t __regfpscr __ASM("fpscr");
|
||||||
|
return(__regfpscr);
|
||||||
|
#else
|
||||||
|
return(0U);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set FPSCR
|
||||||
|
\details Assigns the given value to the Floating Point Status/Control register.
|
||||||
|
\param [in] fpscr Floating Point Status/Control value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||||
|
{
|
||||||
|
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||||
|
register uint32_t __regfpscr __ASM("fpscr");
|
||||||
|
__regfpscr = (fpscr);
|
||||||
|
#else
|
||||||
|
(void)fpscr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## Core Instruction Access ######################### */
|
||||||
|
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||||
|
Access to dedicated instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief No Operation
|
||||||
|
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
#define __NOP __nop
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Wait For Interrupt
|
||||||
|
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFI __wfi
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Wait For Event
|
||||||
|
\details Wait For Event is a hint instruction that permits the processor to enter
|
||||||
|
a low-power state until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFE __wfe
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Send Event
|
||||||
|
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||||
|
*/
|
||||||
|
#define __SEV __sev
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Instruction Synchronization Barrier
|
||||||
|
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||||
|
so that all instructions following the ISB are fetched from cache or memory,
|
||||||
|
after the instruction has been completed.
|
||||||
|
*/
|
||||||
|
#define __ISB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__isb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Data Synchronization Barrier
|
||||||
|
\details Acts as a special kind of Data Memory Barrier.
|
||||||
|
It completes when all explicit memory accesses before this instruction complete.
|
||||||
|
*/
|
||||||
|
#define __DSB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__dsb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Data Memory Barrier
|
||||||
|
\details Ensures the apparent order of the explicit memory operations before
|
||||||
|
and after the instruction, without ensuring their completion.
|
||||||
|
*/
|
||||||
|
#define __DMB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__dmb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0U)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (32 bit)
|
||||||
|
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#define __REV __rev
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (16 bit)
|
||||||
|
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||||
|
{
|
||||||
|
rev16 r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (16 bit)
|
||||||
|
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
|
||||||
|
{
|
||||||
|
revsh r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Rotate Right in unsigned value (32 bit)
|
||||||
|
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||||
|
\param [in] op1 Value to rotate
|
||||||
|
\param [in] op2 Number of Bits to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
#define __ROR __ror
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Breakpoint
|
||||||
|
\details Causes the processor to enter Debug state.
|
||||||
|
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||||
|
\param [in] value is ignored by the processor.
|
||||||
|
If required, a debugger can use it to store additional information about the breakpoint.
|
||||||
|
*/
|
||||||
|
#define __BKPT(value) __breakpoint(value)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse bit order of value
|
||||||
|
\details Reverses the bit order of the given value.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||||
|
#define __RBIT __rbit
|
||||||
|
#else
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
|
||||||
|
|
||||||
|
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||||
|
for (value >>= 1U; value != 0U; value >>= 1U)
|
||||||
|
{
|
||||||
|
result <<= 1U;
|
||||||
|
result |= value & 1U;
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
result <<= s; /* shift when v's highest bits are zero */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Count leading zeros
|
||||||
|
\details Counts the number of leading zeros of a data value.
|
||||||
|
\param [in] value Value to count the leading zeros
|
||||||
|
\return number of leading zeros in value
|
||||||
|
*/
|
||||||
|
#define __CLZ __clz
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (8 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||||
|
#else
|
||||||
|
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (16 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||||
|
#else
|
||||||
|
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (32 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||||
|
#else
|
||||||
|
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (8 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||||
|
#else
|
||||||
|
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (16 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||||
|
#else
|
||||||
|
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (32 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||||
|
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||||
|
#else
|
||||||
|
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Remove the exclusive lock
|
||||||
|
\details Removes the exclusive lock which is created by LDREX.
|
||||||
|
*/
|
||||||
|
#define __CLREX __clrex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Signed Saturate
|
||||||
|
\details Saturates a signed value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __SSAT __ssat
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Unsigned Saturate
|
||||||
|
\details Saturates an unsigned value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __USAT __usat
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Rotate Right with Extend (32 bit)
|
||||||
|
\details Moves each bit of a bitstring right by one bit.
|
||||||
|
The carry input is shifted in at the left end of the bitstring.
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
rrx r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (8 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (16 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (32 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (8 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (16 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (32 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Signed Saturate
|
||||||
|
\details Saturates a signed value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||||
|
{
|
||||||
|
if ((sat >= 1U) && (sat <= 32U))
|
||||||
|
{
|
||||||
|
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||||
|
const int32_t min = -1 - max ;
|
||||||
|
if (val > max)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else if (val < min)
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Unsigned Saturate
|
||||||
|
\details Saturates an unsigned value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||||
|
{
|
||||||
|
if (sat <= 31U)
|
||||||
|
{
|
||||||
|
const uint32_t max = ((1U << sat) - 1U);
|
||||||
|
if (val > (int32_t)max)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else if (val < 0)
|
||||||
|
{
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (uint32_t)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||||
|
|
||||||
|
|
||||||
|
/* ################### Compiler specific Intrinsics ########################### */
|
||||||
|
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||||
|
Access to dedicated SIMD instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||||
|
|
||||||
|
#define __SADD8 __sadd8
|
||||||
|
#define __QADD8 __qadd8
|
||||||
|
#define __SHADD8 __shadd8
|
||||||
|
#define __UADD8 __uadd8
|
||||||
|
#define __UQADD8 __uqadd8
|
||||||
|
#define __UHADD8 __uhadd8
|
||||||
|
#define __SSUB8 __ssub8
|
||||||
|
#define __QSUB8 __qsub8
|
||||||
|
#define __SHSUB8 __shsub8
|
||||||
|
#define __USUB8 __usub8
|
||||||
|
#define __UQSUB8 __uqsub8
|
||||||
|
#define __UHSUB8 __uhsub8
|
||||||
|
#define __SADD16 __sadd16
|
||||||
|
#define __QADD16 __qadd16
|
||||||
|
#define __SHADD16 __shadd16
|
||||||
|
#define __UADD16 __uadd16
|
||||||
|
#define __UQADD16 __uqadd16
|
||||||
|
#define __UHADD16 __uhadd16
|
||||||
|
#define __SSUB16 __ssub16
|
||||||
|
#define __QSUB16 __qsub16
|
||||||
|
#define __SHSUB16 __shsub16
|
||||||
|
#define __USUB16 __usub16
|
||||||
|
#define __UQSUB16 __uqsub16
|
||||||
|
#define __UHSUB16 __uhsub16
|
||||||
|
#define __SASX __sasx
|
||||||
|
#define __QASX __qasx
|
||||||
|
#define __SHASX __shasx
|
||||||
|
#define __UASX __uasx
|
||||||
|
#define __UQASX __uqasx
|
||||||
|
#define __UHASX __uhasx
|
||||||
|
#define __SSAX __ssax
|
||||||
|
#define __QSAX __qsax
|
||||||
|
#define __SHSAX __shsax
|
||||||
|
#define __USAX __usax
|
||||||
|
#define __UQSAX __uqsax
|
||||||
|
#define __UHSAX __uhsax
|
||||||
|
#define __USAD8 __usad8
|
||||||
|
#define __USADA8 __usada8
|
||||||
|
#define __SSAT16 __ssat16
|
||||||
|
#define __USAT16 __usat16
|
||||||
|
#define __UXTB16 __uxtb16
|
||||||
|
#define __UXTAB16 __uxtab16
|
||||||
|
#define __SXTB16 __sxtb16
|
||||||
|
#define __SXTAB16 __sxtab16
|
||||||
|
#define __SMUAD __smuad
|
||||||
|
#define __SMUADX __smuadx
|
||||||
|
#define __SMLAD __smlad
|
||||||
|
#define __SMLADX __smladx
|
||||||
|
#define __SMLALD __smlald
|
||||||
|
#define __SMLALDX __smlaldx
|
||||||
|
#define __SMUSD __smusd
|
||||||
|
#define __SMUSDX __smusdx
|
||||||
|
#define __SMLSD __smlsd
|
||||||
|
#define __SMLSDX __smlsdx
|
||||||
|
#define __SMLSLD __smlsld
|
||||||
|
#define __SMLSLDX __smlsldx
|
||||||
|
#define __SEL __sel
|
||||||
|
#define __QADD __qadd
|
||||||
|
#define __QSUB __qsub
|
||||||
|
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||||
|
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||||
|
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||||
|
|
||||||
|
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||||
|
((int64_t)(ARG3) << 32U) ) >> 32U))
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||||
|
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __CMSIS_ARMCC_H */
|
||||||
1869
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_armclang.h
Normal file
1869
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_armclang.h
Normal file
@@ -0,0 +1,1869 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file cmsis_armclang.h
|
||||||
|
* @brief CMSIS compiler armclang (Arm Compiler 6) header file
|
||||||
|
* @version V5.0.4
|
||||||
|
* @date 10. January 2018
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */
|
||||||
|
|
||||||
|
#ifndef __CMSIS_ARMCLANG_H
|
||||||
|
#define __CMSIS_ARMCLANG_H
|
||||||
|
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
|
||||||
|
#ifndef __ARM_COMPAT_H
|
||||||
|
#include <arm_compat.h> /* Compatibility header for Arm Compiler 5 intrinsics */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CMSIS compiler specific defines */
|
||||||
|
#ifndef __ASM
|
||||||
|
#define __ASM __asm
|
||||||
|
#endif
|
||||||
|
#ifndef __INLINE
|
||||||
|
#define __INLINE __inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_INLINE
|
||||||
|
#define __STATIC_INLINE static __inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_FORCEINLINE
|
||||||
|
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline
|
||||||
|
#endif
|
||||||
|
#ifndef __NO_RETURN
|
||||||
|
#define __NO_RETURN __attribute__((__noreturn__))
|
||||||
|
#endif
|
||||||
|
#ifndef __USED
|
||||||
|
#define __USED __attribute__((used))
|
||||||
|
#endif
|
||||||
|
#ifndef __WEAK
|
||||||
|
#define __WEAK __attribute__((weak))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED
|
||||||
|
#define __PACKED __attribute__((packed, aligned(1)))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_STRUCT
|
||||||
|
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_UNION
|
||||||
|
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wpacked"
|
||||||
|
/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */
|
||||||
|
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_WRITE
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wpacked"
|
||||||
|
/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
|
||||||
|
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_READ
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wpacked"
|
||||||
|
/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
|
||||||
|
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_WRITE
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wpacked"
|
||||||
|
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
|
||||||
|
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_READ
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wpacked"
|
||||||
|
/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */
|
||||||
|
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __ALIGNED
|
||||||
|
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||||
|
#endif
|
||||||
|
#ifndef __RESTRICT
|
||||||
|
#define __RESTRICT __restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################### Core Function Access ########################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable IRQ Interrupts
|
||||||
|
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
/* intrinsic void __enable_irq(); see arm_compat.h */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable IRQ Interrupts
|
||||||
|
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
/* intrinsic void __disable_irq(); see arm_compat.h */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Control Register
|
||||||
|
\details Returns the content of the Control Register.
|
||||||
|
\return Control Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_CONTROL(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Control Register (non-secure)
|
||||||
|
\details Returns the content of the non-secure Control Register when in secure mode.
|
||||||
|
\return non-secure Control Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, control_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Control Register
|
||||||
|
\details Writes the given value to the Control Register.
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Control Register (non-secure)
|
||||||
|
\details Writes the given value to the non-secure Control Register when in secure state.
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get IPSR Register
|
||||||
|
\details Returns the content of the IPSR Register.
|
||||||
|
\return IPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_IPSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get APSR Register
|
||||||
|
\details Returns the content of the APSR Register.
|
||||||
|
\return APSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get xPSR Register
|
||||||
|
\details Returns the content of the xPSR Register.
|
||||||
|
\return xPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_xPSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer
|
||||||
|
\details Returns the current value of the Process Stack Pointer (PSP).
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_PSP(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, psp" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, psp_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer
|
||||||
|
\details Assigns the given value to the Process Stack Pointer (PSP).
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer
|
||||||
|
\details Returns the current value of the Main Stack Pointer (MSP).
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_MSP(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, msp" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer
|
||||||
|
\details Assigns the given value to the Main Stack Pointer (MSP).
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Stack Pointer (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Stack Pointer (SP) when in secure state.
|
||||||
|
\return SP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, sp_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Stack Pointer (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state.
|
||||||
|
\param [in] topOfStack Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Priority Mask
|
||||||
|
\details Returns the current state of the priority mask bit from the Priority Mask Register.
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Priority Mask (non-secure)
|
||||||
|
\details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Priority Mask
|
||||||
|
\details Assigns the given value to the Priority Mask Register.
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Priority Mask (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Priority Mask Register when in secure state.
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||||
|
/**
|
||||||
|
\brief Enable FIQ
|
||||||
|
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __enable_fault_irq __enable_fiq /* see arm_compat.h */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable FIQ
|
||||||
|
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __disable_fault_irq __disable_fiq /* see arm_compat.h */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Base Priority
|
||||||
|
\details Returns the current value of the Base Priority register.
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, basepri" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Base Priority (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Base Priority register when in secure state.
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority
|
||||||
|
\details Assigns the given value to the Base Priority register.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Base Priority register when in secure state.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority with condition
|
||||||
|
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||||
|
or the new value increases the BASEPRI priority level.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Fault Mask
|
||||||
|
\details Returns the current value of the Fault Mask register.
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Fault Mask (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Fault Mask register when in secure state.
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Fault Mask
|
||||||
|
\details Assigns the given value to the Fault Mask register.
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Fault Mask (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Fault Mask register when in secure state.
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer Limit
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence zero is returned always in non-secure
|
||||||
|
mode.
|
||||||
|
|
||||||
|
\details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
|
||||||
|
\return PSPLIM Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
return 0U;
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
__ASM volatile ("MRS %0, psplim" : "=r" (result) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer Limit (non-secure)
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence zero is returned always in non-secure
|
||||||
|
mode.
|
||||||
|
|
||||||
|
\details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
|
||||||
|
\return PSPLIM Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
return 0U;
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
__ASM volatile ("MRS %0, psplim_ns" : "=r" (result) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer Limit
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence the write is silently ignored in non-secure
|
||||||
|
mode.
|
||||||
|
|
||||||
|
\details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
|
||||||
|
\param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
(void)ProcStackPtrLimit;
|
||||||
|
#else
|
||||||
|
__ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer (non-secure)
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence the write is silently ignored in non-secure
|
||||||
|
mode.
|
||||||
|
|
||||||
|
\details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
|
||||||
|
\param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
(void)ProcStackPtrLimit;
|
||||||
|
#else
|
||||||
|
__ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer Limit
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence zero is returned always.
|
||||||
|
|
||||||
|
\details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
|
||||||
|
\return MSPLIM Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
return 0U;
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
__ASM volatile ("MRS %0, msplim" : "=r" (result) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer Limit (non-secure)
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence zero is returned always.
|
||||||
|
|
||||||
|
\details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
|
||||||
|
\return MSPLIM Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
return 0U;
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
__ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer Limit
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence the write is silently ignored.
|
||||||
|
|
||||||
|
\details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
|
||||||
|
\param [in] MainStackPtrLimit Main Stack Pointer Limit value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
(void)MainStackPtrLimit;
|
||||||
|
#else
|
||||||
|
__ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer Limit (non-secure)
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence the write is silently ignored.
|
||||||
|
|
||||||
|
\details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
|
||||||
|
\param [in] MainStackPtrLimit Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
(void)MainStackPtrLimit;
|
||||||
|
#else
|
||||||
|
__ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get FPSCR
|
||||||
|
\details Returns the current value of the Floating Point Status/Control register.
|
||||||
|
\return Floating Point Status/Control register value
|
||||||
|
*/
|
||||||
|
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||||
|
#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr
|
||||||
|
#else
|
||||||
|
#define __get_FPSCR() ((uint32_t)0U)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set FPSCR
|
||||||
|
\details Assigns the given value to the Floating Point Status/Control register.
|
||||||
|
\param [in] fpscr Floating Point Status/Control value to set
|
||||||
|
*/
|
||||||
|
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||||
|
#define __set_FPSCR __builtin_arm_set_fpscr
|
||||||
|
#else
|
||||||
|
#define __set_FPSCR(x) ((void)(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## Core Instruction Access ######################### */
|
||||||
|
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||||
|
Access to dedicated instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define macros for porting to both thumb1 and thumb2.
|
||||||
|
* For thumb1, use low register (r0-r7), specified by constraint "l"
|
||||||
|
* Otherwise, use general registers, specified by constraint "r" */
|
||||||
|
#if defined (__thumb__) && !defined (__thumb2__)
|
||||||
|
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
||||||
|
#define __CMSIS_GCC_USE_REG(r) "l" (r)
|
||||||
|
#else
|
||||||
|
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
||||||
|
#define __CMSIS_GCC_USE_REG(r) "r" (r)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief No Operation
|
||||||
|
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
#define __NOP __builtin_arm_nop
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Wait For Interrupt
|
||||||
|
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFI __builtin_arm_wfi
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Wait For Event
|
||||||
|
\details Wait For Event is a hint instruction that permits the processor to enter
|
||||||
|
a low-power state until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFE __builtin_arm_wfe
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Send Event
|
||||||
|
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||||
|
*/
|
||||||
|
#define __SEV __builtin_arm_sev
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Instruction Synchronization Barrier
|
||||||
|
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||||
|
so that all instructions following the ISB are fetched from cache or memory,
|
||||||
|
after the instruction has been completed.
|
||||||
|
*/
|
||||||
|
#define __ISB() __builtin_arm_isb(0xF);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Data Synchronization Barrier
|
||||||
|
\details Acts as a special kind of Data Memory Barrier.
|
||||||
|
It completes when all explicit memory accesses before this instruction complete.
|
||||||
|
*/
|
||||||
|
#define __DSB() __builtin_arm_dsb(0xF);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Data Memory Barrier
|
||||||
|
\details Ensures the apparent order of the explicit memory operations before
|
||||||
|
and after the instruction, without ensuring their completion.
|
||||||
|
*/
|
||||||
|
#define __DMB() __builtin_arm_dmb(0xF);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (32 bit)
|
||||||
|
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#define __REV(value) __builtin_bswap32(value)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (16 bit)
|
||||||
|
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#define __REV16(value) __ROR(__REV(value), 16)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (16 bit)
|
||||||
|
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#define __REVSH(value) (int16_t)__builtin_bswap16(value)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Rotate Right in unsigned value (32 bit)
|
||||||
|
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||||
|
\param [in] op1 Value to rotate
|
||||||
|
\param [in] op2 Number of Bits to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
op2 %= 32U;
|
||||||
|
if (op2 == 0U)
|
||||||
|
{
|
||||||
|
return op1;
|
||||||
|
}
|
||||||
|
return (op1 >> op2) | (op1 << (32U - op2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Breakpoint
|
||||||
|
\details Causes the processor to enter Debug state.
|
||||||
|
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||||
|
\param [in] value is ignored by the processor.
|
||||||
|
If required, a debugger can use it to store additional information about the breakpoint.
|
||||||
|
*/
|
||||||
|
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse bit order of value
|
||||||
|
\details Reverses the bit order of the given value.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#define __RBIT __builtin_arm_rbit
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Count leading zeros
|
||||||
|
\details Counts the number of leading zeros of a data value.
|
||||||
|
\param [in] value Value to count the leading zeros
|
||||||
|
\return number of leading zeros in value
|
||||||
|
*/
|
||||||
|
#define __CLZ (uint8_t)__builtin_clz
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (8 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXB (uint8_t)__builtin_arm_ldrex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (16 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXH (uint16_t)__builtin_arm_ldrex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (32 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXW (uint32_t)__builtin_arm_ldrex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (8 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXB (uint32_t)__builtin_arm_strex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (16 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXH (uint32_t)__builtin_arm_strex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (32 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXW (uint32_t)__builtin_arm_strex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Remove the exclusive lock
|
||||||
|
\details Removes the exclusive lock which is created by LDREX.
|
||||||
|
*/
|
||||||
|
#define __CLREX __builtin_arm_clrex
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Signed Saturate
|
||||||
|
\details Saturates a signed value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __SSAT __builtin_arm_ssat
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Unsigned Saturate
|
||||||
|
\details Saturates an unsigned value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __USAT __builtin_arm_usat
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Rotate Right with Extend (32 bit)
|
||||||
|
\details Moves each bit of a bitstring right by one bit.
|
||||||
|
The carry input is shifted in at the left end of the bitstring.
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (8 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return ((uint8_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (16 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return ((uint16_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (32 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (8 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (16 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (32 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Signed Saturate
|
||||||
|
\details Saturates a signed value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||||
|
{
|
||||||
|
if ((sat >= 1U) && (sat <= 32U))
|
||||||
|
{
|
||||||
|
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||||
|
const int32_t min = -1 - max ;
|
||||||
|
if (val > max)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else if (val < min)
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Unsigned Saturate
|
||||||
|
\details Saturates an unsigned value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||||
|
{
|
||||||
|
if (sat <= 31U)
|
||||||
|
{
|
||||||
|
const uint32_t max = ((1U << sat) - 1U);
|
||||||
|
if (val > (int32_t)max)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else if (val < 0)
|
||||||
|
{
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (uint32_t)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire (8 bit)
|
||||||
|
\details Executes a LDAB instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return ((uint8_t) result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire (16 bit)
|
||||||
|
\details Executes a LDAH instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return ((uint16_t) result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire (32 bit)
|
||||||
|
\details Executes a LDA instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release (8 bit)
|
||||||
|
\details Executes a STLB instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release (16 bit)
|
||||||
|
\details Executes a STLH instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release (32 bit)
|
||||||
|
\details Executes a STL instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire Exclusive (8 bit)
|
||||||
|
\details Executes a LDAB exclusive instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDAEXB (uint8_t)__builtin_arm_ldaex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire Exclusive (16 bit)
|
||||||
|
\details Executes a LDAH exclusive instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDAEXH (uint16_t)__builtin_arm_ldaex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire Exclusive (32 bit)
|
||||||
|
\details Executes a LDA exclusive instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDAEX (uint32_t)__builtin_arm_ldaex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release Exclusive (8 bit)
|
||||||
|
\details Executes a STLB exclusive instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STLEXB (uint32_t)__builtin_arm_stlex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release Exclusive (16 bit)
|
||||||
|
\details Executes a STLH exclusive instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STLEXH (uint32_t)__builtin_arm_stlex
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release Exclusive (32 bit)
|
||||||
|
\details Executes a STL exclusive instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STLEX (uint32_t)__builtin_arm_stlex
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||||
|
|
||||||
|
|
||||||
|
/* ################### Compiler specific Intrinsics ########################### */
|
||||||
|
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||||
|
Access to dedicated SIMD instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __SSAT16(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
int32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __USAT16(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ /* Little endian */
|
||||||
|
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else /* Big endian */
|
||||||
|
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ /* Little endian */
|
||||||
|
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else /* Big endian */
|
||||||
|
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ /* Little endian */
|
||||||
|
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else /* Big endian */
|
||||||
|
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ /* Little endian */
|
||||||
|
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else /* Big endian */
|
||||||
|
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||||
|
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||||
|
if (ARG3 == 0) \
|
||||||
|
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
||||||
|
else \
|
||||||
|
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||||
|
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||||
|
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__ARM_FEATURE_DSP == 1) */
|
||||||
|
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __CMSIS_ARMCLANG_H */
|
||||||
266
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_compiler.h
Normal file
266
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_compiler.h
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file cmsis_compiler.h
|
||||||
|
* @brief CMSIS compiler generic header file
|
||||||
|
* @version V5.0.4
|
||||||
|
* @date 10. January 2018
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CMSIS_COMPILER_H
|
||||||
|
#define __CMSIS_COMPILER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Arm Compiler 4/5
|
||||||
|
*/
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#include "cmsis_armcc.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Arm Compiler 6 (armclang)
|
||||||
|
*/
|
||||||
|
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#include "cmsis_armclang.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GNU Compiler
|
||||||
|
*/
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#include "cmsis_gcc.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IAR Compiler
|
||||||
|
*/
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#include <cmsis_iccarm.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TI Arm Compiler
|
||||||
|
*/
|
||||||
|
#elif defined ( __TI_ARM__ )
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
#ifndef __ASM
|
||||||
|
#define __ASM __asm
|
||||||
|
#endif
|
||||||
|
#ifndef __INLINE
|
||||||
|
#define __INLINE inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_INLINE
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_FORCEINLINE
|
||||||
|
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||||
|
#endif
|
||||||
|
#ifndef __NO_RETURN
|
||||||
|
#define __NO_RETURN __attribute__((noreturn))
|
||||||
|
#endif
|
||||||
|
#ifndef __USED
|
||||||
|
#define __USED __attribute__((used))
|
||||||
|
#endif
|
||||||
|
#ifndef __WEAK
|
||||||
|
#define __WEAK __attribute__((weak))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED
|
||||||
|
#define __PACKED __attribute__((packed))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_STRUCT
|
||||||
|
#define __PACKED_STRUCT struct __attribute__((packed))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_UNION
|
||||||
|
#define __PACKED_UNION union __attribute__((packed))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||||
|
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_WRITE
|
||||||
|
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_READ
|
||||||
|
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||||
|
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_WRITE
|
||||||
|
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_READ
|
||||||
|
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __ALIGNED
|
||||||
|
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||||
|
#endif
|
||||||
|
#ifndef __RESTRICT
|
||||||
|
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||||
|
#define __RESTRICT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TASKING Compiler
|
||||||
|
*/
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM
|
||||||
|
#define __ASM __asm
|
||||||
|
#endif
|
||||||
|
#ifndef __INLINE
|
||||||
|
#define __INLINE inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_INLINE
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_FORCEINLINE
|
||||||
|
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||||
|
#endif
|
||||||
|
#ifndef __NO_RETURN
|
||||||
|
#define __NO_RETURN __attribute__((noreturn))
|
||||||
|
#endif
|
||||||
|
#ifndef __USED
|
||||||
|
#define __USED __attribute__((used))
|
||||||
|
#endif
|
||||||
|
#ifndef __WEAK
|
||||||
|
#define __WEAK __attribute__((weak))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED
|
||||||
|
#define __PACKED __packed__
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_STRUCT
|
||||||
|
#define __PACKED_STRUCT struct __packed__
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_UNION
|
||||||
|
#define __PACKED_UNION union __packed__
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||||
|
struct __packed__ T_UINT32 { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_WRITE
|
||||||
|
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_READ
|
||||||
|
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||||
|
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_WRITE
|
||||||
|
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_READ
|
||||||
|
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __ALIGNED
|
||||||
|
#define __ALIGNED(x) __align(x)
|
||||||
|
#endif
|
||||||
|
#ifndef __RESTRICT
|
||||||
|
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||||
|
#define __RESTRICT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* COSMIC Compiler
|
||||||
|
*/
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#ifndef __ASM
|
||||||
|
#define __ASM _asm
|
||||||
|
#endif
|
||||||
|
#ifndef __INLINE
|
||||||
|
#define __INLINE inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_INLINE
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_FORCEINLINE
|
||||||
|
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||||
|
#endif
|
||||||
|
#ifndef __NO_RETURN
|
||||||
|
// NO RETURN is automatically detected hence no warning here
|
||||||
|
#define __NO_RETURN
|
||||||
|
#endif
|
||||||
|
#ifndef __USED
|
||||||
|
#warning No compiler specific solution for __USED. __USED is ignored.
|
||||||
|
#define __USED
|
||||||
|
#endif
|
||||||
|
#ifndef __WEAK
|
||||||
|
#define __WEAK __weak
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED
|
||||||
|
#define __PACKED @packed
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_STRUCT
|
||||||
|
#define __PACKED_STRUCT @packed struct
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_UNION
|
||||||
|
#define __PACKED_UNION @packed union
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||||
|
@packed struct T_UINT32 { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_WRITE
|
||||||
|
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_READ
|
||||||
|
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||||
|
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_WRITE
|
||||||
|
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_READ
|
||||||
|
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||||
|
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __ALIGNED
|
||||||
|
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||||
|
#define __ALIGNED(x)
|
||||||
|
#endif
|
||||||
|
#ifndef __RESTRICT
|
||||||
|
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||||
|
#define __RESTRICT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Unknown compiler.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __CMSIS_COMPILER_H */
|
||||||
|
|
||||||
2085
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_gcc.h
Normal file
2085
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_gcc.h
Normal file
@@ -0,0 +1,2085 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file cmsis_gcc.h
|
||||||
|
* @brief CMSIS compiler GCC header file
|
||||||
|
* @version V5.0.4
|
||||||
|
* @date 09. April 2018
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CMSIS_GCC_H
|
||||||
|
#define __CMSIS_GCC_H
|
||||||
|
|
||||||
|
/* ignore some GCC warnings */
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||||
|
#pragma GCC diagnostic ignored "-Wconversion"
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
|
||||||
|
/* Fallback for __has_builtin */
|
||||||
|
#ifndef __has_builtin
|
||||||
|
#define __has_builtin(x) (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* CMSIS compiler specific defines */
|
||||||
|
#ifndef __ASM
|
||||||
|
#define __ASM __asm
|
||||||
|
#endif
|
||||||
|
#ifndef __INLINE
|
||||||
|
#define __INLINE inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_INLINE
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
#endif
|
||||||
|
#ifndef __STATIC_FORCEINLINE
|
||||||
|
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
|
||||||
|
#endif
|
||||||
|
#ifndef __NO_RETURN
|
||||||
|
#define __NO_RETURN __attribute__((__noreturn__))
|
||||||
|
#endif
|
||||||
|
#ifndef __USED
|
||||||
|
#define __USED __attribute__((used))
|
||||||
|
#endif
|
||||||
|
#ifndef __WEAK
|
||||||
|
#define __WEAK __attribute__((weak))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED
|
||||||
|
#define __PACKED __attribute__((packed, aligned(1)))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_STRUCT
|
||||||
|
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||||
|
#endif
|
||||||
|
#ifndef __PACKED_UNION
|
||||||
|
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpacked"
|
||||||
|
#pragma GCC diagnostic ignored "-Wattributes"
|
||||||
|
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_WRITE
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpacked"
|
||||||
|
#pragma GCC diagnostic ignored "-Wattributes"
|
||||||
|
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT16_READ
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpacked"
|
||||||
|
#pragma GCC diagnostic ignored "-Wattributes"
|
||||||
|
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_WRITE
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpacked"
|
||||||
|
#pragma GCC diagnostic ignored "-Wattributes"
|
||||||
|
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||||
|
#endif
|
||||||
|
#ifndef __UNALIGNED_UINT32_READ
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wpacked"
|
||||||
|
#pragma GCC diagnostic ignored "-Wattributes"
|
||||||
|
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||||
|
#endif
|
||||||
|
#ifndef __ALIGNED
|
||||||
|
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||||
|
#endif
|
||||||
|
#ifndef __RESTRICT
|
||||||
|
#define __RESTRICT __restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################### Core Function Access ########################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable IRQ Interrupts
|
||||||
|
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __enable_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsie i" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable IRQ Interrupts
|
||||||
|
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __disable_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsid i" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Control Register
|
||||||
|
\details Returns the content of the Control Register.
|
||||||
|
\return Control Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_CONTROL(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Control Register (non-secure)
|
||||||
|
\details Returns the content of the non-secure Control Register when in secure mode.
|
||||||
|
\return non-secure Control Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, control_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Control Register
|
||||||
|
\details Writes the given value to the Control Register.
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Control Register (non-secure)
|
||||||
|
\details Writes the given value to the non-secure Control Register when in secure state.
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get IPSR Register
|
||||||
|
\details Returns the content of the IPSR Register.
|
||||||
|
\return IPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_IPSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get APSR Register
|
||||||
|
\details Returns the content of the APSR Register.
|
||||||
|
\return APSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get xPSR Register
|
||||||
|
\details Returns the content of the xPSR Register.
|
||||||
|
\return xPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_xPSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer
|
||||||
|
\details Returns the current value of the Process Stack Pointer (PSP).
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_PSP(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, psp" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, psp_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer
|
||||||
|
\details Assigns the given value to the Process Stack Pointer (PSP).
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer
|
||||||
|
\details Returns the current value of the Main Stack Pointer (MSP).
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_MSP(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, msp" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer
|
||||||
|
\details Assigns the given value to the Main Stack Pointer (MSP).
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Stack Pointer (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Stack Pointer (SP) when in secure state.
|
||||||
|
\return SP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, sp_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Stack Pointer (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state.
|
||||||
|
\param [in] topOfStack Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Priority Mask
|
||||||
|
\details Returns the current state of the priority mask bit from the Priority Mask Register.
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory");
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Priority Mask (non-secure)
|
||||||
|
\details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory");
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Priority Mask
|
||||||
|
\details Assigns the given value to the Priority Mask Register.
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Priority Mask (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Priority Mask Register when in secure state.
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||||
|
/**
|
||||||
|
\brief Enable FIQ
|
||||||
|
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __enable_fault_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsie f" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable FIQ
|
||||||
|
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __disable_fault_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsid f" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Base Priority
|
||||||
|
\details Returns the current value of the Base Priority register.
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, basepri" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Base Priority (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Base Priority register when in secure state.
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority
|
||||||
|
\details Assigns the given value to the Base Priority register.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Base Priority register when in secure state.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Base Priority with condition
|
||||||
|
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||||
|
or the new value increases the BASEPRI priority level.
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Fault Mask
|
||||||
|
\details Returns the current value of the Fault Mask register.
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Fault Mask (non-secure)
|
||||||
|
\details Returns the current value of the non-secure Fault Mask register when in secure state.
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Fault Mask
|
||||||
|
\details Assigns the given value to the Fault Mask register.
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Fault Mask (non-secure)
|
||||||
|
\details Assigns the given value to the non-secure Fault Mask register when in secure state.
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer Limit
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence zero is returned always in non-secure
|
||||||
|
mode.
|
||||||
|
|
||||||
|
\details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
|
||||||
|
\return PSPLIM Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
return 0U;
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
__ASM volatile ("MRS %0, psplim" : "=r" (result) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Process Stack Pointer Limit (non-secure)
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence zero is returned always.
|
||||||
|
|
||||||
|
\details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
|
||||||
|
\return PSPLIM Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
return 0U;
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
__ASM volatile ("MRS %0, psplim_ns" : "=r" (result) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer Limit
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence the write is silently ignored in non-secure
|
||||||
|
mode.
|
||||||
|
|
||||||
|
\details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
|
||||||
|
\param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
(void)ProcStackPtrLimit;
|
||||||
|
#else
|
||||||
|
__ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Process Stack Pointer (non-secure)
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence the write is silently ignored.
|
||||||
|
|
||||||
|
\details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
|
||||||
|
\param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
(void)ProcStackPtrLimit;
|
||||||
|
#else
|
||||||
|
__ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer Limit
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence zero is returned always in non-secure
|
||||||
|
mode.
|
||||||
|
|
||||||
|
\details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
|
||||||
|
\return MSPLIM Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
return 0U;
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
__ASM volatile ("MRS %0, msplim" : "=r" (result) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Get Main Stack Pointer Limit (non-secure)
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence zero is returned always.
|
||||||
|
|
||||||
|
\details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
|
||||||
|
\return MSPLIM Register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
return 0U;
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
__ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer Limit
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence the write is silently ignored in non-secure
|
||||||
|
mode.
|
||||||
|
|
||||||
|
\details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
|
||||||
|
\param [in] MainStackPtrLimit Main Stack Pointer Limit value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
(void)MainStackPtrLimit;
|
||||||
|
#else
|
||||||
|
__ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
|
||||||
|
/**
|
||||||
|
\brief Set Main Stack Pointer Limit (non-secure)
|
||||||
|
Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure
|
||||||
|
Stack Pointer Limit register hence the write is silently ignored.
|
||||||
|
|
||||||
|
\details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
|
||||||
|
\param [in] MainStackPtrLimit Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
(void)MainStackPtrLimit;
|
||||||
|
#else
|
||||||
|
__ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get FPSCR
|
||||||
|
\details Returns the current value of the Floating Point Status/Control register.
|
||||||
|
\return Floating Point Status/Control register value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __get_FPSCR(void)
|
||||||
|
{
|
||||||
|
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||||
|
#if __has_builtin(__builtin_arm_get_fpscr)
|
||||||
|
// Re-enable using built-in when GCC has been fixed
|
||||||
|
// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
|
||||||
|
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
|
||||||
|
return __builtin_arm_get_fpscr();
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
return(0U);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set FPSCR
|
||||||
|
\details Assigns the given value to the Floating Point Status/Control register.
|
||||||
|
\param [in] fpscr Floating Point Status/Control value to set
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
|
||||||
|
{
|
||||||
|
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||||
|
#if __has_builtin(__builtin_arm_set_fpscr)
|
||||||
|
// Re-enable using built-in when GCC has been fixed
|
||||||
|
// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
|
||||||
|
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
|
||||||
|
__builtin_arm_set_fpscr(fpscr);
|
||||||
|
#else
|
||||||
|
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory");
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
(void)fpscr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## Core Instruction Access ######################### */
|
||||||
|
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||||
|
Access to dedicated instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define macros for porting to both thumb1 and thumb2.
|
||||||
|
* For thumb1, use low register (r0-r7), specified by constraint "l"
|
||||||
|
* Otherwise, use general registers, specified by constraint "r" */
|
||||||
|
#if defined (__thumb__) && !defined (__thumb2__)
|
||||||
|
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
||||||
|
#define __CMSIS_GCC_RW_REG(r) "+l" (r)
|
||||||
|
#define __CMSIS_GCC_USE_REG(r) "l" (r)
|
||||||
|
#else
|
||||||
|
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
||||||
|
#define __CMSIS_GCC_RW_REG(r) "+r" (r)
|
||||||
|
#define __CMSIS_GCC_USE_REG(r) "r" (r)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief No Operation
|
||||||
|
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
#define __NOP() __ASM volatile ("nop")
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Wait For Interrupt
|
||||||
|
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFI() __ASM volatile ("wfi")
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Wait For Event
|
||||||
|
\details Wait For Event is a hint instruction that permits the processor to enter
|
||||||
|
a low-power state until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFE() __ASM volatile ("wfe")
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Send Event
|
||||||
|
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||||
|
*/
|
||||||
|
#define __SEV() __ASM volatile ("sev")
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Instruction Synchronization Barrier
|
||||||
|
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||||
|
so that all instructions following the ISB are fetched from cache or memory,
|
||||||
|
after the instruction has been completed.
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __ISB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("isb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Data Synchronization Barrier
|
||||||
|
\details Acts as a special kind of Data Memory Barrier.
|
||||||
|
It completes when all explicit memory accesses before this instruction complete.
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __DSB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("dsb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Data Memory Barrier
|
||||||
|
\details Ensures the apparent order of the explicit memory operations before
|
||||||
|
and after the instruction, without ensuring their completion.
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __DMB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("dmb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (32 bit)
|
||||||
|
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __REV(uint32_t value)
|
||||||
|
{
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||||
|
return __builtin_bswap32(value);
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (16 bit)
|
||||||
|
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse byte order (16 bit)
|
||||||
|
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE int16_t __REVSH(int16_t value)
|
||||||
|
{
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
return (int16_t)__builtin_bswap16(value);
|
||||||
|
#else
|
||||||
|
int16_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Rotate Right in unsigned value (32 bit)
|
||||||
|
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||||
|
\param [in] op1 Value to rotate
|
||||||
|
\param [in] op2 Number of Bits to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
op2 %= 32U;
|
||||||
|
if (op2 == 0U)
|
||||||
|
{
|
||||||
|
return op1;
|
||||||
|
}
|
||||||
|
return (op1 >> op2) | (op1 << (32U - op2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Breakpoint
|
||||||
|
\details Causes the processor to enter Debug state.
|
||||||
|
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||||
|
\param [in] value is ignored by the processor.
|
||||||
|
If required, a debugger can use it to store additional information about the breakpoint.
|
||||||
|
*/
|
||||||
|
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Reverse bit order of value
|
||||||
|
\details Reverses the bit order of the given value.
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||||
|
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||||
|
#else
|
||||||
|
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
|
||||||
|
|
||||||
|
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||||
|
for (value >>= 1U; value != 0U; value >>= 1U)
|
||||||
|
{
|
||||||
|
result <<= 1U;
|
||||||
|
result |= value & 1U;
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
result <<= s; /* shift when v's highest bits are zero */
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Count leading zeros
|
||||||
|
\details Counts the number of leading zeros of a data value.
|
||||||
|
\param [in] value Value to count the leading zeros
|
||||||
|
\return number of leading zeros in value
|
||||||
|
*/
|
||||||
|
#define __CLZ (uint8_t)__builtin_clz
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (8 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint8_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (16 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint16_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDR Exclusive (32 bit)
|
||||||
|
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (8 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (16 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STR Exclusive (32 bit)
|
||||||
|
\details Executes a exclusive STR instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Remove the exclusive lock
|
||||||
|
\details Removes the exclusive lock which is created by LDREX.
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __CLREX(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("clrex" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||||
|
/**
|
||||||
|
\brief Signed Saturate
|
||||||
|
\details Saturates a signed value.
|
||||||
|
\param [in] ARG1 Value to be saturated
|
||||||
|
\param [in] ARG2 Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __SSAT(ARG1,ARG2) \
|
||||||
|
__extension__ \
|
||||||
|
({ \
|
||||||
|
int32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Unsigned Saturate
|
||||||
|
\details Saturates an unsigned value.
|
||||||
|
\param [in] ARG1 Value to be saturated
|
||||||
|
\param [in] ARG2 Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __USAT(ARG1,ARG2) \
|
||||||
|
__extension__ \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Rotate Right with Extend (32 bit)
|
||||||
|
\details Moves each bit of a bitstring right by one bit.
|
||||||
|
The carry input is shifted in at the left end of the bitstring.
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (8 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint8_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (16 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint16_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief LDRT Unprivileged (32 bit)
|
||||||
|
\details Executes a Unprivileged LDRT instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (8 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (16 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief STRT Unprivileged (32 bit)
|
||||||
|
\details Executes a Unprivileged STRT instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Signed Saturate
|
||||||
|
\details Saturates a signed value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||||
|
{
|
||||||
|
if ((sat >= 1U) && (sat <= 32U))
|
||||||
|
{
|
||||||
|
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||||
|
const int32_t min = -1 - max ;
|
||||||
|
if (val > max)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else if (val < min)
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Unsigned Saturate
|
||||||
|
\details Saturates an unsigned value.
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||||
|
{
|
||||||
|
if (sat <= 31U)
|
||||||
|
{
|
||||||
|
const uint32_t max = ((1U << sat) - 1U);
|
||||||
|
if (val > (int32_t)max)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else if (val < 0)
|
||||||
|
{
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (uint32_t)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||||
|
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire (8 bit)
|
||||||
|
\details Executes a LDAB instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return ((uint8_t) result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire (16 bit)
|
||||||
|
\details Executes a LDAH instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return ((uint16_t) result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire (32 bit)
|
||||||
|
\details Executes a LDA instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release (8 bit)
|
||||||
|
\details Executes a STLB instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release (16 bit)
|
||||||
|
\details Executes a STLH instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release (32 bit)
|
||||||
|
\details Executes a STL instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire Exclusive (8 bit)
|
||||||
|
\details Executes a LDAB exclusive instruction for 8 bit value.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return ((uint8_t) result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire Exclusive (16 bit)
|
||||||
|
\details Executes a LDAH exclusive instruction for 16 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return ((uint16_t) result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Load-Acquire Exclusive (32 bit)
|
||||||
|
\details Executes a LDA exclusive instruction for 32 bit values.
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release Exclusive (8 bit)
|
||||||
|
\details Executes a STLB exclusive instruction for 8 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release Exclusive (16 bit)
|
||||||
|
\details Executes a STLH exclusive instruction for 16 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Store-Release Exclusive (32 bit)
|
||||||
|
\details Executes a STL exclusive instruction for 32 bit values.
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||||
|
|
||||||
|
|
||||||
|
/* ################### Compiler specific Intrinsics ########################### */
|
||||||
|
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||||
|
Access to dedicated SIMD instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __SSAT16(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
int32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __USAT16(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ /* Little endian */
|
||||||
|
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else /* Big endian */
|
||||||
|
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ /* Little endian */
|
||||||
|
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else /* Big endian */
|
||||||
|
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ /* Little endian */
|
||||||
|
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else /* Big endian */
|
||||||
|
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ /* Little endian */
|
||||||
|
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else /* Big endian */
|
||||||
|
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||||
|
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||||
|
if (ARG3 == 0) \
|
||||||
|
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
||||||
|
else \
|
||||||
|
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||||
|
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||||
|
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||||
|
|
||||||
|
__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__ARM_FEATURE_DSP == 1) */
|
||||||
|
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||||
|
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
#endif /* __CMSIS_GCC_H */
|
||||||
935
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_iccarm.h
Normal file
935
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_iccarm.h
Normal file
@@ -0,0 +1,935 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file cmsis_iccarm.h
|
||||||
|
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
|
||||||
|
* @version V5.0.7
|
||||||
|
* @date 19. June 2018
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017-2018 IAR Systems
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CMSIS_ICCARM_H__
|
||||||
|
#define __CMSIS_ICCARM_H__
|
||||||
|
|
||||||
|
#ifndef __ICCARM__
|
||||||
|
#error This file should only be compiled by ICCARM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma system_include
|
||||||
|
|
||||||
|
#define __IAR_FT _Pragma("inline=forced") __intrinsic
|
||||||
|
|
||||||
|
#if (__VER__ >= 8000000)
|
||||||
|
#define __ICCARM_V8 1
|
||||||
|
#else
|
||||||
|
#define __ICCARM_V8 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ALIGNED
|
||||||
|
#if __ICCARM_V8
|
||||||
|
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||||
|
#elif (__VER__ >= 7080000)
|
||||||
|
/* Needs IAR language extensions */
|
||||||
|
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||||
|
#else
|
||||||
|
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
|
||||||
|
#define __ALIGNED(x)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Define compiler macros for CPU architecture, used in CMSIS 5.
|
||||||
|
*/
|
||||||
|
#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__
|
||||||
|
/* Macros already defined */
|
||||||
|
#else
|
||||||
|
#if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
|
||||||
|
#define __ARM_ARCH_8M_MAIN__ 1
|
||||||
|
#elif defined(__ARM8M_BASELINE__)
|
||||||
|
#define __ARM_ARCH_8M_BASE__ 1
|
||||||
|
#elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
|
||||||
|
#if __ARM_ARCH == 6
|
||||||
|
#define __ARM_ARCH_6M__ 1
|
||||||
|
#elif __ARM_ARCH == 7
|
||||||
|
#if __ARM_FEATURE_DSP
|
||||||
|
#define __ARM_ARCH_7EM__ 1
|
||||||
|
#else
|
||||||
|
#define __ARM_ARCH_7M__ 1
|
||||||
|
#endif
|
||||||
|
#endif /* __ARM_ARCH */
|
||||||
|
#endif /* __ARM_ARCH_PROFILE == 'M' */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Alternativ core deduction for older ICCARM's */
|
||||||
|
#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \
|
||||||
|
!defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__)
|
||||||
|
#if defined(__ARM6M__) && (__CORE__ == __ARM6M__)
|
||||||
|
#define __ARM_ARCH_6M__ 1
|
||||||
|
#elif defined(__ARM7M__) && (__CORE__ == __ARM7M__)
|
||||||
|
#define __ARM_ARCH_7M__ 1
|
||||||
|
#elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__)
|
||||||
|
#define __ARM_ARCH_7EM__ 1
|
||||||
|
#elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__)
|
||||||
|
#define __ARM_ARCH_8M_BASE__ 1
|
||||||
|
#elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__)
|
||||||
|
#define __ARM_ARCH_8M_MAIN__ 1
|
||||||
|
#elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__)
|
||||||
|
#define __ARM_ARCH_8M_MAIN__ 1
|
||||||
|
#else
|
||||||
|
#error "Unknown target."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1
|
||||||
|
#define __IAR_M0_FAMILY 1
|
||||||
|
#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1
|
||||||
|
#define __IAR_M0_FAMILY 1
|
||||||
|
#else
|
||||||
|
#define __IAR_M0_FAMILY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ASM
|
||||||
|
#define __ASM __asm
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __INLINE
|
||||||
|
#define __INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NO_RETURN
|
||||||
|
#if __ICCARM_V8
|
||||||
|
#define __NO_RETURN __attribute__((__noreturn__))
|
||||||
|
#else
|
||||||
|
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __PACKED
|
||||||
|
#if __ICCARM_V8
|
||||||
|
#define __PACKED __attribute__((packed, aligned(1)))
|
||||||
|
#else
|
||||||
|
/* Needs IAR language extensions */
|
||||||
|
#define __PACKED __packed
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __PACKED_STRUCT
|
||||||
|
#if __ICCARM_V8
|
||||||
|
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||||
|
#else
|
||||||
|
/* Needs IAR language extensions */
|
||||||
|
#define __PACKED_STRUCT __packed struct
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __PACKED_UNION
|
||||||
|
#if __ICCARM_V8
|
||||||
|
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||||
|
#else
|
||||||
|
/* Needs IAR language extensions */
|
||||||
|
#define __PACKED_UNION __packed union
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __RESTRICT
|
||||||
|
#define __RESTRICT __restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __STATIC_INLINE
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __FORCEINLINE
|
||||||
|
#define __FORCEINLINE _Pragma("inline=forced")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __STATIC_FORCEINLINE
|
||||||
|
#define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __UNALIGNED_UINT16_READ
|
||||||
|
#pragma language=save
|
||||||
|
#pragma language=extended
|
||||||
|
__IAR_FT uint16_t __iar_uint16_read(void const *ptr)
|
||||||
|
{
|
||||||
|
return *(__packed uint16_t*)(ptr);
|
||||||
|
}
|
||||||
|
#pragma language=restore
|
||||||
|
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __UNALIGNED_UINT16_WRITE
|
||||||
|
#pragma language=save
|
||||||
|
#pragma language=extended
|
||||||
|
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val)
|
||||||
|
{
|
||||||
|
*(__packed uint16_t*)(ptr) = val;;
|
||||||
|
}
|
||||||
|
#pragma language=restore
|
||||||
|
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __UNALIGNED_UINT32_READ
|
||||||
|
#pragma language=save
|
||||||
|
#pragma language=extended
|
||||||
|
__IAR_FT uint32_t __iar_uint32_read(void const *ptr)
|
||||||
|
{
|
||||||
|
return *(__packed uint32_t*)(ptr);
|
||||||
|
}
|
||||||
|
#pragma language=restore
|
||||||
|
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __UNALIGNED_UINT32_WRITE
|
||||||
|
#pragma language=save
|
||||||
|
#pragma language=extended
|
||||||
|
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val)
|
||||||
|
{
|
||||||
|
*(__packed uint32_t*)(ptr) = val;;
|
||||||
|
}
|
||||||
|
#pragma language=restore
|
||||||
|
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||||
|
#pragma language=save
|
||||||
|
#pragma language=extended
|
||||||
|
__packed struct __iar_u32 { uint32_t v; };
|
||||||
|
#pragma language=restore
|
||||||
|
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __USED
|
||||||
|
#if __ICCARM_V8
|
||||||
|
#define __USED __attribute__((used))
|
||||||
|
#else
|
||||||
|
#define __USED _Pragma("__root")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __WEAK
|
||||||
|
#if __ICCARM_V8
|
||||||
|
#define __WEAK __attribute__((weak))
|
||||||
|
#else
|
||||||
|
#define __WEAK _Pragma("__weak")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ICCARM_INTRINSICS_VERSION__
|
||||||
|
#define __ICCARM_INTRINSICS_VERSION__ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __ICCARM_INTRINSICS_VERSION__ == 2
|
||||||
|
|
||||||
|
#if defined(__CLZ)
|
||||||
|
#undef __CLZ
|
||||||
|
#endif
|
||||||
|
#if defined(__REVSH)
|
||||||
|
#undef __REVSH
|
||||||
|
#endif
|
||||||
|
#if defined(__RBIT)
|
||||||
|
#undef __RBIT
|
||||||
|
#endif
|
||||||
|
#if defined(__SSAT)
|
||||||
|
#undef __SSAT
|
||||||
|
#endif
|
||||||
|
#if defined(__USAT)
|
||||||
|
#undef __USAT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "iccarm_builtin.h"
|
||||||
|
|
||||||
|
#define __disable_fault_irq __iar_builtin_disable_fiq
|
||||||
|
#define __disable_irq __iar_builtin_disable_interrupt
|
||||||
|
#define __enable_fault_irq __iar_builtin_enable_fiq
|
||||||
|
#define __enable_irq __iar_builtin_enable_interrupt
|
||||||
|
#define __arm_rsr __iar_builtin_rsr
|
||||||
|
#define __arm_wsr __iar_builtin_wsr
|
||||||
|
|
||||||
|
|
||||||
|
#define __get_APSR() (__arm_rsr("APSR"))
|
||||||
|
#define __get_BASEPRI() (__arm_rsr("BASEPRI"))
|
||||||
|
#define __get_CONTROL() (__arm_rsr("CONTROL"))
|
||||||
|
#define __get_FAULTMASK() (__arm_rsr("FAULTMASK"))
|
||||||
|
|
||||||
|
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||||
|
#define __get_FPSCR() (__arm_rsr("FPSCR"))
|
||||||
|
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE)))
|
||||||
|
#else
|
||||||
|
#define __get_FPSCR() ( 0 )
|
||||||
|
#define __set_FPSCR(VALUE) ((void)VALUE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __get_IPSR() (__arm_rsr("IPSR"))
|
||||||
|
#define __get_MSP() (__arm_rsr("MSP"))
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
#define __get_MSPLIM() (0U)
|
||||||
|
#else
|
||||||
|
#define __get_MSPLIM() (__arm_rsr("MSPLIM"))
|
||||||
|
#endif
|
||||||
|
#define __get_PRIMASK() (__arm_rsr("PRIMASK"))
|
||||||
|
#define __get_PSP() (__arm_rsr("PSP"))
|
||||||
|
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
#define __get_PSPLIM() (0U)
|
||||||
|
#else
|
||||||
|
#define __get_PSPLIM() (__arm_rsr("PSPLIM"))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __get_xPSR() (__arm_rsr("xPSR"))
|
||||||
|
|
||||||
|
#define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE)))
|
||||||
|
#define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE)))
|
||||||
|
#define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE)))
|
||||||
|
#define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE)))
|
||||||
|
#define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE)))
|
||||||
|
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
#define __set_MSPLIM(VALUE) ((void)(VALUE))
|
||||||
|
#else
|
||||||
|
#define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE)))
|
||||||
|
#endif
|
||||||
|
#define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE)))
|
||||||
|
#define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE)))
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
#define __set_PSPLIM(VALUE) ((void)(VALUE))
|
||||||
|
#else
|
||||||
|
#define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS"))
|
||||||
|
#define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE)))
|
||||||
|
#define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS"))
|
||||||
|
#define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE)))
|
||||||
|
#define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS"))
|
||||||
|
#define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE)))
|
||||||
|
#define __TZ_get_SP_NS() (__arm_rsr("SP_NS"))
|
||||||
|
#define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE)))
|
||||||
|
#define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS"))
|
||||||
|
#define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE)))
|
||||||
|
#define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS"))
|
||||||
|
#define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE)))
|
||||||
|
#define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS"))
|
||||||
|
#define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE)))
|
||||||
|
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
#define __TZ_get_PSPLIM_NS() (0U)
|
||||||
|
#define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE))
|
||||||
|
#else
|
||||||
|
#define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS"))
|
||||||
|
#define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS"))
|
||||||
|
#define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE)))
|
||||||
|
|
||||||
|
#define __NOP __iar_builtin_no_operation
|
||||||
|
|
||||||
|
#define __CLZ __iar_builtin_CLZ
|
||||||
|
#define __CLREX __iar_builtin_CLREX
|
||||||
|
|
||||||
|
#define __DMB __iar_builtin_DMB
|
||||||
|
#define __DSB __iar_builtin_DSB
|
||||||
|
#define __ISB __iar_builtin_ISB
|
||||||
|
|
||||||
|
#define __LDREXB __iar_builtin_LDREXB
|
||||||
|
#define __LDREXH __iar_builtin_LDREXH
|
||||||
|
#define __LDREXW __iar_builtin_LDREX
|
||||||
|
|
||||||
|
#define __RBIT __iar_builtin_RBIT
|
||||||
|
#define __REV __iar_builtin_REV
|
||||||
|
#define __REV16 __iar_builtin_REV16
|
||||||
|
|
||||||
|
__IAR_FT int16_t __REVSH(int16_t val)
|
||||||
|
{
|
||||||
|
return (int16_t) __iar_builtin_REVSH(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __ROR __iar_builtin_ROR
|
||||||
|
#define __RRX __iar_builtin_RRX
|
||||||
|
|
||||||
|
#define __SEV __iar_builtin_SEV
|
||||||
|
|
||||||
|
#if !__IAR_M0_FAMILY
|
||||||
|
#define __SSAT __iar_builtin_SSAT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __STREXB __iar_builtin_STREXB
|
||||||
|
#define __STREXH __iar_builtin_STREXH
|
||||||
|
#define __STREXW __iar_builtin_STREX
|
||||||
|
|
||||||
|
#if !__IAR_M0_FAMILY
|
||||||
|
#define __USAT __iar_builtin_USAT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __WFE __iar_builtin_WFE
|
||||||
|
#define __WFI __iar_builtin_WFI
|
||||||
|
|
||||||
|
#if __ARM_MEDIA__
|
||||||
|
#define __SADD8 __iar_builtin_SADD8
|
||||||
|
#define __QADD8 __iar_builtin_QADD8
|
||||||
|
#define __SHADD8 __iar_builtin_SHADD8
|
||||||
|
#define __UADD8 __iar_builtin_UADD8
|
||||||
|
#define __UQADD8 __iar_builtin_UQADD8
|
||||||
|
#define __UHADD8 __iar_builtin_UHADD8
|
||||||
|
#define __SSUB8 __iar_builtin_SSUB8
|
||||||
|
#define __QSUB8 __iar_builtin_QSUB8
|
||||||
|
#define __SHSUB8 __iar_builtin_SHSUB8
|
||||||
|
#define __USUB8 __iar_builtin_USUB8
|
||||||
|
#define __UQSUB8 __iar_builtin_UQSUB8
|
||||||
|
#define __UHSUB8 __iar_builtin_UHSUB8
|
||||||
|
#define __SADD16 __iar_builtin_SADD16
|
||||||
|
#define __QADD16 __iar_builtin_QADD16
|
||||||
|
#define __SHADD16 __iar_builtin_SHADD16
|
||||||
|
#define __UADD16 __iar_builtin_UADD16
|
||||||
|
#define __UQADD16 __iar_builtin_UQADD16
|
||||||
|
#define __UHADD16 __iar_builtin_UHADD16
|
||||||
|
#define __SSUB16 __iar_builtin_SSUB16
|
||||||
|
#define __QSUB16 __iar_builtin_QSUB16
|
||||||
|
#define __SHSUB16 __iar_builtin_SHSUB16
|
||||||
|
#define __USUB16 __iar_builtin_USUB16
|
||||||
|
#define __UQSUB16 __iar_builtin_UQSUB16
|
||||||
|
#define __UHSUB16 __iar_builtin_UHSUB16
|
||||||
|
#define __SASX __iar_builtin_SASX
|
||||||
|
#define __QASX __iar_builtin_QASX
|
||||||
|
#define __SHASX __iar_builtin_SHASX
|
||||||
|
#define __UASX __iar_builtin_UASX
|
||||||
|
#define __UQASX __iar_builtin_UQASX
|
||||||
|
#define __UHASX __iar_builtin_UHASX
|
||||||
|
#define __SSAX __iar_builtin_SSAX
|
||||||
|
#define __QSAX __iar_builtin_QSAX
|
||||||
|
#define __SHSAX __iar_builtin_SHSAX
|
||||||
|
#define __USAX __iar_builtin_USAX
|
||||||
|
#define __UQSAX __iar_builtin_UQSAX
|
||||||
|
#define __UHSAX __iar_builtin_UHSAX
|
||||||
|
#define __USAD8 __iar_builtin_USAD8
|
||||||
|
#define __USADA8 __iar_builtin_USADA8
|
||||||
|
#define __SSAT16 __iar_builtin_SSAT16
|
||||||
|
#define __USAT16 __iar_builtin_USAT16
|
||||||
|
#define __UXTB16 __iar_builtin_UXTB16
|
||||||
|
#define __UXTAB16 __iar_builtin_UXTAB16
|
||||||
|
#define __SXTB16 __iar_builtin_SXTB16
|
||||||
|
#define __SXTAB16 __iar_builtin_SXTAB16
|
||||||
|
#define __SMUAD __iar_builtin_SMUAD
|
||||||
|
#define __SMUADX __iar_builtin_SMUADX
|
||||||
|
#define __SMMLA __iar_builtin_SMMLA
|
||||||
|
#define __SMLAD __iar_builtin_SMLAD
|
||||||
|
#define __SMLADX __iar_builtin_SMLADX
|
||||||
|
#define __SMLALD __iar_builtin_SMLALD
|
||||||
|
#define __SMLALDX __iar_builtin_SMLALDX
|
||||||
|
#define __SMUSD __iar_builtin_SMUSD
|
||||||
|
#define __SMUSDX __iar_builtin_SMUSDX
|
||||||
|
#define __SMLSD __iar_builtin_SMLSD
|
||||||
|
#define __SMLSDX __iar_builtin_SMLSDX
|
||||||
|
#define __SMLSLD __iar_builtin_SMLSLD
|
||||||
|
#define __SMLSLDX __iar_builtin_SMLSLDX
|
||||||
|
#define __SEL __iar_builtin_SEL
|
||||||
|
#define __QADD __iar_builtin_QADD
|
||||||
|
#define __QSUB __iar_builtin_QSUB
|
||||||
|
#define __PKHBT __iar_builtin_PKHBT
|
||||||
|
#define __PKHTB __iar_builtin_PKHTB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||||
|
|
||||||
|
#if __IAR_M0_FAMILY
|
||||||
|
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
|
||||||
|
#define __CLZ __cmsis_iar_clz_not_active
|
||||||
|
#define __SSAT __cmsis_iar_ssat_not_active
|
||||||
|
#define __USAT __cmsis_iar_usat_not_active
|
||||||
|
#define __RBIT __cmsis_iar_rbit_not_active
|
||||||
|
#define __get_APSR __cmsis_iar_get_APSR_not_active
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
|
||||||
|
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
|
||||||
|
#define __set_FPSCR __cmsis_iar_set_FPSR_not_active
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __INTRINSICS_INCLUDED
|
||||||
|
#error intrinsics.h is already included previously!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <intrinsics.h>
|
||||||
|
|
||||||
|
#if __IAR_M0_FAMILY
|
||||||
|
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
|
||||||
|
#undef __CLZ
|
||||||
|
#undef __SSAT
|
||||||
|
#undef __USAT
|
||||||
|
#undef __RBIT
|
||||||
|
#undef __get_APSR
|
||||||
|
|
||||||
|
__STATIC_INLINE uint8_t __CLZ(uint32_t data)
|
||||||
|
{
|
||||||
|
if (data == 0U) { return 32U; }
|
||||||
|
|
||||||
|
uint32_t count = 0U;
|
||||||
|
uint32_t mask = 0x80000000U;
|
||||||
|
|
||||||
|
while ((data & mask) == 0U)
|
||||||
|
{
|
||||||
|
count += 1U;
|
||||||
|
mask = mask >> 1U;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE uint32_t __RBIT(uint32_t v)
|
||||||
|
{
|
||||||
|
uint8_t sc = 31U;
|
||||||
|
uint32_t r = v;
|
||||||
|
for (v >>= 1U; v; v >>= 1U)
|
||||||
|
{
|
||||||
|
r <<= 1U;
|
||||||
|
r |= v & 1U;
|
||||||
|
sc--;
|
||||||
|
}
|
||||||
|
return (r << sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm("MRS %0,APSR" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||||
|
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
|
||||||
|
#undef __get_FPSCR
|
||||||
|
#undef __set_FPSCR
|
||||||
|
#define __get_FPSCR() (0)
|
||||||
|
#define __set_FPSCR(VALUE) ((void)VALUE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma diag_suppress=Pe940
|
||||||
|
#pragma diag_suppress=Pe177
|
||||||
|
|
||||||
|
#define __enable_irq __enable_interrupt
|
||||||
|
#define __disable_irq __disable_interrupt
|
||||||
|
#define __NOP __no_operation
|
||||||
|
|
||||||
|
#define __get_xPSR __get_PSR
|
||||||
|
|
||||||
|
#if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0)
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr)
|
||||||
|
{
|
||||||
|
return __LDREX((unsigned long *)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr)
|
||||||
|
{
|
||||||
|
return __STREX(value, (unsigned long *)ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
|
||||||
|
#if (__CORTEX_M >= 0x03)
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __set_BASEPRI_MAX(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR BASEPRI_MAX,%0"::"r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define __enable_fault_irq __enable_fiq
|
||||||
|
#define __disable_fault_irq __disable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) */
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __get_MSPLIM(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
res = 0U;
|
||||||
|
#else
|
||||||
|
__asm volatile("MRS %0,MSPLIM" : "=r" (res));
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __set_MSPLIM(uint32_t value)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||||
|
(void)value;
|
||||||
|
#else
|
||||||
|
__asm volatile("MSR MSPLIM,%0" :: "r" (value));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __get_PSPLIM(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
res = 0U;
|
||||||
|
#else
|
||||||
|
__asm volatile("MRS %0,PSPLIM" : "=r" (res));
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __set_PSPLIM(uint32_t value)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
(void)value;
|
||||||
|
#else
|
||||||
|
__asm volatile("MSR PSPLIM,%0" :: "r" (value));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_CONTROL_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm volatile("MRS %0,CONTROL_NS" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __TZ_set_CONTROL_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR CONTROL_NS,%0" :: "r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_PSP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm volatile("MRS %0,PSP_NS" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __TZ_set_PSP_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR PSP_NS,%0" :: "r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_MSP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm volatile("MRS %0,MSP_NS" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __TZ_set_MSP_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR MSP_NS,%0" :: "r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_SP_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm volatile("MRS %0,SP_NS" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
__IAR_FT void __TZ_set_SP_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR SP_NS,%0" :: "r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_PRIMASK_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm volatile("MRS %0,PRIMASK_NS" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR PRIMASK_NS,%0" :: "r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_BASEPRI_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm volatile("MRS %0,BASEPRI_NS" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR BASEPRI_NS,%0" :: "r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_PSPLIM_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
res = 0U;
|
||||||
|
#else
|
||||||
|
__asm volatile("MRS %0,PSPLIM_NS" : "=r" (res));
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||||
|
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||||
|
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||||
|
(void)value;
|
||||||
|
#else
|
||||||
|
__asm volatile("MSR PSPLIM_NS,%0" :: "r" (value));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __TZ_get_MSPLIM_NS(void)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__asm volatile("MRS %0,MSPLIM_NS" : "=r" (res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value)
|
||||||
|
{
|
||||||
|
__asm volatile("MSR MSPLIM_NS,%0" :: "r" (value));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
|
||||||
|
|
||||||
|
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||||
|
|
||||||
|
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
|
||||||
|
|
||||||
|
#if __IAR_M0_FAMILY
|
||||||
|
__STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||||
|
{
|
||||||
|
if ((sat >= 1U) && (sat <= 32U))
|
||||||
|
{
|
||||||
|
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||||
|
const int32_t min = -1 - max ;
|
||||||
|
if (val > max)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else if (val < min)
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
__STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||||
|
{
|
||||||
|
if (sat <= 31U)
|
||||||
|
{
|
||||||
|
const uint32_t max = ((1U << sat) - 1U);
|
||||||
|
if (val > (int32_t)max)
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else if (val < 0)
|
||||||
|
{
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (uint32_t)val;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
|
||||||
|
|
||||||
|
__IAR_FT uint8_t __LDRBT(volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||||
|
return ((uint8_t)res);
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint16_t __LDRHT(volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||||
|
return ((uint16_t)res);
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __LDRT(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
__ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
__ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
__ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) */
|
||||||
|
|
||||||
|
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||||
|
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||||
|
|
||||||
|
|
||||||
|
__IAR_FT uint8_t __LDAB(volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||||
|
return ((uint8_t)res);
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint16_t __LDAH(volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||||
|
return ((uint16_t)res);
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __LDA(volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||||
|
return ((uint8_t)res);
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||||
|
return ((uint16_t)res);
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
__IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
|
||||||
|
{
|
||||||
|
uint32_t res;
|
||||||
|
__ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
|
||||||
|
|
||||||
|
#undef __IAR_FT
|
||||||
|
#undef __IAR_M0_FAMILY
|
||||||
|
#undef __ICCARM_V8
|
||||||
|
|
||||||
|
#pragma diag_default=Pe940
|
||||||
|
#pragma diag_default=Pe177
|
||||||
|
|
||||||
|
#endif /* __CMSIS_ICCARM_H__ */
|
||||||
39
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_version.h
Normal file
39
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_version.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file cmsis_version.h
|
||||||
|
* @brief CMSIS Core(M) Version definitions
|
||||||
|
* @version V5.0.2
|
||||||
|
* @date 19. April 2017
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#elif defined (__clang__)
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CMSIS_VERSION_H
|
||||||
|
#define __CMSIS_VERSION_H
|
||||||
|
|
||||||
|
/* CMSIS Version definitions */
|
||||||
|
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
|
||||||
|
#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */
|
||||||
|
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
|
||||||
|
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
|
||||||
|
#endif
|
||||||
1918
STM32F103_Example/Drivers/CMSIS/Core/Include/core_armv8mbl.h
Normal file
1918
STM32F103_Example/Drivers/CMSIS/Core/Include/core_armv8mbl.h
Normal file
@@ -0,0 +1,1918 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_armv8mbl.h
|
||||||
|
* @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File
|
||||||
|
* @version V5.0.7
|
||||||
|
* @date 22. June 2018
|
||||||
|
******************************************************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#elif defined (__clang__)
|
||||||
|
#pragma clang system_header /* treat file as system include file */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_ARMV8MBL_H_GENERIC
|
||||||
|
#define __CORE_ARMV8MBL_H_GENERIC
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||||
|
CMSIS violates the following MISRA-C:2004 rules:
|
||||||
|
|
||||||
|
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||||
|
Function definitions in header files are used to allow 'inlining'.
|
||||||
|
|
||||||
|
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||||
|
Unions are used for effective representation of core registers.
|
||||||
|
|
||||||
|
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||||
|
Function-like macros are used to allow more efficient code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CMSIS definitions
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\ingroup Cortex_ARMv8MBL
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cmsis_version.h"
|
||||||
|
|
||||||
|
/* CMSIS definitions */
|
||||||
|
#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||||
|
#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||||
|
#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \
|
||||||
|
__ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||||
|
|
||||||
|
#define __CORTEX_M ( 2U) /*!< Cortex-M Core */
|
||||||
|
|
||||||
|
/** __FPU_USED indicates whether an FPU is used or not.
|
||||||
|
This core does not support an FPU at all
|
||||||
|
*/
|
||||||
|
#define __FPU_USED 0U
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#if defined __TARGET_FPU_VFP
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||||
|
#if defined __ARM_PCS_VFP
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#if defined __ARMVFP__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __TI_ARM__ )
|
||||||
|
#if defined __TI_VFP_SUPPORT__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
#if defined __FPU_VFP__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#if ( __CSMC__ & 0x400U)
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_ARMV8MBL_H_GENERIC */
|
||||||
|
|
||||||
|
#ifndef __CMSIS_GENERIC
|
||||||
|
|
||||||
|
#ifndef __CORE_ARMV8MBL_H_DEPENDANT
|
||||||
|
#define __CORE_ARMV8MBL_H_DEPENDANT
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check device defines and use defaults */
|
||||||
|
#if defined __CHECK_DEVICE_DEFINES
|
||||||
|
#ifndef __ARMv8MBL_REV
|
||||||
|
#define __ARMv8MBL_REV 0x0000U
|
||||||
|
#warning "__ARMv8MBL_REV not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __FPU_PRESENT
|
||||||
|
#define __FPU_PRESENT 0U
|
||||||
|
#warning "__FPU_PRESENT not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __MPU_PRESENT
|
||||||
|
#define __MPU_PRESENT 0U
|
||||||
|
#warning "__MPU_PRESENT not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __SAUREGION_PRESENT
|
||||||
|
#define __SAUREGION_PRESENT 0U
|
||||||
|
#warning "__SAUREGION_PRESENT not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __VTOR_PRESENT
|
||||||
|
#define __VTOR_PRESENT 0U
|
||||||
|
#warning "__VTOR_PRESENT not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NVIC_PRIO_BITS
|
||||||
|
#define __NVIC_PRIO_BITS 2U
|
||||||
|
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __Vendor_SysTickConfig
|
||||||
|
#define __Vendor_SysTickConfig 0U
|
||||||
|
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ETM_PRESENT
|
||||||
|
#define __ETM_PRESENT 0U
|
||||||
|
#warning "__ETM_PRESENT not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __MTB_PRESENT
|
||||||
|
#define __MTB_PRESENT 0U
|
||||||
|
#warning "__MTB_PRESENT not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IO definitions (access restrictions to peripheral registers) */
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||||
|
|
||||||
|
<strong>IO Type Qualifiers</strong> are used
|
||||||
|
\li to specify the access to peripheral variables.
|
||||||
|
\li for automatic generation of peripheral register debug information.
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define __I volatile /*!< Defines 'read only' permissions */
|
||||||
|
#else
|
||||||
|
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||||
|
#endif
|
||||||
|
#define __O volatile /*!< Defines 'write only' permissions */
|
||||||
|
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||||
|
|
||||||
|
/* following defines should be used for structure members */
|
||||||
|
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||||
|
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||||
|
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||||
|
|
||||||
|
/*@} end of group ARMv8MBL */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Register Abstraction
|
||||||
|
Core Register contain:
|
||||||
|
- Core Register
|
||||||
|
- Core NVIC Register
|
||||||
|
- Core SCB Register
|
||||||
|
- Core SysTick Register
|
||||||
|
- Core Debug Register
|
||||||
|
- Core MPU Register
|
||||||
|
- Core SAU Register
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||||
|
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_CORE Status and Control Registers
|
||||||
|
\brief Core Register type definitions.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Application Program Status Register (APSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||||
|
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||||
|
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||||
|
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||||
|
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} APSR_Type;
|
||||||
|
|
||||||
|
/* APSR Register Definitions */
|
||||||
|
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||||
|
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||||
|
|
||||||
|
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||||
|
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||||
|
|
||||||
|
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||||
|
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||||
|
|
||||||
|
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||||
|
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||||
|
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} IPSR_Type;
|
||||||
|
|
||||||
|
/* IPSR Register Definitions */
|
||||||
|
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||||
|
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||||
|
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||||
|
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||||
|
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||||
|
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||||
|
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||||
|
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||||
|
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} xPSR_Type;
|
||||||
|
|
||||||
|
/* xPSR Register Definitions */
|
||||||
|
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||||
|
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||||
|
|
||||||
|
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||||
|
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||||
|
|
||||||
|
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||||
|
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||||
|
|
||||||
|
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||||
|
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||||
|
|
||||||
|
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||||
|
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||||
|
|
||||||
|
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||||
|
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Union type to access the Control Registers (CONTROL).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
|
||||||
|
uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */
|
||||||
|
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} CONTROL_Type;
|
||||||
|
|
||||||
|
/* CONTROL Register Definitions */
|
||||||
|
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||||
|
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||||
|
|
||||||
|
#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
|
||||||
|
#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_CORE */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||||
|
\brief Type definitions for the NVIC Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||||
|
uint32_t RESERVED0[16U];
|
||||||
|
__IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||||
|
uint32_t RSERVED1[16U];
|
||||||
|
__IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||||
|
uint32_t RESERVED2[16U];
|
||||||
|
__IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||||
|
uint32_t RESERVED3[16U];
|
||||||
|
__IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
|
||||||
|
uint32_t RESERVED4[16U];
|
||||||
|
__IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */
|
||||||
|
uint32_t RESERVED5[16U];
|
||||||
|
__IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||||
|
} NVIC_Type;
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_NVIC */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||||
|
\brief Type definitions for the System Control Block Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the System Control Block (SCB).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||||
|
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||||
|
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
|
||||||
|
__IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
|
||||||
|
#else
|
||||||
|
uint32_t RESERVED0;
|
||||||
|
#endif
|
||||||
|
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||||
|
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||||
|
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||||
|
uint32_t RESERVED1;
|
||||||
|
__IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||||
|
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||||
|
} SCB_Type;
|
||||||
|
|
||||||
|
/* SCB CPUID Register Definitions */
|
||||||
|
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||||
|
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||||
|
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||||
|
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||||
|
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||||
|
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||||
|
|
||||||
|
/* SCB Interrupt Control State Register Definitions */
|
||||||
|
#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */
|
||||||
|
#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */
|
||||||
|
#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */
|
||||||
|
#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||||
|
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||||
|
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||||
|
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||||
|
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */
|
||||||
|
#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */
|
||||||
|
|
||||||
|
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||||
|
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||||
|
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||||
|
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */
|
||||||
|
#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||||
|
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||||
|
|
||||||
|
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
|
||||||
|
/* SCB Vector Table Offset Register Definitions */
|
||||||
|
#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
|
||||||
|
#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||||
|
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||||
|
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||||
|
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||||
|
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */
|
||||||
|
#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */
|
||||||
|
#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */
|
||||||
|
#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||||
|
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||||
|
|
||||||
|
/* SCB System Control Register Definitions */
|
||||||
|
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||||
|
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */
|
||||||
|
#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||||
|
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||||
|
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||||
|
|
||||||
|
/* SCB Configuration Control Register Definitions */
|
||||||
|
#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */
|
||||||
|
#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */
|
||||||
|
#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */
|
||||||
|
#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */
|
||||||
|
#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */
|
||||||
|
#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */
|
||||||
|
#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||||
|
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */
|
||||||
|
#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
|
||||||
|
|
||||||
|
/* SCB System Handler Control and State Register Definitions */
|
||||||
|
#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */
|
||||||
|
#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */
|
||||||
|
|
||||||
|
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||||
|
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||||
|
|
||||||
|
#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */
|
||||||
|
#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
|
||||||
|
|
||||||
|
#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */
|
||||||
|
#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
|
||||||
|
|
||||||
|
#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */
|
||||||
|
#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
|
||||||
|
|
||||||
|
#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */
|
||||||
|
#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */
|
||||||
|
|
||||||
|
#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */
|
||||||
|
#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SCB */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||||
|
\brief Type definitions for the System Timer Registers.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the System Timer (SysTick).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||||
|
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||||
|
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||||
|
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||||
|
} SysTick_Type;
|
||||||
|
|
||||||
|
/* SysTick Control / Status Register Definitions */
|
||||||
|
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||||
|
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||||
|
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||||
|
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||||
|
|
||||||
|
/* SysTick Reload Register Definitions */
|
||||||
|
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||||
|
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||||
|
|
||||||
|
/* SysTick Current Register Definitions */
|
||||||
|
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||||
|
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||||
|
|
||||||
|
/* SysTick Calibration Register Definitions */
|
||||||
|
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||||
|
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||||
|
|
||||||
|
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||||
|
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||||
|
|
||||||
|
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||||
|
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SysTick */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_DWT Data Watchpoint and Trace (DWT)
|
||||||
|
\brief Type definitions for the Data Watchpoint and Trace (DWT)
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Data Watchpoint and Trace Register (DWT).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
|
||||||
|
uint32_t RESERVED0[6U];
|
||||||
|
__IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
|
||||||
|
__IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
|
||||||
|
uint32_t RESERVED1[1U];
|
||||||
|
__IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
|
||||||
|
uint32_t RESERVED2[1U];
|
||||||
|
__IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
|
||||||
|
uint32_t RESERVED3[1U];
|
||||||
|
__IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
|
||||||
|
uint32_t RESERVED4[1U];
|
||||||
|
__IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
|
||||||
|
uint32_t RESERVED5[1U];
|
||||||
|
__IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
|
||||||
|
uint32_t RESERVED6[1U];
|
||||||
|
__IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
|
||||||
|
uint32_t RESERVED7[1U];
|
||||||
|
__IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
|
||||||
|
uint32_t RESERVED8[1U];
|
||||||
|
__IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */
|
||||||
|
uint32_t RESERVED9[1U];
|
||||||
|
__IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */
|
||||||
|
uint32_t RESERVED10[1U];
|
||||||
|
__IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */
|
||||||
|
uint32_t RESERVED11[1U];
|
||||||
|
__IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */
|
||||||
|
uint32_t RESERVED12[1U];
|
||||||
|
__IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */
|
||||||
|
uint32_t RESERVED13[1U];
|
||||||
|
__IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */
|
||||||
|
uint32_t RESERVED14[1U];
|
||||||
|
__IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */
|
||||||
|
uint32_t RESERVED15[1U];
|
||||||
|
__IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */
|
||||||
|
uint32_t RESERVED16[1U];
|
||||||
|
__IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */
|
||||||
|
uint32_t RESERVED17[1U];
|
||||||
|
__IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */
|
||||||
|
uint32_t RESERVED18[1U];
|
||||||
|
__IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */
|
||||||
|
uint32_t RESERVED19[1U];
|
||||||
|
__IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */
|
||||||
|
uint32_t RESERVED20[1U];
|
||||||
|
__IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */
|
||||||
|
uint32_t RESERVED21[1U];
|
||||||
|
__IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */
|
||||||
|
uint32_t RESERVED22[1U];
|
||||||
|
__IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */
|
||||||
|
uint32_t RESERVED23[1U];
|
||||||
|
__IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */
|
||||||
|
uint32_t RESERVED24[1U];
|
||||||
|
__IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */
|
||||||
|
uint32_t RESERVED25[1U];
|
||||||
|
__IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */
|
||||||
|
uint32_t RESERVED26[1U];
|
||||||
|
__IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */
|
||||||
|
uint32_t RESERVED27[1U];
|
||||||
|
__IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */
|
||||||
|
uint32_t RESERVED28[1U];
|
||||||
|
__IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */
|
||||||
|
uint32_t RESERVED29[1U];
|
||||||
|
__IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */
|
||||||
|
uint32_t RESERVED30[1U];
|
||||||
|
__IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */
|
||||||
|
uint32_t RESERVED31[1U];
|
||||||
|
__IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */
|
||||||
|
} DWT_Type;
|
||||||
|
|
||||||
|
/* DWT Control Register Definitions */
|
||||||
|
#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */
|
||||||
|
#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */
|
||||||
|
|
||||||
|
#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */
|
||||||
|
#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */
|
||||||
|
|
||||||
|
#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */
|
||||||
|
#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */
|
||||||
|
|
||||||
|
#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */
|
||||||
|
#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */
|
||||||
|
|
||||||
|
#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */
|
||||||
|
#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */
|
||||||
|
|
||||||
|
/* DWT Comparator Function Register Definitions */
|
||||||
|
#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */
|
||||||
|
#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */
|
||||||
|
|
||||||
|
#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */
|
||||||
|
#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */
|
||||||
|
|
||||||
|
#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */
|
||||||
|
#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */
|
||||||
|
|
||||||
|
#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */
|
||||||
|
#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */
|
||||||
|
|
||||||
|
#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */
|
||||||
|
#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_DWT */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_TPI Trace Port Interface (TPI)
|
||||||
|
\brief Type definitions for the Trace Port Interface (TPI)
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Trace Port Interface Register (TPI).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */
|
||||||
|
__IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */
|
||||||
|
uint32_t RESERVED0[2U];
|
||||||
|
__IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */
|
||||||
|
uint32_t RESERVED1[55U];
|
||||||
|
__IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */
|
||||||
|
uint32_t RESERVED2[131U];
|
||||||
|
__IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */
|
||||||
|
__IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */
|
||||||
|
__IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */
|
||||||
|
uint32_t RESERVED3[809U];
|
||||||
|
__OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */
|
||||||
|
__IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */
|
||||||
|
uint32_t RESERVED4[4U];
|
||||||
|
__IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */
|
||||||
|
__IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */
|
||||||
|
} TPI_Type;
|
||||||
|
|
||||||
|
/* TPI Asynchronous Clock Prescaler Register Definitions */
|
||||||
|
#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */
|
||||||
|
#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */
|
||||||
|
|
||||||
|
/* TPI Selected Pin Protocol Register Definitions */
|
||||||
|
#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */
|
||||||
|
#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */
|
||||||
|
|
||||||
|
/* TPI Formatter and Flush Status Register Definitions */
|
||||||
|
#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */
|
||||||
|
#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */
|
||||||
|
|
||||||
|
#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */
|
||||||
|
#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */
|
||||||
|
|
||||||
|
#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */
|
||||||
|
#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */
|
||||||
|
|
||||||
|
#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */
|
||||||
|
#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */
|
||||||
|
|
||||||
|
/* TPI Formatter and Flush Control Register Definitions */
|
||||||
|
#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */
|
||||||
|
#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */
|
||||||
|
|
||||||
|
#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */
|
||||||
|
#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */
|
||||||
|
|
||||||
|
#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */
|
||||||
|
#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */
|
||||||
|
|
||||||
|
/* TPI Periodic Synchronization Control Register Definitions */
|
||||||
|
#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */
|
||||||
|
#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */
|
||||||
|
|
||||||
|
/* TPI Software Lock Status Register Definitions */
|
||||||
|
#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */
|
||||||
|
#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */
|
||||||
|
|
||||||
|
#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */
|
||||||
|
#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */
|
||||||
|
|
||||||
|
#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */
|
||||||
|
#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */
|
||||||
|
|
||||||
|
/* TPI DEVID Register Definitions */
|
||||||
|
#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */
|
||||||
|
#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */
|
||||||
|
|
||||||
|
#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */
|
||||||
|
#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */
|
||||||
|
|
||||||
|
#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */
|
||||||
|
#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */
|
||||||
|
|
||||||
|
#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */
|
||||||
|
#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */
|
||||||
|
|
||||||
|
/* TPI DEVTYPE Register Definitions */
|
||||||
|
#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */
|
||||||
|
#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */
|
||||||
|
|
||||||
|
#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */
|
||||||
|
#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_TPI */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_MPU Memory Protection Unit (MPU)
|
||||||
|
\brief Type definitions for the Memory Protection Unit (MPU)
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Memory Protection Unit (MPU).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
|
||||||
|
__IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
|
||||||
|
__IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */
|
||||||
|
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
|
||||||
|
__IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */
|
||||||
|
uint32_t RESERVED0[7U];
|
||||||
|
union {
|
||||||
|
__IOM uint32_t MAIR[2];
|
||||||
|
struct {
|
||||||
|
__IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */
|
||||||
|
__IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} MPU_Type;
|
||||||
|
|
||||||
|
#define MPU_TYPE_RALIASES 1U
|
||||||
|
|
||||||
|
/* MPU Type Register Definitions */
|
||||||
|
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||||
|
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||||
|
|
||||||
|
#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
|
||||||
|
#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
|
||||||
|
|
||||||
|
#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
|
||||||
|
#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
|
||||||
|
|
||||||
|
/* MPU Control Register Definitions */
|
||||||
|
#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
|
||||||
|
#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
|
||||||
|
|
||||||
|
#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
|
||||||
|
#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
|
||||||
|
|
||||||
|
#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
|
||||||
|
#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
|
||||||
|
|
||||||
|
/* MPU Region Number Register Definitions */
|
||||||
|
#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
|
||||||
|
#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
|
||||||
|
|
||||||
|
/* MPU Region Base Address Register Definitions */
|
||||||
|
#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */
|
||||||
|
#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */
|
||||||
|
|
||||||
|
#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */
|
||||||
|
#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */
|
||||||
|
|
||||||
|
#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */
|
||||||
|
#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */
|
||||||
|
|
||||||
|
#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */
|
||||||
|
#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */
|
||||||
|
|
||||||
|
/* MPU Region Limit Address Register Definitions */
|
||||||
|
#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */
|
||||||
|
#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */
|
||||||
|
|
||||||
|
#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */
|
||||||
|
#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */
|
||||||
|
|
||||||
|
#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */
|
||||||
|
#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */
|
||||||
|
|
||||||
|
/* MPU Memory Attribute Indirection Register 0 Definitions */
|
||||||
|
#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */
|
||||||
|
#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */
|
||||||
|
|
||||||
|
#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */
|
||||||
|
#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */
|
||||||
|
|
||||||
|
#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */
|
||||||
|
#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */
|
||||||
|
|
||||||
|
#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */
|
||||||
|
#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */
|
||||||
|
|
||||||
|
/* MPU Memory Attribute Indirection Register 1 Definitions */
|
||||||
|
#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */
|
||||||
|
#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */
|
||||||
|
|
||||||
|
#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */
|
||||||
|
#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */
|
||||||
|
|
||||||
|
#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */
|
||||||
|
#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */
|
||||||
|
|
||||||
|
#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */
|
||||||
|
#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_MPU */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SAU Security Attribution Unit (SAU)
|
||||||
|
\brief Type definitions for the Security Attribution Unit (SAU)
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Security Attribution Unit (SAU).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */
|
||||||
|
__IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */
|
||||||
|
#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U)
|
||||||
|
__IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */
|
||||||
|
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */
|
||||||
|
__IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */
|
||||||
|
#endif
|
||||||
|
} SAU_Type;
|
||||||
|
|
||||||
|
/* SAU Control Register Definitions */
|
||||||
|
#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */
|
||||||
|
#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */
|
||||||
|
|
||||||
|
#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */
|
||||||
|
#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */
|
||||||
|
|
||||||
|
/* SAU Type Register Definitions */
|
||||||
|
#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */
|
||||||
|
#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */
|
||||||
|
|
||||||
|
#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U)
|
||||||
|
/* SAU Region Number Register Definitions */
|
||||||
|
#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */
|
||||||
|
#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */
|
||||||
|
|
||||||
|
/* SAU Region Base Address Register Definitions */
|
||||||
|
#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */
|
||||||
|
#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */
|
||||||
|
|
||||||
|
/* SAU Region Limit Address Register Definitions */
|
||||||
|
#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */
|
||||||
|
#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */
|
||||||
|
|
||||||
|
#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */
|
||||||
|
#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */
|
||||||
|
|
||||||
|
#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */
|
||||||
|
#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */
|
||||||
|
|
||||||
|
#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SAU */
|
||||||
|
#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||||
|
\brief Type definitions for the Core Debug Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Structure type to access the Core Debug Register (CoreDebug).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
|
||||||
|
__OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
|
||||||
|
__IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
|
||||||
|
__IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
|
||||||
|
uint32_t RESERVED4[1U];
|
||||||
|
__IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */
|
||||||
|
__IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */
|
||||||
|
} CoreDebug_Type;
|
||||||
|
|
||||||
|
/* Debug Halting Control and Status Register Definitions */
|
||||||
|
#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */
|
||||||
|
#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */
|
||||||
|
#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */
|
||||||
|
#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
|
||||||
|
#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */
|
||||||
|
#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */
|
||||||
|
#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */
|
||||||
|
#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */
|
||||||
|
#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */
|
||||||
|
#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */
|
||||||
|
#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */
|
||||||
|
#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
|
||||||
|
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
|
||||||
|
|
||||||
|
/* Debug Core Register Selector Register Definitions */
|
||||||
|
#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
|
||||||
|
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */
|
||||||
|
#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */
|
||||||
|
|
||||||
|
/* Debug Exception and Monitor Control Register */
|
||||||
|
#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */
|
||||||
|
#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */
|
||||||
|
#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */
|
||||||
|
#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
|
||||||
|
|
||||||
|
/* Debug Authentication Control Register Definitions */
|
||||||
|
#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */
|
||||||
|
#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */
|
||||||
|
#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */
|
||||||
|
#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */
|
||||||
|
#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */
|
||||||
|
|
||||||
|
/* Debug Security Control and Status Register Definitions */
|
||||||
|
#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */
|
||||||
|
#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */
|
||||||
|
#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */
|
||||||
|
|
||||||
|
#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */
|
||||||
|
#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_CoreDebug */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||||
|
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Mask and shift a bit field value for use in a register bit range.
|
||||||
|
\param[in] field Name of the register bit field.
|
||||||
|
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
|
||||||
|
\return Masked and shifted value.
|
||||||
|
*/
|
||||||
|
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Mask and shift a register value to extract a bit filed value.
|
||||||
|
\param[in] field Name of the register bit field.
|
||||||
|
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
|
||||||
|
\return Masked and shifted bit field value.
|
||||||
|
*/
|
||||||
|
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_core_bitfield */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_core_base Core Definitions
|
||||||
|
\brief Definitions for base addresses, unions, and structures.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory mapping of Core Hardware */
|
||||||
|
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||||
|
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
|
||||||
|
#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
|
||||||
|
#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
|
||||||
|
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||||
|
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||||
|
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||||
|
|
||||||
|
|
||||||
|
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||||
|
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||||
|
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||||
|
#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */
|
||||||
|
#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */
|
||||||
|
#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */
|
||||||
|
|
||||||
|
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||||
|
#define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
|
||||||
|
#define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||||
|
#define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */
|
||||||
|
#define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||||
|
#define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */
|
||||||
|
#define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */
|
||||||
|
#define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */
|
||||||
|
#define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */
|
||||||
|
#define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */
|
||||||
|
|
||||||
|
#define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */
|
||||||
|
#define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */
|
||||||
|
#define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */
|
||||||
|
#define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */
|
||||||
|
|
||||||
|
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||||
|
#define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */
|
||||||
|
#define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
|
||||||
|
/*@} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Hardware Abstraction Layer
|
||||||
|
Core Function Interface contains:
|
||||||
|
- Core NVIC Functions
|
||||||
|
- Core SysTick Functions
|
||||||
|
- Core Register Access Functions
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## NVIC functions #################################### */
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||||
|
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CMSIS_NVIC_VIRTUAL
|
||||||
|
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||||
|
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
|
||||||
|
#endif
|
||||||
|
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||||
|
#else
|
||||||
|
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
|
||||||
|
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
|
||||||
|
#define NVIC_EnableIRQ __NVIC_EnableIRQ
|
||||||
|
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
|
||||||
|
#define NVIC_DisableIRQ __NVIC_DisableIRQ
|
||||||
|
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
|
||||||
|
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
|
||||||
|
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
|
||||||
|
#define NVIC_GetActive __NVIC_GetActive
|
||||||
|
#define NVIC_SetPriority __NVIC_SetPriority
|
||||||
|
#define NVIC_GetPriority __NVIC_GetPriority
|
||||||
|
#define NVIC_SystemReset __NVIC_SystemReset
|
||||||
|
#endif /* CMSIS_NVIC_VIRTUAL */
|
||||||
|
|
||||||
|
#ifdef CMSIS_VECTAB_VIRTUAL
|
||||||
|
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||||
|
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
|
||||||
|
#endif
|
||||||
|
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||||
|
#else
|
||||||
|
#define NVIC_SetVector __NVIC_SetVector
|
||||||
|
#define NVIC_GetVector __NVIC_GetVector
|
||||||
|
#endif /* (CMSIS_VECTAB_VIRTUAL) */
|
||||||
|
|
||||||
|
#define NVIC_USER_IRQ_OFFSET 16
|
||||||
|
|
||||||
|
|
||||||
|
/* Special LR values for Secure/Non-Secure call handling and exception handling */
|
||||||
|
|
||||||
|
/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */
|
||||||
|
#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */
|
||||||
|
|
||||||
|
/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */
|
||||||
|
#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */
|
||||||
|
#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */
|
||||||
|
#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */
|
||||||
|
#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */
|
||||||
|
#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */
|
||||||
|
#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */
|
||||||
|
#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */
|
||||||
|
|
||||||
|
/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */
|
||||||
|
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */
|
||||||
|
#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */
|
||||||
|
#else
|
||||||
|
#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Interrupt Priorities are WORD accessible only under Armv6-M */
|
||||||
|
/* The following MACROS handle generation of the register offset and byte masks */
|
||||||
|
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||||
|
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||||
|
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||||
|
|
||||||
|
#define __NVIC_SetPriorityGrouping(X) (void)(X)
|
||||||
|
#define __NVIC_GetPriorityGrouping() (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable Interrupt
|
||||||
|
\details Enables a device specific interrupt in the NVIC interrupt controller.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Interrupt Enable status
|
||||||
|
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 Interrupt is not enabled.
|
||||||
|
\return 1 Interrupt is enabled.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable Interrupt
|
||||||
|
\details Disables a device specific interrupt in the NVIC interrupt controller.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||||
|
__DSB();
|
||||||
|
__ISB();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Pending Interrupt
|
||||||
|
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 Interrupt status is not pending.
|
||||||
|
\return 1 Interrupt status is pending.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Pending Interrupt
|
||||||
|
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Clear Pending Interrupt
|
||||||
|
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Active Interrupt
|
||||||
|
\details Reads the active register in the NVIC and returns the active bit for the device specific interrupt.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 Interrupt status is not active.
|
||||||
|
\return 1 Interrupt status is active.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||||
|
/**
|
||||||
|
\brief Get Interrupt Target State
|
||||||
|
\details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 if interrupt is assigned to Secure
|
||||||
|
\return 1 if interrupt is assigned to Non Secure
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Interrupt Target State
|
||||||
|
\details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 if interrupt is assigned to Secure
|
||||||
|
1 if interrupt is assigned to Non Secure
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)));
|
||||||
|
return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Clear Interrupt Target State
|
||||||
|
\details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 if interrupt is assigned to Secure
|
||||||
|
1 if interrupt is assigned to Non Secure
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)));
|
||||||
|
return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Interrupt Priority
|
||||||
|
\details Sets the priority of a device specific interrupt or a processor exception.
|
||||||
|
The interrupt number can be positive to specify a device specific interrupt,
|
||||||
|
or negative to specify a processor exception.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\param [in] priority Priority to set.
|
||||||
|
\note The priority cannot be set for every processor exception.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Interrupt Priority
|
||||||
|
\details Reads the priority of a device specific interrupt or a processor exception.
|
||||||
|
The interrupt number can be positive to specify a device specific interrupt,
|
||||||
|
or negative to specify a processor exception.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\return Interrupt Priority.
|
||||||
|
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Encode Priority
|
||||||
|
\details Encodes the priority for an interrupt with the given priority group,
|
||||||
|
preemptive priority value, and subpriority value.
|
||||||
|
In case of a conflict between priority grouping and available
|
||||||
|
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
|
||||||
|
\param [in] PriorityGroup Used priority group.
|
||||||
|
\param [in] PreemptPriority Preemptive priority value (starting from 0).
|
||||||
|
\param [in] SubPriority Subpriority value (starting from 0).
|
||||||
|
\return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||||
|
{
|
||||||
|
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||||
|
uint32_t PreemptPriorityBits;
|
||||||
|
uint32_t SubPriorityBits;
|
||||||
|
|
||||||
|
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||||
|
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||||
|
|
||||||
|
return (
|
||||||
|
((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
|
||||||
|
((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Decode Priority
|
||||||
|
\details Decodes an interrupt priority value with a given priority group to
|
||||||
|
preemptive priority value and subpriority value.
|
||||||
|
In case of a conflict between priority grouping and available
|
||||||
|
priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
|
||||||
|
\param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
|
||||||
|
\param [in] PriorityGroup Used priority group.
|
||||||
|
\param [out] pPreemptPriority Preemptive priority value (starting from 0).
|
||||||
|
\param [out] pSubPriority Subpriority value (starting from 0).
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
|
||||||
|
{
|
||||||
|
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||||
|
uint32_t PreemptPriorityBits;
|
||||||
|
uint32_t SubPriorityBits;
|
||||||
|
|
||||||
|
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||||
|
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||||
|
|
||||||
|
*pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
|
||||||
|
*pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Interrupt Vector
|
||||||
|
\details Sets an interrupt vector in SRAM based interrupt vector table.
|
||||||
|
The interrupt number can be positive to specify a device specific interrupt,
|
||||||
|
or negative to specify a processor exception.
|
||||||
|
VTOR must been relocated to SRAM before.
|
||||||
|
If VTOR is not present address 0 must be mapped to SRAM.
|
||||||
|
\param [in] IRQn Interrupt number
|
||||||
|
\param [in] vector Address of interrupt handler function
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||||
|
{
|
||||||
|
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
|
||||||
|
uint32_t *vectors = (uint32_t *)SCB->VTOR;
|
||||||
|
#else
|
||||||
|
uint32_t *vectors = (uint32_t *)0x0U;
|
||||||
|
#endif
|
||||||
|
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Interrupt Vector
|
||||||
|
\details Reads an interrupt vector from interrupt vector table.
|
||||||
|
The interrupt number can be positive to specify a device specific interrupt,
|
||||||
|
or negative to specify a processor exception.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\return Address of interrupt handler function
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
|
||||||
|
uint32_t *vectors = (uint32_t *)SCB->VTOR;
|
||||||
|
#else
|
||||||
|
uint32_t *vectors = (uint32_t *)0x0U;
|
||||||
|
#endif
|
||||||
|
return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief System Reset
|
||||||
|
\details Initiates a system reset request to reset the MCU.
|
||||||
|
*/
|
||||||
|
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
|
||||||
|
{
|
||||||
|
__DSB(); /* Ensure all outstanding memory accesses included
|
||||||
|
buffered write are completed before reset */
|
||||||
|
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||||
|
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||||
|
__DSB(); /* Ensure completion of memory access */
|
||||||
|
|
||||||
|
for(;;) /* wait until reset */
|
||||||
|
{
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||||
|
/**
|
||||||
|
\brief Enable Interrupt (non-secure)
|
||||||
|
\details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Interrupt Enable status (non-secure)
|
||||||
|
\details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 Interrupt is not enabled.
|
||||||
|
\return 1 Interrupt is enabled.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable Interrupt (non-secure)
|
||||||
|
\details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Pending Interrupt (non-secure)
|
||||||
|
\details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 Interrupt status is not pending.
|
||||||
|
\return 1 Interrupt status is pending.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Pending Interrupt (non-secure)
|
||||||
|
\details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Clear Pending Interrupt (non-secure)
|
||||||
|
\details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Active Interrupt (non-secure)
|
||||||
|
\details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt.
|
||||||
|
\param [in] IRQn Device specific interrupt number.
|
||||||
|
\return 0 Interrupt status is not active.
|
||||||
|
\return 1 Interrupt status is active.
|
||||||
|
\note IRQn must not be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(0U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Interrupt Priority (non-secure)
|
||||||
|
\details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state.
|
||||||
|
The interrupt number can be positive to specify a device specific interrupt,
|
||||||
|
or negative to specify a processor exception.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\param [in] priority Priority to set.
|
||||||
|
\note The priority cannot be set for every non-secure processor exception.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority)
|
||||||
|
{
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Get Interrupt Priority (non-secure)
|
||||||
|
\details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state.
|
||||||
|
The interrupt number can be positive to specify a device specific interrupt,
|
||||||
|
or negative to specify a processor exception.
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((int32_t)(IRQn) >= 0)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_NVICFunctions */
|
||||||
|
|
||||||
|
/* ########################## MPU functions #################################### */
|
||||||
|
|
||||||
|
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||||
|
|
||||||
|
#include "mpu_armv8.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ########################## FPU functions #################################### */
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_FpuFunctions FPU Functions
|
||||||
|
\brief Function that provides FPU type.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief get FPU type
|
||||||
|
\details returns the FPU type
|
||||||
|
\returns
|
||||||
|
- \b 0: No FPU
|
||||||
|
- \b 1: Single precision FPU
|
||||||
|
- \b 2: Double + Single precision FPU
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
|
||||||
|
{
|
||||||
|
return 0U; /* No FPU */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_FpuFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## SAU functions #################################### */
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_SAUFunctions SAU Functions
|
||||||
|
\brief Functions that configure the SAU.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Enable SAU
|
||||||
|
\details Enables the Security Attribution Unit (SAU).
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void TZ_SAU_Enable(void)
|
||||||
|
{
|
||||||
|
SAU->CTRL |= (SAU_CTRL_ENABLE_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Disable SAU
|
||||||
|
\details Disables the Security Attribution Unit (SAU).
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void TZ_SAU_Disable(void)
|
||||||
|
{
|
||||||
|
SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_SAUFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ################################## SysTick function ############################################ */
|
||||||
|
/**
|
||||||
|
\ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||||
|
\brief Functions that configure the System.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief System Tick Configuration
|
||||||
|
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||||
|
Counter is in free running mode to generate periodic interrupts.
|
||||||
|
\param [in] ticks Number of ticks between two interrupts.
|
||||||
|
\return 0 Function succeeded.
|
||||||
|
\return 1 Function failed.
|
||||||
|
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||||
|
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||||
|
must contain a vendor-specific implementation of this function.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||||
|
{
|
||||||
|
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||||
|
{
|
||||||
|
return (1UL); /* Reload value impossible */
|
||||||
|
}
|
||||||
|
|
||||||
|
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||||
|
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||||
|
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||||
|
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||||
|
SysTick_CTRL_TICKINT_Msk |
|
||||||
|
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||||
|
return (0UL); /* Function successful */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
||||||
|
/**
|
||||||
|
\brief System Tick Configuration (non-secure)
|
||||||
|
\details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer.
|
||||||
|
Counter is in free running mode to generate periodic interrupts.
|
||||||
|
\param [in] ticks Number of ticks between two interrupts.
|
||||||
|
\return 0 Function succeeded.
|
||||||
|
\return 1 Function failed.
|
||||||
|
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||||
|
function <b>TZ_SysTick_Config_NS</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||||
|
must contain a vendor-specific implementation of this function.
|
||||||
|
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks)
|
||||||
|
{
|
||||||
|
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||||
|
{
|
||||||
|
return (1UL); /* Reload value impossible */
|
||||||
|
}
|
||||||
|
|
||||||
|
SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||||
|
TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||||
|
SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||||
|
SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||||
|
SysTick_CTRL_TICKINT_Msk |
|
||||||
|
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||||
|
return (0UL); /* Function successful */
|
||||||
|
}
|
||||||
|
#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_ARMV8MBL_H_DEPENDANT */
|
||||||
|
|
||||||
|
#endif /* __CMSIS_GENERIC */
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user