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.
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
# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
# is applied to all files.
FILTER_PATTERNS =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse (i.e. when SOURCE_BROWSER is set to YES).
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# 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 also
# VERBATIM_HEADERS is set to NO.
SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = YES
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES
# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = YES
# 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.
REFERENCES_RELATION = YES
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
# 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.
REFERENCES_LINK_SOURCE = 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 http://www.gnu.org/software/global/global.html). You
# will need version 4.8.6 or higher.
USE_HTAGS = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) 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.
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# 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.
ALPHABETICAL_INDEX = NO
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
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. If left blank `html' will be used as the default path.
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). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
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 the tag is left blank doxygen
# will generate a default style sheet. Note that doxygen will try to copy
# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!
HTML_STYLESHEET =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the stylesheet and background images
# according to this color. Hue is specified as an angle on a colorwheel,
# see http://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.
# The allowed range is 0 to 359.
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
# grayscales only. A value of 255 will produce the most vivid colors.
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.
HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = YES
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = 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. For this to work a browser that supports
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
HTML_DYNAMIC_SECTIONS = NO
# 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, 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 http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
GENERATE_DOCSET = NO
# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
# 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.
DOCSET_FEEDNAME = "Doxygen generated docs"
# When GENERATE_DOCSET tag is set to YES, 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.
DOCSET_BUNDLE_ID = org.doxygen.Project
# When GENERATE_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.
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# If the GENERATE_HTMLHELP tag is set to YES, 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.
CHM_FILE =
# If the GENERATE_HTMLHELP tag is set to YES, 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.
HHC_LOCATION =
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
# content.
CHM_INDEX_ENCODING =
# If the GENERATE_HTMLHELP tag is set to YES, 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.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the HTML help documentation and to the tree view.
TOC_EXPAND = NO
# 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.
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.
QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#namespace
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
# http://doc.trolltech.com/qthelpproject.html#virtual-folders
QHP_VIRTUAL_FOLDER = doc
# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
# add. For more information please see
# http://doc.trolltech.com/qthelpproject.html#custom-filters
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see
#
# Qt Help Project / Custom Filters.
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.
QHP_SECT_FILTER_ATTRS =
# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
# be used to specify the location of Qt's qhelpgenerator.
# If non-empty doxygen will try to run qhelpgenerator on the generated
# .qhp file.
QHG_LOCATION =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
# will be generated, which together with the HTML files, 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.
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.
ECLIPSE_DOC_ID = org.doxygen.Project
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
# This tag can be used to set the number of enum values (range [1..20])
# that doxygen will group on one line in the generated HTML documentation.
ENUM_VALUES_PER_LINE = 1
# 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.
GENERATE_TREEVIEW = NO
# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
# and Class Hierarchy pages using a tree view instead of an ordered list.
USE_INLINE_TREES = 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.
TREEVIEW_WIDTH = 250
# When 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.
EXT_LINKS_IN_WINDOW = NO
# Use this tag to change the font size of Latex formulas included
# as images in the HTML documentation. The default is 10. Note that
# 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.
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are
# not supported properly for IE 6.0, but are supported on all modern browsers.
# Note that when changing this option you need to delete any form_*.png files
# in the HTML output before the changes have effect.
FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using prerendered 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 = NO
# 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.
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a PHP enabled web server instead of at the web client
# using Javascript. Doxygen will generate the search PHP script and index
# file to put on the web server. The advantage of the server
# based approach is that it scales better to large projects and allows
# full text search. The disadvances is that it is more difficult to setup
# and does not have live searching capabilities.
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
# 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. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
# Note that when enabling USE_PDFLATEX this option is only used for
# generating bitmaps for formulas in the HTML output, but not in the
# Makefile that is written to the output directory.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME = 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.
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, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal 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. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). 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.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
# include the index chapters (such as File Index, Compound Index, etc.)
# in the output.
LATEX_HIDE_INDICES = NO
# If LATEX_SOURCE_CODE is set to YES then doxygen will include
# source code with syntax highlighting in the LaTeX output.
# Note that which sources are shown also depends on other settings
# such as SOURCE_BROWSER.
LATEX_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# 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 very pretty with
# other RTF readers or editors.
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. If left blank `rtf' will be used as the default path.
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.
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 other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = YES
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
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. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
# 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 is NO.
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.
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. If left blank `xml' will be used as the default path.
XML_OUTPUT = xml
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
# 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.
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
# generate an AutoGen Definitions (see autogen.sf.net) file
# that captures the structure of the code including all
# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# 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.
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.
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.
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.
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
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 (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF 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.
EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
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.
INCLUDE_PATH = ../..
# 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.
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
# 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.
PREDEFINED = __DOXYGEN__ __AVR32_ABI_COMPILER__ __attribute__()= __GNUC__=4
# 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.
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all 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.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
# The TAGFILES option can be used to specify one or more tagfiles.
# Optionally an initial location of the external documentation
# can be added for each tagfile. 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. If a location is present for each tag, the installdox tool
# does not have to be run to correct the links.
# Note that 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.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
# or super classes. Setting the tag to NO turns the diagrams off. Note that
# this option is superseded by the HAVE_DOT option below. This is only a
# fallback. It is recommended to install and use dot, since it yields more
# powerful graphs.
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# 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.
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, 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)
HAVE_DOT = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
# allowed to run in parallel. When set to 0 (the default) 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.
DOT_NUM_THREADS = 0
# By default doxygen will write a font called FreeSans.ttf to the output
# directory and reference it in all dot files that doxygen generates. This
# font does not include all possible unicode characters however, so when you need
# these (or just want a differently looking font) you can specify the font name
# using DOT_FONTNAME. You need 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.
DOT_FONTNAME = FreeSans
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
# The default size is 10pt.
DOT_FONTSIZE = 10
# By default doxygen will tell dot to use the output directory to look for the
# FreeSans.ttf font (which doxygen will put there itself). If you specify a
# different font using DOT_FONTNAME you can set the path where dot
# can find it using this tag.
DOT_FONTPATH =
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are 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.
COLLABORATION_GRAPH = YES
# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for groups, showing the direct groups dependencies
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.
UML_LOOK = YES
# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# 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.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
# If the CALL_GRAPH and HAVE_DOT options are 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.
CALL_GRAPH = YES
# If the CALLER_GRAPH and HAVE_DOT tags are 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.
CALLER_GRAPH = NO
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are 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.
DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are png, jpg, or gif
# If left blank png will be used.
DOT_IMAGE_FORMAT = gif
# The tag DOT_PATH 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.
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).
DOTFILE_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 doxygen 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.
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.
MAX_DOT_GRAPH_DEPTH = 0
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not
# seem to support this out of the box. Warning: Depending on the platform used,
# enabling this option may lead to badly anti-aliased labels on the edges of
# a graph (i.e. they become hard to read).
DOT_TRANSPARENT = NO
# Set the DOT_MULTI_TARGETS tag to YES 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.
DOT_MULTI_TARGETS = YES
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermediate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
doxygen_module_mainpage.h 0000664 0000000 0000000 00000004454 13317465730 0036776 0 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/services/twi/doxygen/common.services.basic.twihs_0
/**
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
* \mainpage
*
* \section intro Introduction
* This documentation has been automatically generated, and documents the source
* code found in the Atmel Software Framework (ASF).
* Use the above menu to navigate in the documentation, or use the links below:
*
*
* \section main_licence License
*
* \section contactinfo Contact Information
* For further information, visit Atmel.\n
*
*/
dstat-firmware-master/src/asf/common/services/twi/twi_master.h 0000664 0000000 0000000 00000021745 13317465730 0025127 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief TWI Master Mode management
*
* Copyright (c) 2010-2014 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/**
* Support and FAQ: visit Atmel Support
*/
#ifndef TWI_MASTER_H_INCLUDED
#define TWI_MASTER_H_INCLUDED
#include
#if (SAM4L)
# include "sam_twim/twi_master.h"
#elif (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM)
# include "sam_twi/twi_master.h"
#elif XMEGA
# include "xmega_twi/twi_master.h"
#elif MEGA_RF
# include "megarf_twi/twi_master.h"
#elif UC3
# if (defined AVR32_TWI)
# include "uc3_twi/twi_master.h"
# else
# include "uc3_twim/twi_master.h"
# endif
#else
# error Unsupported chip type
#endif
/**
*
* \defgroup twi_group Two Wire-interface(TWI)
*
* This is the common API for TWIs. Additional features are available
* in the documentation of the specific modules.
*
* See \ref twi_quickstart.
*
* \section twi_group_platform Platform Dependencies
*
* The TWI API is partially chip- or platform-specific. While all
* platforms provide mostly the same functionality, there are some
* variations around how different bus types and clock tree structures
* are handled.
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behaviour. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - Master TWI Module initialization
* \code status_code_t twi_master_setup(*twi_module_pointer, twi_master_options_t *opt) \endcode
* - Enables TWI Module
* \code void twi_master_enable(*twi_module_pointer) \endcode
* - Disables TWI Module
* \code void twi_master_disable(*twi_module_pointer) \endcode
* - Read data from a slave device
* \code status_code_t twi_master_read(*twi_module_pointer, twi_package_t *package) \endcode
* - Write data from to a slave device
* \code status_code_t twi_master_write(*twi_module_pointer, twi_package_t *package) \endcode
*
* @{
*/
/**
* \typedef twi_master_t
* This type can be used independently to refer to TWI master module for the
* architecture used. It refers to the correct type definition for the
* architecture, ie. TWI_t* for XMEGA or avr32_twim_t* for UC3
*/
//! @}
/**
* \page twi_quickstart Quickstart guide for Common service TWI
*
* This is the quickstart guide for the \ref twi_group "Common service TWI",
* with step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section twi_basic_use_case Basic use case
* In the most basic use case, the TWI module is configured for
* - Master operation
* - addressing one slave device of the bus at address 0x50
* - TWI clock of 50kHz
* - polled read/write handling
*
* \section twi_basic_use_case_setup Setup steps
* \subsection twi_basic_use_case_setup_code Example code
* Add to your application C-file:
* \code
void twi_init(void)
{
twi_master_options_t opt = {
.speed = 50000,
.chip = 0x50
};
twi_master_setup(&TWIM0, &opt);
}
\endcode
*
* \subsection twi_basic_use_case_setup_flow Workflow
* -# Ensure that board_init() has configured selected I/Os for TWI function.
* -# Ensure that \ref conf_twim.h is present for the driver.
* - \note This file is only for the driver and should not be included by the
* user.
* -# Define and initialize config structs for TWI module in your TWI initialization
* function:
* - \code
twi_master_options_t opt = {
.speed = 50000,
.chip = 0x50
}; \endcode
* - field \ref speed sets the baudrate of the TWI bus
* - field \ref chip sets the address of the slave device you want to communicate with
* -# Call twi_master_setup and optionally check its return code
* - \note The config structs can be reused for other TWI modules
* after this step. Simply reconfigure and write to others modules.
*
* \section twi_basic_use_case_usage Usage steps
* \subsection twi_basic_use_case_usage_code_writing Example code : Writing to a slave device
* Use in application C-file:
* \code
const uint8_t test_pattern[] = {0x55,0xA5,0x5A,0x77,0x99};
twi_package_t packet_write = {
.addr = EEPROM_MEM_ADDR, // TWI slave memory address data
.addr_length = sizeof (uint16_t), // TWI slave memory address data size
.chip = EEPROM_BUS_ADDR, // TWI slave bus address
.buffer = (void *)test_pattern, // transfer data source buffer
.length = sizeof(test_pattern) // transfer data size (bytes)
};
while (twi_master_write(&TWIM0, &packet_write) != TWI_SUCCESS);
\endcode
*
* \subsection twi_basic_use_case_usage_flow Workflow
* -# Prepare the data you want to send to the slave device:
* - \code const uint8_t test_pattern[] = {0x55,0xA5,0x5A,0x77,0x99}; \endcode
* -# Prepare a twi_package_t structure
* \code twi_package_t packet_write; \endcode
* Fill all the fields of the structure :
* - addr is the address in the slave device
* - addr_length is the size of the address in the slave (support for large TWI memory devices)
* - chip sets the 7 bit address of the slave device you want to communicate with
* - buffer is a pointer on the data to write to slave
* - length is the number of data to write
*
* -# Finally, call twi_master_write \code twi_master_write(&TWIM0, &packet_write); \endcode
* and optionally check its return value for TWI_SUCCESS.
* \subsection twi_basic_use_case_usage_code_reading Example code : Reading from a slave device
* Use in application C-file:
* \code
uint8_t data_received[10];
twi_package_t packet_read = {
.addr = EEPROM_MEM_ADDR, // TWI slave memory address data
.addr_length = sizeof (uint16_t), // TWI slave memory address data size
.chip = EEPROM_BUS_ADDR, // TWI slave bus address
.buffer = data_received, // transfer data destination buffer
.length = 10 // transfer data size (bytes)
};
// Perform a multi-byte read access then check the result.
if(twi_master_read(&TWIM0, &packet_read) == TWI_SUCCESS){
//Check read content
if(data_received[0]==0x55)
do_something();
}
\endcode
*
* \subsection twi_basic_use_case_usage_flow Workflow
* -# Prepare a data buffer that will receive the data from the slave device:
* \code uint8_t data_received[10]; \endcode
* -# Prepare a twi_package_t structure
* \code twi_package_t packet_read; \endcode
* Fill all the fields of the structure :
* - addr is the address in the slave device
* - addr_length is the size of the address in the slave (support for large TWI memory devices)
* - chip sets the 7 bit address of the slave device you want to communicate with
* - buffer is a pointer on the data buffer that will receive the data from the slave device
* - length is the number of data to read
*
* -# Finally, call twi_master_read \code twi_master_read(&TWIM0, &packet_read); \endcode
* and optionally check its return value for TWI_SUCCESS.
* the data read from the device are now in data_received.
*/
#endif /* TWI_MASTER_H_INCLUDED */
dstat-firmware-master/src/asf/common/services/twi/xmega_twi/ 0000775 0000000 0000000 00000000000 13317465730 0024553 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/services/twi/xmega_twi/twi_master.h 0000664 0000000 0000000 00000004730 13317465730 0027106 0 ustar 00root root 0000000 0000000 /*****************************************************************************
*
* \file
*
* \brief TWI Master driver for AVR Xmega.
*
* This file defines a useful set of functions for the TWI interface on AVR Xmega
* devices.
*
* Copyright (c) 2009-2014 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
******************************************************************************/
/**
* Support and FAQ: visit Atmel Support
*/
#ifndef _TWI_MASTER_H_
#define _TWI_MASTER_H_
#include "sysclk.h"
#include "twim.h"
typedef TWI_t *twi_master_t;
typedef twi_options_t twi_master_options_t;
static inline int twi_master_setup(twi_master_t twi, twi_master_options_t *opt)
{
opt->speed_reg = TWI_BAUD(sysclk_get_cpu_hz(),opt->speed);
sysclk_enable_peripheral_clock(twi);
return twi_master_init(twi,opt);
}
#endif // _TWI_MASTER_H_
dstat-firmware-master/src/asf/common/services/usb/ 0000775 0000000 0000000 00000000000 13317465730 0022555 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/services/usb/class/ 0000775 0000000 0000000 00000000000 13317465730 0023662 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/services/usb/class/cdc/ 0000775 0000000 0000000 00000000000 13317465730 0024413 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/services/usb/class/cdc/device/ 0000775 0000000 0000000 00000000000 13317465730 0025652 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/services/usb/class/cdc/device/udi_cdc.c 0000664 0000000 0000000 00000063675 13317465730 0027431 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief USB Device Communication Device Class (CDC) interface.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "conf_usb.h"
#include "usb_protocol.h"
#include "usb_protocol_cdc.h"
#include "udd.h"
#include "udc.h"
#include "udi_cdc.h"
#include
#ifdef UDI_CDC_LOW_RATE
# ifdef USB_DEVICE_HS_SUPPORT
# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE)
# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE)
# else
# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE)
# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_FS_SIZE)
# endif
#else
# ifdef USB_DEVICE_HS_SUPPORT
# define UDI_CDC_TX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE)
# define UDI_CDC_RX_BUFFERS (UDI_CDC_DATA_EPS_HS_SIZE)
# else
# define UDI_CDC_TX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE)
# define UDI_CDC_RX_BUFFERS (5*UDI_CDC_DATA_EPS_FS_SIZE)
# endif
#endif
/**
* \ingroup udi_cdc_group
* \defgroup udi_cdc_group_udc Interface with USB Device Core (UDC)
*
* Structures and functions required by UDC.
*
* @{
*/
bool udi_cdc_comm_enable(void);
void udi_cdc_comm_disable(void);
bool udi_cdc_comm_setup(void);
bool udi_cdc_data_enable(void);
void udi_cdc_data_disable(void);
bool udi_cdc_data_setup(void);
uint8_t udi_cdc_getsetting(void);
void udi_cdc_data_sof_notify(void);
UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm = {
.enable = udi_cdc_comm_enable,
.disable = udi_cdc_comm_disable,
.setup = udi_cdc_comm_setup,
.getsetting = udi_cdc_getsetting,
};
UDC_DESC_STORAGE udi_api_t udi_api_cdc_data = {
.enable = udi_cdc_data_enable,
.disable = udi_cdc_data_disable,
.setup = udi_cdc_data_setup,
.getsetting = udi_cdc_getsetting,
.sof_notify = udi_cdc_data_sof_notify,
};
//@}
/**
* \ingroup udi_cdc_group
* \defgroup udi_cdc_group_internal Implementation of UDI CDC
*
* Class internal implementation
* @{
*/
/**
* \name Internal routines
*/
//@{
/**
* \name Routines to control serial line
*/
//@{
/**
* \brief Returns the port number corresponding at current setup request
*
* \return port number
*/
static uint8_t udi_cdc_setup_to_port(void);
/**
* \brief Sends line coding to application
*
* Called after SETUP request when line coding data is received.
*/
static void udi_cdc_line_coding_received(void);
/**
* \brief Records new state
*
* \param port Communication port number to manage
* \param b_set State is enabled if true, else disabled
* \param bit_mask Field to process (see CDC_SERIAL_STATE_ defines)
*/
static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask);
/**
* \brief Check and eventually notify the USB host of new state
*
* \param port Communication port number to manage
* \param ep Port communication endpoint
*/
static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep);
/**
* \brief Ack sent of serial state message
* Callback called after serial state message sent
*
* \param status UDD_EP_TRANSFER_OK, if transfer finished
* \param status UDD_EP_TRANSFER_ABORT, if transfer aborted
* \param n number of data transfered
*/
static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep);
//@}
/**
* \name Routines to process data transfer
*/
//@{
/**
* \brief Enable the reception of data from the USB host
*
* The value udi_cdc_rx_trans_sel indicate the RX buffer to fill.
*
* \param port Communication port number to manage
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
static bool udi_cdc_rx_start(uint8_t port);
/**
* \brief Update rx buffer management with a new data
* Callback called after data reception on USB line
*
* \param status UDD_EP_TRANSFER_OK, if transfer finish
* \param status UDD_EP_TRANSFER_ABORT, if transfer aborted
* \param n number of data received
*/
static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep);
/**
* \brief Ack sent of tx buffer
* Callback called after data transfer on USB line
*
* \param status UDD_EP_TRANSFER_OK, if transfer finished
* \param status UDD_EP_TRANSFER_ABORT, if transfer aborted
* \param n number of data transfered
*/
static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep);
/**
* \brief Send buffer on line or wait a SOF event
*
* \param port Communication port number to manage
*/
static void udi_cdc_tx_send(uint8_t port);
//@}
//@}
/**
* \name Information about configuration of communication line
*/
//@{
static usb_cdc_line_coding_t udi_cdc_line_coding[UDI_CDC_PORT_NB];
static bool udi_cdc_serial_state_msg_ongoing[UDI_CDC_PORT_NB];
static volatile le16_t udi_cdc_state[UDI_CDC_PORT_NB];
COMPILER_WORD_ALIGNED static usb_cdc_notify_serial_state_t uid_cdc_state_msg[UDI_CDC_PORT_NB];
//! Status of CDC COMM interfaces
static volatile uint8_t udi_cdc_nb_comm_enabled = 0;
//@}
/**
* \name Variables to manage RX/TX transfer requests
* Two buffers for each sense are used to optimize the speed.
*/
//@{
//! Status of CDC DATA interfaces
static volatile uint8_t udi_cdc_nb_data_enabled = 0;
static volatile bool udi_cdc_data_running = false;
//! Buffer to receive data
COMPILER_WORD_ALIGNED static uint8_t udi_cdc_rx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_RX_BUFFERS];
//! Data available in RX buffers
static uint16_t udi_cdc_rx_buf_nb[UDI_CDC_PORT_NB][2];
//! Give the current RX buffer used (rx0 if 0, rx1 if 1)
static volatile uint8_t udi_cdc_rx_buf_sel[UDI_CDC_PORT_NB];
//! Read position in current RX buffer
static volatile uint16_t udi_cdc_rx_pos[UDI_CDC_PORT_NB];
//! Signal a transfer on-going
static volatile bool udi_cdc_rx_trans_ongoing[UDI_CDC_PORT_NB];
//! Define a transfer halted
#define UDI_CDC_TRANS_HALTED 2
//! Buffer to send data
COMPILER_WORD_ALIGNED static uint8_t udi_cdc_tx_buf[UDI_CDC_PORT_NB][2][UDI_CDC_TX_BUFFERS];
//! Data available in TX buffers
static uint16_t udi_cdc_tx_buf_nb[UDI_CDC_PORT_NB][2];
//! Give current TX buffer used (tx0 if 0, tx1 if 1)
static volatile uint8_t udi_cdc_tx_buf_sel[UDI_CDC_PORT_NB];
//! Value of SOF during last TX transfer
static uint16_t udi_cdc_tx_sof_num[UDI_CDC_PORT_NB];
//! Signal a transfer on-going
static volatile bool udi_cdc_tx_trans_ongoing[UDI_CDC_PORT_NB];
//! Signal that both buffer content data to send
static volatile bool udi_cdc_tx_both_buf_to_send[UDI_CDC_PORT_NB];
//@}
bool udi_cdc_comm_enable(void)
{
uint8_t port;
uint8_t iface_comm_num;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
udi_cdc_nb_comm_enabled = 0;
#else
if (udi_cdc_nb_comm_enabled > UDI_CDC_PORT_NB) {
udi_cdc_nb_comm_enabled = 0;
}
port = udi_cdc_nb_comm_enabled;
#endif
// Initialize control signal management
udi_cdc_state[port] = CPU_TO_LE16(0);
uid_cdc_state_msg[port].header.bmRequestType =
USB_REQ_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_RECIP_INTERFACE;
uid_cdc_state_msg[port].header.bNotification = USB_REQ_CDC_NOTIFY_SERIAL_STATE;
uid_cdc_state_msg[port].header.wValue = LE16(0);
switch (port) {
#define UDI_CDC_PORT_TO_IFACE_COMM(index, unused) \
case index: \
iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_##index; \
break;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_IFACE_COMM, ~)
#undef UDI_CDC_PORT_TO_IFACE_COMM
default:
iface_comm_num = UDI_CDC_COMM_IFACE_NUMBER_0;
break;
}
uid_cdc_state_msg[port].header.wIndex = LE16(iface_comm_num);
uid_cdc_state_msg[port].header.wLength = LE16(2);
uid_cdc_state_msg[port].value = CPU_TO_LE16(0);
udi_cdc_line_coding[port].dwDTERate = CPU_TO_LE32(UDI_CDC_DEFAULT_RATE);
udi_cdc_line_coding[port].bCharFormat = UDI_CDC_DEFAULT_STOPBITS;
udi_cdc_line_coding[port].bParityType = UDI_CDC_DEFAULT_PARITY;
udi_cdc_line_coding[port].bDataBits = UDI_CDC_DEFAULT_DATABITS;
// Call application callback
// to initialize memories or indicate that interface is enabled
UDI_CDC_SET_CODING_EXT(port,(&udi_cdc_line_coding[port]));
if (!UDI_CDC_ENABLE_EXT(port)) {
return false;
}
udi_cdc_nb_comm_enabled++;
return true;
}
bool udi_cdc_data_enable(void)
{
uint8_t port;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
udi_cdc_nb_data_enabled = 0;
#else
if (udi_cdc_nb_data_enabled > UDI_CDC_PORT_NB) {
udi_cdc_nb_data_enabled = 0;
}
port = udi_cdc_nb_data_enabled;
#endif
// Initialize TX management
udi_cdc_tx_trans_ongoing[port] = false;
udi_cdc_tx_both_buf_to_send[port] = false;
udi_cdc_tx_buf_sel[port] = 0;
udi_cdc_tx_buf_nb[port][0] = 0;
udi_cdc_tx_buf_nb[port][1] = 0;
udi_cdc_tx_sof_num[port] = 0;
udi_cdc_tx_send(port);
// Initialize RX management
udi_cdc_rx_trans_ongoing[port] = false;
udi_cdc_rx_buf_sel[port] = 0;
udi_cdc_rx_buf_nb[port][0] = 0;
udi_cdc_rx_pos[port] = 0;
if (!udi_cdc_rx_start(port)) {
return false;
}
udi_cdc_nb_data_enabled++;
if (udi_cdc_nb_data_enabled == UDI_CDC_PORT_NB) {
udi_cdc_data_running = true;
}
return true;
}
void udi_cdc_comm_disable(void)
{
Assert(udi_cdc_nb_comm_enabled != 0);
udi_cdc_nb_comm_enabled--;
}
void udi_cdc_data_disable(void)
{
uint8_t port;
Assert(udi_cdc_nb_data_enabled != 0);
udi_cdc_nb_data_enabled--;
port = udi_cdc_nb_data_enabled;
UDI_CDC_DISABLE_EXT(port);
udi_cdc_data_running = false;
}
bool udi_cdc_comm_setup(void)
{
uint8_t port = udi_cdc_setup_to_port();
if (Udd_setup_is_in()) {
// GET Interface Requests
if (Udd_setup_type() == USB_REQ_TYPE_CLASS) {
// Requests Class Interface Get
switch (udd_g_ctrlreq.req.bRequest) {
case USB_REQ_CDC_GET_LINE_CODING:
// Get configuration of CDC line
if (sizeof(usb_cdc_line_coding_t) !=
udd_g_ctrlreq.req.wLength)
return false; // Error for USB host
udd_g_ctrlreq.payload =
(uint8_t *) &
udi_cdc_line_coding[port];
udd_g_ctrlreq.payload_size =
sizeof(usb_cdc_line_coding_t);
return true;
}
}
}
if (Udd_setup_is_out()) {
// SET Interface Requests
if (Udd_setup_type() == USB_REQ_TYPE_CLASS) {
// Requests Class Interface Set
switch (udd_g_ctrlreq.req.bRequest) {
case USB_REQ_CDC_SET_LINE_CODING:
// Change configuration of CDC line
if (sizeof(usb_cdc_line_coding_t) !=
udd_g_ctrlreq.req.wLength)
return false; // Error for USB host
udd_g_ctrlreq.callback =
udi_cdc_line_coding_received;
udd_g_ctrlreq.payload =
(uint8_t *) &
udi_cdc_line_coding[port];
udd_g_ctrlreq.payload_size =
sizeof(usb_cdc_line_coding_t);
return true;
case USB_REQ_CDC_SET_CONTROL_LINE_STATE:
// According cdc spec 1.1 chapter 6.2.14
UDI_CDC_SET_DTR_EXT(port, (0 !=
(udd_g_ctrlreq.req.wValue
& CDC_CTRL_SIGNAL_DTE_PRESENT)));
UDI_CDC_SET_RTS_EXT(port, (0 !=
(udd_g_ctrlreq.req.wValue
& CDC_CTRL_SIGNAL_ACTIVATE_CARRIER)));
return true;
}
}
}
return false; // request Not supported
}
bool udi_cdc_data_setup(void)
{
return false; // request Not supported
}
uint8_t udi_cdc_getsetting(void)
{
return 0; // CDC don't have multiple alternate setting
}
void udi_cdc_data_sof_notify(void)
{
static uint8_t port_notify = 0;
// A call of udi_cdc_data_sof_notify() is done for each port
udi_cdc_tx_send(port_notify);
#if UDI_CDC_PORT_NB != 1 // To optimize code
port_notify++;
if (port_notify >= UDI_CDC_PORT_NB) {
port_notify = 0;
}
#endif
}
//-------------------------------------------------
//------- Internal routines to control serial line
static uint8_t udi_cdc_setup_to_port(void)
{
uint8_t port;
switch (udd_g_ctrlreq.req.wIndex & 0xFF) {
#define UDI_CDC_IFACE_COMM_TO_PORT(iface, unused) \
case UDI_CDC_COMM_IFACE_NUMBER_##iface: \
port = iface; \
break;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_IFACE_COMM_TO_PORT, ~)
#undef UDI_CDC_IFACE_COMM_TO_PORT
default:
port = 0;
break;
}
return port;
}
static void udi_cdc_line_coding_received(void)
{
uint8_t port = udi_cdc_setup_to_port();
UDI_CDC_SET_CODING_EXT(port, (&udi_cdc_line_coding[port]));
}
static void udi_cdc_ctrl_state_change(uint8_t port, bool b_set, le16_t bit_mask)
{
irqflags_t flags;
udd_ep_id_t ep_comm;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
// Update state
flags = cpu_irq_save(); // Protect udi_cdc_state
if (b_set) {
udi_cdc_state[port] |= bit_mask;
} else {
udi_cdc_state[port] &= ~(unsigned)bit_mask;
}
cpu_irq_restore(flags);
// Send it if possible and state changed
switch (port) {
#define UDI_CDC_PORT_TO_COMM_EP(index, unused) \
case index: \
ep_comm = UDI_CDC_COMM_EP_##index; \
break;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_COMM_EP, ~)
#undef UDI_CDC_PORT_TO_COMM_EP
default:
ep_comm = UDI_CDC_COMM_EP_0;
break;
}
udi_cdc_ctrl_state_notify(port, ep_comm);
}
static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep)
{
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
// Send it if possible and state changed
if ((!udi_cdc_serial_state_msg_ongoing[port])
&& (udi_cdc_state[port] != uid_cdc_state_msg[port].value)) {
// Fill notification message
uid_cdc_state_msg[port].value = udi_cdc_state[port];
// Send notification message
udi_cdc_serial_state_msg_ongoing[port] =
udd_ep_run(ep,
false,
(uint8_t *) & uid_cdc_state_msg[port],
sizeof(uid_cdc_state_msg[0]),
udi_cdc_serial_state_msg_sent);
}
}
static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep)
{
uint8_t port;
UNUSED(n);
UNUSED(status);
switch (ep) {
#define UDI_CDC_GET_PORT_FROM_COMM_EP(iface, unused) \
case UDI_CDC_COMM_EP_##iface: \
port = iface; \
break;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_GET_PORT_FROM_COMM_EP, ~)
#undef UDI_CDC_GET_PORT_FROM_COMM_EP
default:
port = 0;
break;
}
udi_cdc_serial_state_msg_ongoing[port] = false;
// For the irregular signals like break, the incoming ring signal,
// or the overrun error state, this will reset their values to zero
// and again will not send another notification until their state changes.
udi_cdc_state[port] &= ~(CDC_SERIAL_STATE_BREAK |
CDC_SERIAL_STATE_RING |
CDC_SERIAL_STATE_FRAMING |
CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN);
uid_cdc_state_msg[port].value &= ~(CDC_SERIAL_STATE_BREAK |
CDC_SERIAL_STATE_RING |
CDC_SERIAL_STATE_FRAMING |
CDC_SERIAL_STATE_PARITY | CDC_SERIAL_STATE_OVERRUN);
// Send it if possible and state changed
udi_cdc_ctrl_state_notify(port, ep);
}
//-------------------------------------------------
//------- Internal routines to process data transfer
static bool udi_cdc_rx_start(uint8_t port)
{
irqflags_t flags;
uint8_t buf_sel_trans;
udd_ep_id_t ep;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
flags = cpu_irq_save();
buf_sel_trans = udi_cdc_rx_buf_sel[port];
if (udi_cdc_rx_trans_ongoing[port] ||
(udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) {
// Transfer already on-going or current buffer no empty
cpu_irq_restore(flags);
return false;
}
// Change current buffer
udi_cdc_rx_pos[port] = 0;
udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0;
// Start transfer on RX
udi_cdc_rx_trans_ongoing[port] = true;
cpu_irq_restore(flags);
if (udi_cdc_multi_is_rx_ready(port)) {
UDI_CDC_RX_NOTIFY(port);
}
// Send the buffer with enable of short packet
switch (port) {
#define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \
case index: \
ep = UDI_CDC_DATA_EP_OUT_##index; \
break;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~)
#undef UDI_CDC_PORT_TO_DATA_EP_OUT
default:
ep = UDI_CDC_DATA_EP_OUT_0;
break;
}
return udd_ep_run(ep,
true,
udi_cdc_rx_buf[port][buf_sel_trans],
UDI_CDC_RX_BUFFERS,
udi_cdc_data_received);
}
static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep)
{
uint8_t buf_sel_trans;
uint8_t port;
switch (ep) {
#define UDI_CDC_DATA_EP_OUT_TO_PORT(index, unused) \
case UDI_CDC_DATA_EP_OUT_##index: \
port = index; \
break;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_OUT_TO_PORT, ~)
#undef UDI_CDC_DATA_EP_OUT_TO_PORT
default:
port = 0;
break;
}
if (UDD_EP_TRANSFER_OK != status) {
// Abort reception
return;
}
buf_sel_trans = (udi_cdc_rx_buf_sel[port]==0)?1:0;
if (!n) {
udd_ep_run( ep,
true,
udi_cdc_rx_buf[port][buf_sel_trans],
UDI_CDC_RX_BUFFERS,
udi_cdc_data_received);
return;
}
udi_cdc_rx_buf_nb[port][buf_sel_trans] = n;
udi_cdc_rx_trans_ongoing[port] = false;
udi_cdc_rx_start(port);
}
static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep)
{
uint8_t port;
UNUSED(n);
switch (ep) {
#define UDI_CDC_DATA_EP_IN_TO_PORT(index, unused) \
case UDI_CDC_DATA_EP_IN_##index: \
port = index; \
break;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DATA_EP_IN_TO_PORT, ~)
#undef UDI_CDC_DATA_EP_IN_TO_PORT
default:
port = 0;
break;
}
if (UDD_EP_TRANSFER_OK != status) {
// Abort transfer
return;
}
udi_cdc_tx_buf_nb[port][(udi_cdc_tx_buf_sel[port]==0)?1:0] = 0;
udi_cdc_tx_both_buf_to_send[port] = false;
udi_cdc_tx_trans_ongoing[port] = false;
udi_cdc_tx_send(port);
}
static void udi_cdc_tx_send(uint8_t port)
{
irqflags_t flags;
uint8_t buf_sel_trans;
bool b_short_packet;
udd_ep_id_t ep;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
if (udi_cdc_tx_trans_ongoing[port]) {
return; // Already on going or wait next SOF to send next data
}
if (udd_is_high_speed()) {
if (udi_cdc_tx_sof_num[port] == udd_get_micro_frame_number()) {
return; // Wait next SOF to send next data
}
}else{
if (udi_cdc_tx_sof_num[port] == udd_get_frame_number()) {
return; // Wait next SOF to send next data
}
}
flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel
buf_sel_trans = udi_cdc_tx_buf_sel[port];
if (!udi_cdc_tx_both_buf_to_send[port]) {
// Send current Buffer
// and switch the current buffer
udi_cdc_tx_buf_sel[port] = (buf_sel_trans==0)?1:0;
}else{
// Send the other Buffer
// and no switch the current buffer
buf_sel_trans = (buf_sel_trans==0)?1:0;
}
udi_cdc_tx_trans_ongoing[port] = true;
cpu_irq_restore(flags);
b_short_packet = (udi_cdc_tx_buf_nb[port][buf_sel_trans] != UDI_CDC_TX_BUFFERS);
if (b_short_packet) {
if (udd_is_high_speed()) {
udi_cdc_tx_sof_num[port] = udd_get_micro_frame_number();
}else{
udi_cdc_tx_sof_num[port] = udd_get_frame_number();
}
}else{
udi_cdc_tx_sof_num[port] = 0; // Force next transfer without wait SOF
}
// Send the buffer with enable of short packet
switch (port) {
#define UDI_CDC_PORT_TO_DATA_EP_IN(index, unused) \
case index: \
ep = UDI_CDC_DATA_EP_IN_##index; \
break;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_IN, ~)
#undef UDI_CDC_PORT_TO_DATA_EP_IN
default:
ep = UDI_CDC_DATA_EP_IN_0;
break;
}
udd_ep_run( ep,
b_short_packet,
udi_cdc_tx_buf[port][buf_sel_trans],
udi_cdc_tx_buf_nb[port][buf_sel_trans],
udi_cdc_data_sent);
}
//---------------------------------------------
//------- Application interface
//------- Application interface
void udi_cdc_ctrl_signal_dcd(bool b_set)
{
udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DCD);
}
void udi_cdc_ctrl_signal_dsr(bool b_set)
{
udi_cdc_ctrl_state_change(0, b_set, CDC_SERIAL_STATE_DSR);
}
void udi_cdc_signal_framing_error(void)
{
udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_FRAMING);
}
void udi_cdc_signal_parity_error(void)
{
udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_PARITY);
}
void udi_cdc_signal_overrun(void)
{
udi_cdc_ctrl_state_change(0, true, CDC_SERIAL_STATE_OVERRUN);
}
void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set)
{
udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DCD);
}
void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set)
{
udi_cdc_ctrl_state_change(port, b_set, CDC_SERIAL_STATE_DSR);
}
void udi_cdc_multi_signal_framing_error(uint8_t port)
{
udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_FRAMING);
}
void udi_cdc_multi_signal_parity_error(uint8_t port)
{
udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_PARITY);
}
void udi_cdc_multi_signal_overrun(uint8_t port)
{
udi_cdc_ctrl_state_change(port, true, CDC_SERIAL_STATE_OVERRUN);
}
bool udi_cdc_multi_is_rx_ready(uint8_t port)
{
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
uint16_t pos = udi_cdc_rx_pos[port];
return (pos < udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]]);
}
bool udi_cdc_is_rx_ready(void)
{
return udi_cdc_multi_is_rx_ready(0);
}
int udi_cdc_multi_getc(uint8_t port)
{
int rx_data = 0;
bool b_databit_9;
uint16_t pos;
uint8_t buf_sel;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits);
udi_cdc_getc_process_one_byte:
// Check available data
pos = udi_cdc_rx_pos[port];
buf_sel = udi_cdc_rx_buf_sel[port];
while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) {
if (!udi_cdc_data_running) {
return 0;
}
goto udi_cdc_getc_process_one_byte;
}
// Read data
rx_data |= udi_cdc_rx_buf[port][buf_sel][pos];
udi_cdc_rx_pos[port] = pos+1;
udi_cdc_rx_start(port);
if (b_databit_9) {
// Receive MSB
b_databit_9 = false;
rx_data = rx_data << 8;
goto udi_cdc_getc_process_one_byte;
}
return rx_data;
}
int udi_cdc_getc(void)
{
return udi_cdc_multi_getc(0);
}
iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size)
{
uint8_t *ptr_buf = (uint8_t *)buf;
iram_size_t copy_nb;
uint16_t pos;
uint8_t buf_sel;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
udi_cdc_read_buf_loop_wait:
// Check available data
pos = udi_cdc_rx_pos[port];
buf_sel = udi_cdc_rx_buf_sel[port];
while (pos >= udi_cdc_rx_buf_nb[port][buf_sel]) {
if (!udi_cdc_data_running) {
return size;
}
goto udi_cdc_read_buf_loop_wait;
}
// Read data
copy_nb = udi_cdc_rx_buf_nb[port][buf_sel] - pos;
if (copy_nb>size) {
copy_nb = size;
}
memcpy(ptr_buf, &udi_cdc_rx_buf[port][buf_sel][pos], copy_nb);
udi_cdc_rx_pos[port] += copy_nb;
ptr_buf += copy_nb;
size -= copy_nb;
udi_cdc_rx_start(port);
if (size) {
goto udi_cdc_read_buf_loop_wait;
}
return 0;
}
iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size)
{
return udi_cdc_multi_read_buf(0, buf, size);
}
bool udi_cdc_multi_is_tx_ready(uint8_t port)
{
irqflags_t flags;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
if (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS) {
return true;
}
if (!udi_cdc_tx_both_buf_to_send[port]) {
flags = cpu_irq_save(); // to protect udi_cdc_tx_buf_sel
if (!udi_cdc_tx_trans_ongoing[port]) {
// No transfer on-going
// then use the other buffer to store data
udi_cdc_tx_both_buf_to_send[port] = true;
udi_cdc_tx_buf_sel[port] = (udi_cdc_tx_buf_sel[port]==0)?1:0;
}
cpu_irq_restore(flags);
}
return (udi_cdc_tx_buf_nb[port][udi_cdc_tx_buf_sel[port]]!=UDI_CDC_TX_BUFFERS);
}
bool udi_cdc_is_tx_ready(void)
{
return udi_cdc_multi_is_tx_ready(0);
}
int udi_cdc_multi_putc(uint8_t port, int value)
{
irqflags_t flags;
bool b_databit_9;
uint8_t buf_sel;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
b_databit_9 = (9 == udi_cdc_line_coding[port].bDataBits);
udi_cdc_putc_process_one_byte:
// Check available space
if (!udi_cdc_multi_is_tx_ready(port)) {
if (!udi_cdc_data_running) {
return false;
}
goto udi_cdc_putc_process_one_byte;
}
// Write value
flags = cpu_irq_save();
buf_sel = udi_cdc_tx_buf_sel[port];
udi_cdc_tx_buf[port][buf_sel][udi_cdc_tx_buf_nb[port][buf_sel]++] = value;
cpu_irq_restore(flags);
if (b_databit_9) {
// Send MSB
b_databit_9 = false;
value = value >> 8;
goto udi_cdc_putc_process_one_byte;
}
return true;
}
int udi_cdc_putc(int value)
{
return udi_cdc_multi_putc(0, value);
}
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size)
{
irqflags_t flags;
uint8_t buf_sel;
uint16_t buf_nb;
iram_size_t copy_nb;
uint8_t *ptr_buf = (uint8_t *)buf;
#if UDI_CDC_PORT_NB == 1 // To optimize code
port = 0;
#endif
if (9 == udi_cdc_line_coding[port].bDataBits) {
size *=2;
}
udi_cdc_write_buf_loop_wait:
// Check available space
if (!udi_cdc_multi_is_tx_ready(port)) {
if (!udi_cdc_data_running) {
return size;
}
goto udi_cdc_write_buf_loop_wait;
}
// Write values
flags = cpu_irq_save();
buf_sel = udi_cdc_tx_buf_sel[port];
buf_nb = udi_cdc_tx_buf_nb[port][buf_sel];
copy_nb = UDI_CDC_TX_BUFFERS - buf_nb;
if (copy_nb>size) {
copy_nb = size;
}
memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb);
udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb;
cpu_irq_restore(flags);
// Update buffer pointer
ptr_buf = ptr_buf + copy_nb;
size -= copy_nb;
if (size) {
goto udi_cdc_write_buf_loop_wait;
}
return 0;
}
iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size)
{
return udi_cdc_multi_write_buf(0, buf, size);
}
//@}
dstat-firmware-master/src/asf/common/services/usb/class/cdc/device/udi_cdc.h 0000664 0000000 0000000 00000063521 13317465730 0027424 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief USB Device Communication Device Class (CDC) interface definitions.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _UDI_CDC_H_
#define _UDI_CDC_H_
#include "conf_usb.h"
#include "usb_protocol.h"
#include "usb_protocol_cdc.h"
#include "udd.h"
#include "udc_desc.h"
#include "udi.h"
// Check the number of port
#ifndef UDI_CDC_PORT_NB
# define UDI_CDC_PORT_NB 1
#endif
#if (UDI_CDC_PORT_NB < 1) || (UDI_CDC_PORT_NB > 7)
# error UDI_CDC_PORT_NB must be between 1 and 7
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup udi_cdc_group_udc
* @{
*/
//! Global structure which contains standard UDI API for UDC
extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_comm;
extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data;
//@}
/**
* \ingroup udi_cdc_group
* \defgroup udi_cdc_group_desc USB interface descriptors
*
* The following structures provide predefined USB interface descriptors.
* It must be used to define the final USB descriptors.
*/
//@{
/**
* \brief Communication Class interface descriptor
*
* Interface descriptor with associated functional and endpoint
* descriptors for the CDC Communication Class interface.
*/
typedef struct {
//! Standard interface descriptor
usb_iface_desc_t iface;
//! CDC Header functional descriptor
usb_cdc_hdr_desc_t header;
//! CDC Abstract Control Model functional descriptor
usb_cdc_acm_desc_t acm;
//! CDC Union functional descriptor
usb_cdc_union_desc_t union_desc;
//! CDC Call Management functional descriptor
usb_cdc_call_mgmt_desc_t call_mgmt;
//! Notification endpoint descriptor
usb_ep_desc_t ep_notify;
} udi_cdc_comm_desc_t;
/**
* \brief Data Class interface descriptor
*
* Interface descriptor with associated endpoint descriptors for the
* CDC Data Class interface.
*/
typedef struct {
//! Standard interface descriptor
usb_iface_desc_t iface;
//! Data IN/OUT endpoint descriptors
usb_ep_desc_t ep_in;
usb_ep_desc_t ep_out;
} udi_cdc_data_desc_t;
//! CDC communication endpoints size for all speeds
#define UDI_CDC_COMM_EP_SIZE 64
//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B)
#define UDI_CDC_DATA_EPS_FS_SIZE 64
//! CDC data endpoints size for HS speed (512B only)
#define UDI_CDC_DATA_EPS_HS_SIZE 512
/**
* \name Content of interface descriptors
* Up to 7 CDC interfaces can be implemented on a USB device.
*/
//@{
//! By default no string associated to these interfaces
#ifndef UDI_CDC_IAD_STRING_ID_0
#define UDI_CDC_IAD_STRING_ID_0 0
#endif
#ifndef UDI_CDC_COMM_STRING_ID_0
#define UDI_CDC_COMM_STRING_ID_0 0
#endif
#ifndef UDI_CDC_DATA_STRING_ID_0
#define UDI_CDC_DATA_STRING_ID_0 0
#endif
#define UDI_CDC_IAD_DESC_0 UDI_CDC_IAD_DESC(0)
#define UDI_CDC_COMM_DESC_0 UDI_CDC_COMM_DESC(0)
#define UDI_CDC_DATA_DESC_0_FS UDI_CDC_DATA_DESC_FS(0)
#define UDI_CDC_DATA_DESC_0_HS UDI_CDC_DATA_DESC_HS(0)
//! By default no string associated to these interfaces
#ifndef UDI_CDC_IAD_STRING_ID_1
#define UDI_CDC_IAD_STRING_ID_1 0
#endif
#ifndef UDI_CDC_COMM_STRING_ID_1
#define UDI_CDC_COMM_STRING_ID_1 0
#endif
#ifndef UDI_CDC_DATA_STRING_ID_1
#define UDI_CDC_DATA_STRING_ID_1 0
#endif
#define UDI_CDC_IAD_DESC_1 UDI_CDC_IAD_DESC(1)
#define UDI_CDC_COMM_DESC_1 UDI_CDC_COMM_DESC(1)
#define UDI_CDC_DATA_DESC_1_FS UDI_CDC_DATA_DESC_FS(1)
#define UDI_CDC_DATA_DESC_1_HS UDI_CDC_DATA_DESC_HS(1)
//! By default no string associated to these interfaces
#ifndef UDI_CDC_IAD_STRING_ID_2
#define UDI_CDC_IAD_STRING_ID_2 0
#endif
#ifndef UDI_CDC_COMM_STRING_ID_2
#define UDI_CDC_COMM_STRING_ID_2 0
#endif
#ifndef UDI_CDC_DATA_STRING_ID_2
#define UDI_CDC_DATA_STRING_ID_2 0
#endif
#define UDI_CDC_IAD_DESC_2 UDI_CDC_IAD_DESC(2)
#define UDI_CDC_COMM_DESC_2 UDI_CDC_COMM_DESC(2)
#define UDI_CDC_DATA_DESC_2_FS UDI_CDC_DATA_DESC_FS(2)
#define UDI_CDC_DATA_DESC_2_HS UDI_CDC_DATA_DESC_HS(2)
//! By default no string associated to these interfaces
#ifndef UDI_CDC_IAD_STRING_ID_3
#define UDI_CDC_IAD_STRING_ID_3 0
#endif
#ifndef UDI_CDC_COMM_STRING_ID_3
#define UDI_CDC_COMM_STRING_ID_3 0
#endif
#ifndef UDI_CDC_DATA_STRING_ID_3
#define UDI_CDC_DATA_STRING_ID_3 0
#endif
#define UDI_CDC_IAD_DESC_3 UDI_CDC_IAD_DESC(3)
#define UDI_CDC_COMM_DESC_3 UDI_CDC_COMM_DESC(3)
#define UDI_CDC_DATA_DESC_3_FS UDI_CDC_DATA_DESC_FS(3)
#define UDI_CDC_DATA_DESC_3_HS UDI_CDC_DATA_DESC_HS(3)
//! By default no string associated to these interfaces
#ifndef UDI_CDC_IAD_STRING_ID_4
#define UDI_CDC_IAD_STRING_ID_4 0
#endif
#ifndef UDI_CDC_COMM_STRING_ID_4
#define UDI_CDC_COMM_STRING_ID_4 0
#endif
#ifndef UDI_CDC_DATA_STRING_ID_4
#define UDI_CDC_DATA_STRING_ID_4 0
#endif
#define UDI_CDC_IAD_DESC_4 UDI_CDC_IAD_DESC(4)
#define UDI_CDC_COMM_DESC_4 UDI_CDC_COMM_DESC(4)
#define UDI_CDC_DATA_DESC_4_FS UDI_CDC_DATA_DESC_FS(4)
#define UDI_CDC_DATA_DESC_4_HS UDI_CDC_DATA_DESC_HS(4)
//! By default no string associated to these interfaces
#ifndef UDI_CDC_IAD_STRING_ID_5
#define UDI_CDC_IAD_STRING_ID_5 0
#endif
#ifndef UDI_CDC_COMM_STRING_ID_5
#define UDI_CDC_COMM_STRING_ID_5 0
#endif
#ifndef UDI_CDC_DATA_STRING_ID_5
#define UDI_CDC_DATA_STRING_ID_5 0
#endif
#define UDI_CDC_IAD_DESC_5 UDI_CDC_IAD_DESC(5)
#define UDI_CDC_COMM_DESC_5 UDI_CDC_COMM_DESC(5)
#define UDI_CDC_DATA_DESC_5_FS UDI_CDC_DATA_DESC_FS(5)
#define UDI_CDC_DATA_DESC_5_HS UDI_CDC_DATA_DESC_HS(5)
//! By default no string associated to these interfaces
#ifndef UDI_CDC_IAD_STRING_ID_6
#define UDI_CDC_IAD_STRING_ID_6 0
#endif
#ifndef UDI_CDC_COMM_STRING_ID_6
#define UDI_CDC_COMM_STRING_ID_6 0
#endif
#ifndef UDI_CDC_DATA_STRING_ID_6
#define UDI_CDC_DATA_STRING_ID_6 0
#endif
#define UDI_CDC_IAD_DESC_6 UDI_CDC_IAD_DESC(6)
#define UDI_CDC_COMM_DESC_6 UDI_CDC_COMM_DESC(6)
#define UDI_CDC_DATA_DESC_6_FS UDI_CDC_DATA_DESC_FS(6)
#define UDI_CDC_DATA_DESC_6_HS UDI_CDC_DATA_DESC_HS(6)
//@}
//! Content of CDC IAD interface descriptor for all speeds
#define UDI_CDC_IAD_DESC(port) { \
.bLength = sizeof(usb_iad_desc_t),\
.bDescriptorType = USB_DT_IAD,\
.bInterfaceCount = 2,\
.bFunctionClass = CDC_CLASS_COMM,\
.bFunctionSubClass = CDC_SUBCLASS_ACM,\
.bFunctionProtocol = CDC_PROTOCOL_V25TER,\
.bFirstInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\
.iFunction = UDI_CDC_IAD_STRING_ID_##port,\
}
//! Content of CDC COMM interface descriptor for all speeds
#define UDI_CDC_COMM_DESC(port) { \
.iface.bLength = sizeof(usb_iface_desc_t),\
.iface.bDescriptorType = USB_DT_INTERFACE,\
.iface.bAlternateSetting = 0,\
.iface.bNumEndpoints = 1,\
.iface.bInterfaceClass = CDC_CLASS_COMM,\
.iface.bInterfaceSubClass = CDC_SUBCLASS_ACM,\
.iface.bInterfaceProtocol = CDC_PROTOCOL_V25TER,\
.header.bFunctionLength = sizeof(usb_cdc_hdr_desc_t),\
.header.bDescriptorType = CDC_CS_INTERFACE,\
.header.bDescriptorSubtype = CDC_SCS_HEADER,\
.header.bcdCDC = LE16(0x0110),\
.call_mgmt.bFunctionLength = sizeof(usb_cdc_call_mgmt_desc_t),\
.call_mgmt.bDescriptorType = CDC_CS_INTERFACE,\
.call_mgmt.bDescriptorSubtype = CDC_SCS_CALL_MGMT,\
.call_mgmt.bmCapabilities = \
CDC_CALL_MGMT_SUPPORTED | CDC_CALL_MGMT_OVER_DCI,\
.acm.bFunctionLength = sizeof(usb_cdc_acm_desc_t),\
.acm.bDescriptorType = CDC_CS_INTERFACE,\
.acm.bDescriptorSubtype = CDC_SCS_ACM,\
.acm.bmCapabilities = CDC_ACM_SUPPORT_LINE_REQUESTS,\
.union_desc.bFunctionLength = sizeof(usb_cdc_union_desc_t),\
.union_desc.bDescriptorType = CDC_CS_INTERFACE,\
.union_desc.bDescriptorSubtype= CDC_SCS_UNION,\
.ep_notify.bLength = sizeof(usb_ep_desc_t),\
.ep_notify.bDescriptorType = USB_DT_ENDPOINT,\
.ep_notify.bmAttributes = USB_EP_TYPE_INTERRUPT,\
.ep_notify.wMaxPacketSize = LE16(UDI_CDC_COMM_EP_SIZE),\
.ep_notify.bInterval = 0x10,\
.ep_notify.bEndpointAddress = UDI_CDC_COMM_EP_##port,\
.iface.bInterfaceNumber = UDI_CDC_COMM_IFACE_NUMBER_##port,\
.call_mgmt.bDataInterface = UDI_CDC_DATA_IFACE_NUMBER_##port,\
.union_desc.bMasterInterface = UDI_CDC_COMM_IFACE_NUMBER_##port,\
.union_desc.bSlaveInterface0 = UDI_CDC_DATA_IFACE_NUMBER_##port,\
.iface.iInterface = UDI_CDC_COMM_STRING_ID_##port,\
}
//! Content of CDC DATA interface descriptors
#define UDI_CDC_DATA_DESC_COMMON \
.iface.bLength = sizeof(usb_iface_desc_t),\
.iface.bDescriptorType = USB_DT_INTERFACE,\
.iface.bAlternateSetting = 0,\
.iface.bNumEndpoints = 2,\
.iface.bInterfaceClass = CDC_CLASS_DATA,\
.iface.bInterfaceSubClass = 0,\
.iface.bInterfaceProtocol = 0,\
.ep_in.bLength = sizeof(usb_ep_desc_t),\
.ep_in.bDescriptorType = USB_DT_ENDPOINT,\
.ep_in.bmAttributes = USB_EP_TYPE_BULK,\
.ep_in.bInterval = 0,\
.ep_out.bLength = sizeof(usb_ep_desc_t),\
.ep_out.bDescriptorType = USB_DT_ENDPOINT,\
.ep_out.bmAttributes = USB_EP_TYPE_BULK,\
.ep_out.bInterval = 0,
#define UDI_CDC_DATA_DESC_FS(port) { \
UDI_CDC_DATA_DESC_COMMON \
.ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\
.ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_FS_SIZE),\
.ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\
.ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\
.iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\
.iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\
}
#define UDI_CDC_DATA_DESC_HS(port) { \
UDI_CDC_DATA_DESC_COMMON \
.ep_in.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\
.ep_out.wMaxPacketSize = LE16(UDI_CDC_DATA_EPS_HS_SIZE),\
.ep_in.bEndpointAddress = UDI_CDC_DATA_EP_IN_##port,\
.ep_out.bEndpointAddress = UDI_CDC_DATA_EP_OUT_##port,\
.iface.bInterfaceNumber = UDI_CDC_DATA_IFACE_NUMBER_##port,\
.iface.iInterface = UDI_CDC_DATA_STRING_ID_##port,\
}
//@}
/**
* \ingroup udi_group
* \defgroup udi_cdc_group USB Device Interface (UDI) for Communication Class Device (CDC)
*
* Common APIs used by high level application to use this USB class.
*
* These routines are used to transfer and control data
* to/from USB CDC endpoint.
*
* See \ref udi_cdc_quickstart.
* @{
*/
/**
* \name Interface for application with single CDC interface support
*/
//@{
/**
* \brief Notify a state change of DCD signal
*
* \param b_set DCD is enabled if true, else disabled
*/
void udi_cdc_ctrl_signal_dcd(bool b_set);
/**
* \brief Notify a state change of DSR signal
*
* \param b_set DSR is enabled if true, else disabled
*/
void udi_cdc_ctrl_signal_dsr(bool b_set);
/**
* \brief Notify a framing error
*/
void udi_cdc_signal_framing_error(void);
/**
* \brief Notify a parity error
*/
void udi_cdc_signal_parity_error(void);
/**
* \brief Notify a overrun
*/
void udi_cdc_signal_overrun(void);
/**
* \brief This function checks if a character has been received on the CDC line
*
* \return \c 1 if a byte is ready to be read.
*/
bool udi_cdc_is_rx_ready(void);
/**
* \brief Waits and gets a value on CDC line
*
* \return value read on CDC line
*/
int udi_cdc_getc(void);
/**
* \brief Reads a RAM buffer on CDC line
*
* \param buf Values read
* \param size Number of value read
*
* \return the number of data remaining
*/
iram_size_t udi_cdc_read_buf(void* buf, iram_size_t size);
/**
* \brief This function checks if a new character sent is possible
* The type int is used to support scanf redirection from compiler LIB.
*
* \return \c 1 if a new character can be sent
*/
bool udi_cdc_is_tx_ready(void);
/**
* \brief Puts a byte on CDC line
* The type int is used to support printf redirection from compiler LIB.
*
* \param value Value to put
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
int udi_cdc_putc(int value);
/**
* \brief Writes a RAM buffer on CDC line
*
* \param buf Values to write
* \param size Number of value to write
*
* \return the number of data remaining
*/
iram_size_t udi_cdc_write_buf(const void* buf, iram_size_t size);
//@}
/**
* \name Interface for application with multi CDC interfaces support
*/
//@{
/**
* \brief Notify a state change of DCD signal
*
* \param port Communication port number to manage
* \param b_set DCD is enabled if true, else disabled
*/
void udi_cdc_multi_ctrl_signal_dcd(uint8_t port, bool b_set);
/**
* \brief Notify a state change of DSR signal
*
* \param port Communication port number to manage
* \param b_set DSR is enabled if true, else disabled
*/
void udi_cdc_multi_ctrl_signal_dsr(uint8_t port, bool b_set);
/**
* \brief Notify a framing error
*
* \param port Communication port number to manage
*/
void udi_cdc_multi_signal_framing_error(uint8_t port);
/**
* \brief Notify a parity error
*
* \param port Communication port number to manage
*/
void udi_cdc_multi_signal_parity_error(uint8_t port);
/**
* \brief Notify a overrun
*
* \param port Communication port number to manage
*/
void udi_cdc_multi_signal_overrun(uint8_t port);
/**
* \brief This function checks if a character has been received on the CDC line
*
* \param port Communication port number to manage
*
* \return \c 1 if a byte is ready to be read.
*/
bool udi_cdc_multi_is_rx_ready(uint8_t port);
/**
* \brief Waits and gets a value on CDC line
*
* \param port Communication port number to manage
*
* \return value read on CDC line
*/
int udi_cdc_multi_getc(uint8_t port);
/**
* \brief Reads a RAM buffer on CDC line
*
* \param port Communication port number to manage
* \param buf Values read
* \param size Number of values read
*
* \return the number of data remaining
*/
iram_size_t udi_cdc_multi_read_buf(uint8_t port, void* buf, iram_size_t size);
/**
* \brief This function checks if a new character sent is possible
* The type int is used to support scanf redirection from compiler LIB.
*
* \param port Communication port number to manage
*
* \return \c 1 if a new character can be sent
*/
bool udi_cdc_multi_is_tx_ready(uint8_t port);
/**
* \brief Puts a byte on CDC line
* The type int is used to support printf redirection from compiler LIB.
*
* \param port Communication port number to manage
* \param value Value to put
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
int udi_cdc_multi_putc(uint8_t port, int value);
/**
* \brief Writes a RAM buffer on CDC line
*
* \param port Communication port number to manage
* \param buf Values to write
* \param size Number of value to write
*
* \return the number of data remaining
*/
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size);
//@}
//@}
/**
* \page udi_cdc_quickstart Quick start guide for USB device Communication Class Device module (UDI CDC)
*
* This is the quick start guide for the \ref udi_cdc_group
* "USB device interface CDC module (UDI CDC)" with step-by-step instructions on
* how to configure and use the modules in a selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section udi_cdc_basic_use_case Basic use case
* In this basic use case, the "USB CDC (Single Interface Device)" module is used
* with only one communication port.
* The "USB CDC (Composite Device)" module usage is described in \ref udi_cdc_use_cases
* "Advanced use cases".
*
* \section udi_cdc_basic_use_case_setup Setup steps
* \subsection udi_cdc_basic_use_case_setup_prereq Prerequisites
* \copydetails udc_basic_use_case_setup_prereq
* \subsection udi_cdc_basic_use_case_setup_code Example code
* \copydetails udc_basic_use_case_setup_code
* \subsection udi_cdc_basic_use_case_setup_flow Workflow
* \copydetails udc_basic_use_case_setup_flow
*
* \section udi_cdc_basic_use_case_usage Usage steps
*
* \subsection udi_cdc_basic_use_case_usage_code Example code
* Content of conf_usb.h:
* \code
* #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable()
* extern bool my_callback_cdc_enable(void);
* #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable()
* extern void my_callback_cdc_disable(void);
* #define UDI_CDC_LOW_RATE
*
* #define UDI_CDC_DEFAULT_RATE 115200
* #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1
* #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE
* #define UDI_CDC_DEFAULT_DATABITS 8
*
* #include "udi_cdc_conf.h" // At the end of conf_usb.h file
* \endcode
*
* Add to application C-file:
* \code
* static bool my_flag_autorize_cdc_transfert = false;
* bool my_callback_cdc_enable(void)
* {
* my_flag_autorize_cdc_transfert = true;
* return true;
* }
* void my_callback_cdc_disable(void)
* {
* my_flag_autorize_cdc_transfert = false;
* }
*
* void task(void)
* {
* if (my_flag_autorize_cdc_transfert) {
* udi_cdc_putc('A');
* udi_cdc_getc();
* }
* }
* \endcode
*
* \subsection udi_cdc_basic_use_case_setup_flow Workflow
* -# Ensure that conf_usb.h is available and contains the following configuration
* which is the USB device CDC configuration:
* - \code #define USB_DEVICE_SERIAL_NAME "12...EF" // Disk SN for CDC \endcode
* \note The USB serial number is mandatory when a CDC interface is used.
* - \code #define UDI_CDC_ENABLE_EXT(port) my_callback_cdc_enable()
* extern bool my_callback_cdc_enable(void); \endcode
* \note After the device enumeration (detecting and identifying USB devices),
* the USB host starts the device configuration. When the USB CDC interface
* from the device is accepted by the host, the USB host enables this interface and the
* UDI_CDC_ENABLE_EXT() callback function is called and return true.
* Thus, when this event is received, the data transfer on CDC interface are authorized.
* - \code #define UDI_CDC_DISABLE_EXT(port) my_callback_cdc_disable()
* extern void my_callback_cdc_disable(void); \endcode
* \note When the USB device is unplugged or is reset by the USB host, the USB
* interface is disabled and the UDI_CDC_DISABLE_EXT() callback function
* is called. Thus, the data transfer must be stopped on CDC interface.
* - \code #define UDI_CDC_LOW_RATE \endcode
* \note Define it when the transfer CDC Device to Host is a low rate
* (<512000 bauds) to reduce CDC buffers size.
* - \code #define UDI_CDC_DEFAULT_RATE 115200
* #define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1
* #define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE
* #define UDI_CDC_DEFAULT_DATABITS 8 \endcode
* \note Default configuration of communication port at startup.
* -# Send or wait data on CDC line:
* - \code // Waits and gets a value on CDC line
* int udi_cdc_getc(void);
* // Reads a RAM buffer on CDC line
* iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size);
* // Puts a byte on CDC line
* int udi_cdc_putc(int value);
* // Writes a RAM buffer on CDC line
* iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode
*
* \section udi_cdc_use_cases Advanced use cases
* For more advanced use of the UDI CDC module, see the following use cases:
* - \subpage udi_cdc_use_case_composite
* - \subpage udc_use_case_1
* - \subpage udc_use_case_2
* - \subpage udc_use_case_3
* - \subpage udc_use_case_4
* - \subpage udc_use_case_5
* - \subpage udc_use_case_6
*/
/**
* \page udi_cdc_use_case_composite CDC in a composite device
*
* A USB Composite Device is a USB Device which uses more than one USB class.
* In this use case, the "USB CDC (Composite Device)" module is used to
* create a USB composite device. Thus, this USB module can be associated with
* another "Composite Device" module, like "USB HID Mouse (Composite Device)".
*
* Also, you can refer to application note
*
* AVR4902 ASF - USB Composite Device.
*
* \section udi_cdc_use_case_composite_setup Setup steps
* For the setup code of this use case to work, the
* \ref udi_cdc_basic_use_case "basic use case" must be followed.
*
* \section udi_cdc_use_case_composite_usage Usage steps
*
* \subsection udi_cdc_use_case_composite_usage_code Example code
* Content of conf_usb.h:
* \code
* #define USB_DEVICE_EP_CTRL_SIZE 64
* #define USB_DEVICE_NB_INTERFACE (X+2)
* #define USB_DEVICE_MAX_EP (X+3)
*
* #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX
* #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX
* #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint
* #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0
* #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1
*
* #define UDI_COMPOSITE_DESC_T \
* usb_iad_desc_t udi_cdc_iad; \
* udi_cdc_comm_desc_t udi_cdc_comm; \
* udi_cdc_data_desc_t udi_cdc_data; \
* ...
* #define UDI_COMPOSITE_DESC_FS \
* .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \
* .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \
* .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \
* ...
* #define UDI_COMPOSITE_DESC_HS \
* .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \
* .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \
* .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \
* ...
* #define UDI_COMPOSITE_API \
* &udi_api_cdc_comm, \
* &udi_api_cdc_data, \
* ...
* \endcode
*
* \subsection udi_cdc_use_case_composite_usage_flow Workflow
* -# Ensure that conf_usb.h is available and contains the following parameters
* required for a USB composite device configuration:
* - \code // Endpoint control size, This must be:
* // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM)
* // - 64 for a high speed device
* #define USB_DEVICE_EP_CTRL_SIZE 64
* // Total Number of interfaces on this USB device.
* // Add 2 for CDC.
* #define USB_DEVICE_NB_INTERFACE (X+2)
* // Total number of endpoints on this USB device.
* // This must include each endpoint for each interface.
* // Add 3 for CDC.
* #define USB_DEVICE_MAX_EP (X+3) \endcode
* -# Ensure that conf_usb.h contains the description of
* composite device:
* - \code // The endpoint numbers chosen by you for the CDC.
* // The endpoint numbers starting from 1.
* #define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX
* #define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX
* #define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint
* // The interface index of an interface starting from 0
* #define UDI_CDC_COMM_IFACE_NUMBER_0 X+0
* #define UDI_CDC_DATA_IFACE_NUMBER_0 X+1 \endcode
* -# Ensure that conf_usb.h contains the following parameters
* required for a USB composite device configuration:
* - \code // USB Interfaces descriptor structure
* #define UDI_COMPOSITE_DESC_T \
* ...
* usb_iad_desc_t udi_cdc_iad; \
* udi_cdc_comm_desc_t udi_cdc_comm; \
* udi_cdc_data_desc_t udi_cdc_data; \
* ...
* // USB Interfaces descriptor value for Full Speed
* #define UDI_COMPOSITE_DESC_FS \
* ...
* .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \
* .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \
* .udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \
* ...
* // USB Interfaces descriptor value for High Speed
* #define UDI_COMPOSITE_DESC_HS \
* ...
* .udi_cdc_iad = UDI_CDC_IAD_DESC_0, \
* .udi_cdc_comm = UDI_CDC_COMM_DESC_0, \
* .udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \
* ...
* // USB Interface APIs
* #define UDI_COMPOSITE_API \
* ...
* &udi_api_cdc_comm, \
* &udi_api_cdc_data, \
* ... \endcode
* - \note The descriptors order given in the four lists above must be the
* same as the order defined by all interface indexes. The interface index
* orders are defined through UDI_X_IFACE_NUMBER defines.\n
* Also, the CDC requires a USB Interface Association Descriptor (IAD) for
* composite device.
*/
#ifdef __cplusplus
}
#endif
#endif // _UDI_CDC_H_
dstat-firmware-master/src/asf/common/services/usb/class/cdc/device/udi_cdc_conf.h 0000664 0000000 0000000 00000012454 13317465730 0030430 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Default CDC configuration for a USB Device with a single interface
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _UDI_CDC_CONF_H_
#define _UDI_CDC_CONF_H_
#include "usb_protocol_cdc.h"
#include "conf_usb.h"
#ifndef UDI_CDC_PORT_NB
# define UDI_CDC_PORT_NB 1
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* \addtogroup udi_cdc_group_single_desc
* @{
*/
//! Control endpoint size (Endpoint 0)
#define USB_DEVICE_EP_CTRL_SIZE 64
#if XMEGA
/**
* \name Endpoint configuration on XMEGA
* The XMEGA supports a IN and OUT endpoint with the same number endpoint,
* thus XMEGA can support up to 7 CDC interfaces.
*/
//@{
#define UDI_CDC_DATA_EP_IN_0 ( 1 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_0 ( 2 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_0 ( 2 | USB_EP_DIR_IN) // Notify endpoint
#define UDI_CDC_DATA_EP_IN_1 ( 3 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_1 ( 4 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_1 ( 4 | USB_EP_DIR_IN) // Notify endpoint
#define UDI_CDC_DATA_EP_IN_2 ( 5 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_2 ( 6 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_2 ( 6 | USB_EP_DIR_IN) // Notify endpoint
#define UDI_CDC_DATA_EP_IN_3 ( 7 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_3 ( 8 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_3 ( 8 | USB_EP_DIR_IN) // Notify endpoint
#define UDI_CDC_DATA_EP_IN_4 ( 9 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_4 (10 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_4 (10 | USB_EP_DIR_IN) // Notify endpoint
#define UDI_CDC_DATA_EP_IN_5 (11 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_5 (12 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_5 (12 | USB_EP_DIR_IN) // Notify endpoint
#define UDI_CDC_DATA_EP_IN_6 (13 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_6 (14 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_6 (14 | USB_EP_DIR_IN) // Notify endpoint
//! 2 endpoints numbers used per CDC interface
#define USB_DEVICE_MAX_EP (2*UDI_CDC_PORT_NB)
//@}
#else
/**
* \name Default endpoint configuration
* The USBB, UDP, UDPHS and UOTGHS interfaces can support up to 2 CDC interfaces.
*/
//@{
# if UDI_CDC_PORT_NB > 2
# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints.
# endif
#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint
#define UDI_CDC_DATA_EP_IN_1 (4 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_1 (5 | USB_EP_DIR_OUT) // RX
#define UDI_CDC_COMM_EP_1 (6 | USB_EP_DIR_IN) // Notify endpoint
//! 3 endpoints used per CDC interface
#define USB_DEVICE_MAX_EP (3*UDI_CDC_PORT_NB)
//@}
#endif
/**
* \name Default Interface numbers
*/
//@{
#define UDI_CDC_COMM_IFACE_NUMBER_0 0
#define UDI_CDC_DATA_IFACE_NUMBER_0 1
#define UDI_CDC_COMM_IFACE_NUMBER_1 2
#define UDI_CDC_DATA_IFACE_NUMBER_1 3
#define UDI_CDC_COMM_IFACE_NUMBER_2 4
#define UDI_CDC_DATA_IFACE_NUMBER_2 5
#define UDI_CDC_COMM_IFACE_NUMBER_3 6
#define UDI_CDC_DATA_IFACE_NUMBER_3 7
#define UDI_CDC_COMM_IFACE_NUMBER_4 8
#define UDI_CDC_DATA_IFACE_NUMBER_4 9
#define UDI_CDC_COMM_IFACE_NUMBER_5 10
#define UDI_CDC_DATA_IFACE_NUMBER_5 11
#define UDI_CDC_COMM_IFACE_NUMBER_6 12
#define UDI_CDC_DATA_IFACE_NUMBER_6 13
//@}
//@}
#ifdef __cplusplus
}
#endif
#endif // _UDI_CDC_CONF_H_
dstat-firmware-master/src/asf/common/services/usb/class/cdc/device/udi_cdc_desc.c 0000664 0000000 0000000 00000016545 13317465730 0030421 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Default descriptors for a USB Device with a single interface CDC
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "conf_usb.h"
#include "udd.h"
#include "udc_desc.h"
#include "udi_cdc.h"
/**
* \defgroup udi_cdc_group_single_desc USB device descriptors for a single interface
*
* The following structures provide the USB device descriptors required for
* USB Device with a single interface CDC.
*
* It is ready to use and do not require more definition.
*
* @{
*/
//! Two interfaces for a CDC device
#define USB_DEVICE_NB_INTERFACE (2*UDI_CDC_PORT_NB)
//! USB Device Descriptor
COMPILER_WORD_ALIGNED
UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = {
.bLength = sizeof(usb_dev_desc_t),
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = LE16(USB_V2_0),
#if UDI_CDC_PORT_NB > 1
.bDeviceClass = 0,
#else
.bDeviceClass = CDC_CLASS_DEVICE,
#endif
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE,
.idVendor = LE16(USB_DEVICE_VENDOR_ID),
.idProduct = LE16(USB_DEVICE_PRODUCT_ID),
.bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8)
| USB_DEVICE_MINOR_VERSION),
#ifdef USB_DEVICE_MANUFACTURE_NAME
.iManufacturer = 1,
#else
.iManufacturer = 0, // No manufacture string
#endif
#ifdef USB_DEVICE_PRODUCT_NAME
.iProduct = 2,
#else
.iProduct = 0, // No product string
#endif
#ifdef USB_DEVICE_SERIAL_NAME
.iSerialNumber = 3,
#else
.iSerialNumber = 0, // No serial string
#endif
.bNumConfigurations = 1
};
#ifdef USB_DEVICE_HS_SUPPORT
//! USB Device Qualifier Descriptor for HS
COMPILER_WORD_ALIGNED
UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = {
.bLength = sizeof(usb_dev_qual_desc_t),
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
.bcdUSB = LE16(USB_V2_0),
#if UDI_CDC_PORT_NB > 1
.bDeviceClass = 0,
#else
.bDeviceClass = CDC_CLASS_DEVICE,
#endif
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE,
.bNumConfigurations = 1
};
#endif
//! Structure for USB Device Configuration Descriptor
COMPILER_PACK_SET(1)
typedef struct {
usb_conf_desc_t conf;
#if UDI_CDC_PORT_NB == 1
udi_cdc_comm_desc_t udi_cdc_comm_0;
udi_cdc_data_desc_t udi_cdc_data_0;
#else
# define UDI_CDC_DESC_STRUCTURE(index, unused) \
usb_iad_desc_t udi_cdc_iad_##index; \
udi_cdc_comm_desc_t udi_cdc_comm_##index; \
udi_cdc_data_desc_t udi_cdc_data_##index;
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_STRUCTURE, ~)
# undef UDI_CDC_DESC_STRUCTURE
#endif
} udc_desc_t;
COMPILER_PACK_RESET()
//! USB Device Configuration Descriptor filled for full and high speed
COMPILER_WORD_ALIGNED
UDC_DESC_STORAGE udc_desc_t udc_desc_fs = {
.conf.bLength = sizeof(usb_conf_desc_t),
.conf.bDescriptorType = USB_DT_CONFIGURATION,
.conf.wTotalLength = LE16(sizeof(udc_desc_t)),
.conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE,
.conf.bConfigurationValue = 1,
.conf.iConfiguration = 0,
.conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR,
.conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER),
#if UDI_CDC_PORT_NB == 1
.udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0,
.udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_FS,
#else
# define UDI_CDC_DESC_FS(index, unused) \
.udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index,\
.udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index,\
.udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_FS,
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_FS, ~)
# undef UDI_CDC_DESC_FS
#endif
};
#ifdef USB_DEVICE_HS_SUPPORT
COMPILER_WORD_ALIGNED
UDC_DESC_STORAGE udc_desc_t udc_desc_hs = {
.conf.bLength = sizeof(usb_conf_desc_t),
.conf.bDescriptorType = USB_DT_CONFIGURATION,
.conf.wTotalLength = LE16(sizeof(udc_desc_t)),
.conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE,
.conf.bConfigurationValue = 1,
.conf.iConfiguration = 0,
.conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR,
.conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER),
#if UDI_CDC_PORT_NB == 1
.udi_cdc_comm_0 = UDI_CDC_COMM_DESC_0,
.udi_cdc_data_0 = UDI_CDC_DATA_DESC_0_HS,
#else
# define UDI_CDC_DESC_HS(index, unused) \
.udi_cdc_iad_##index = UDI_CDC_IAD_DESC_##index, \
.udi_cdc_comm_##index = UDI_CDC_COMM_DESC_##index, \
.udi_cdc_data_##index = UDI_CDC_DATA_DESC_##index##_HS,
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_DESC_HS, ~)
# undef UDI_CDC_DESC_HS
#endif
};
#endif
/**
* \name UDC structures which content all USB Device definitions
*/
//@{
//! Associate an UDI for each USB interface
UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = {
# define UDI_CDC_API(index, unused) \
&udi_api_cdc_comm, \
&udi_api_cdc_data,
MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_API, ~)
# undef UDI_CDC_API
};
//! Add UDI with USB Descriptors FS & HS
UDC_DESC_STORAGE udc_config_speed_t udc_config_fs[1] = { {
.desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs,
.udi_apis = udi_apis,
}};
#ifdef USB_DEVICE_HS_SUPPORT
UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = { {
.desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs,
.udi_apis = udi_apis,
}};
#endif
//! Add all information about USB Device in global structure for UDC
UDC_DESC_STORAGE udc_config_t udc_config = {
.confdev_lsfs = &udc_device_desc,
.conf_lsfs = udc_config_fs,
#ifdef USB_DEVICE_HS_SUPPORT
.confdev_hs = &udc_device_desc,
.qualifier = &udc_device_qual,
.conf_hs = udc_config_hs,
#endif
};
//@}
//@}
dstat-firmware-master/src/asf/common/services/usb/class/cdc/usb_protocol_cdc.h 0000664 0000000 0000000 00000025730 13317465730 0030116 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief USB Communication Device Class (CDC) protocol definitions
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _USB_PROTOCOL_CDC_H_
#define _USB_PROTOCOL_CDC_H_
#include "compiler.h"
/**
* \ingroup usb_protocol_group
* \defgroup cdc_protocol_group Communication Device Class Definitions
* @{
*/
/**
* \name Possible values of class
*/
//@{
#define CDC_CLASS_DEVICE 0x02 //!< USB Communication Device Class
#define CDC_CLASS_COMM 0x02 //!< CDC Communication Class Interface
#define CDC_CLASS_DATA 0x0A //!< CDC Data Class Interface
//@}
//! \name USB CDC Subclass IDs
//@{
#define CDC_SUBCLASS_DLCM 0x01 //!< Direct Line Control Model
#define CDC_SUBCLASS_ACM 0x02 //!< Abstract Control Model
#define CDC_SUBCLASS_TCM 0x03 //!< Telephone Control Model
#define CDC_SUBCLASS_MCCM 0x04 //!< Multi-Channel Control Model
#define CDC_SUBCLASS_CCM 0x05 //!< CAPI Control Model
#define CDC_SUBCLASS_ETH 0x06 //!< Ethernet Networking Control Model
#define CDC_SUBCLASS_ATM 0x07 //!< ATM Networking Control Model
//@}
//! \name USB CDC Communication Interface Protocol IDs
//@{
#define CDC_PROTOCOL_V25TER 0x01 //!< Common AT commands
//@}
//! \name USB CDC Data Interface Protocol IDs
//@{
#define CDC_PROTOCOL_I430 0x30 //!< ISDN BRI
#define CDC_PROTOCOL_HDLC 0x31 //!< HDLC
#define CDC_PROTOCOL_TRANS 0x32 //!< Transparent
#define CDC_PROTOCOL_Q921M 0x50 //!< Q.921 management protocol
#define CDC_PROTOCOL_Q921 0x51 //!< Q.931 [sic] Data link protocol
#define CDC_PROTOCOL_Q921TM 0x52 //!< Q.921 TEI-multiplexor
#define CDC_PROTOCOL_V42BIS 0x90 //!< Data compression procedures
#define CDC_PROTOCOL_Q931 0x91 //!< Euro-ISDN protocol control
#define CDC_PROTOCOL_V120 0x92 //!< V.24 rate adaption to ISDN
#define CDC_PROTOCOL_CAPI20 0x93 //!< CAPI Commands
#define CDC_PROTOCOL_HOST 0xFD //!< Host based driver
/**
* \brief Describes the Protocol Unit Functional Descriptors [sic]
* on Communication Class Interface
*/
#define CDC_PROTOCOL_PUFD 0xFE
//@}
//! \name USB CDC Functional Descriptor Types
//@{
#define CDC_CS_INTERFACE 0x24 //!< Interface Functional Descriptor
#define CDC_CS_ENDPOINT 0x25 //!< Endpoint Functional Descriptor
//@}
//! \name USB CDC Functional Descriptor Subtypes
//@{
#define CDC_SCS_HEADER 0x00 //!< Header Functional Descriptor
#define CDC_SCS_CALL_MGMT 0x01 //!< Call Management
#define CDC_SCS_ACM 0x02 //!< Abstract Control Management
#define CDC_SCS_UNION 0x06 //!< Union Functional Descriptor
//@}
//! \name USB CDC Request IDs
//@{
#define USB_REQ_CDC_SEND_ENCAPSULATED_COMMAND 0x00
#define USB_REQ_CDC_GET_ENCAPSULATED_RESPONSE 0x01
#define USB_REQ_CDC_SET_COMM_FEATURE 0x02
#define USB_REQ_CDC_GET_COMM_FEATURE 0x03
#define USB_REQ_CDC_CLEAR_COMM_FEATURE 0x04
#define USB_REQ_CDC_SET_AUX_LINE_STATE 0x10
#define USB_REQ_CDC_SET_HOOK_STATE 0x11
#define USB_REQ_CDC_PULSE_SETUP 0x12
#define USB_REQ_CDC_SEND_PULSE 0x13
#define USB_REQ_CDC_SET_PULSE_TIME 0x14
#define USB_REQ_CDC_RING_AUX_JACK 0x15
#define USB_REQ_CDC_SET_LINE_CODING 0x20
#define USB_REQ_CDC_GET_LINE_CODING 0x21
#define USB_REQ_CDC_SET_CONTROL_LINE_STATE 0x22
#define USB_REQ_CDC_SEND_BREAK 0x23
#define USB_REQ_CDC_SET_RINGER_PARMS 0x30
#define USB_REQ_CDC_GET_RINGER_PARMS 0x31
#define USB_REQ_CDC_SET_OPERATION_PARMS 0x32
#define USB_REQ_CDC_GET_OPERATION_PARMS 0x33
#define USB_REQ_CDC_SET_LINE_PARMS 0x34
#define USB_REQ_CDC_GET_LINE_PARMS 0x35
#define USB_REQ_CDC_DIAL_DIGITS 0x36
#define USB_REQ_CDC_SET_UNIT_PARAMETER 0x37
#define USB_REQ_CDC_GET_UNIT_PARAMETER 0x38
#define USB_REQ_CDC_CLEAR_UNIT_PARAMETER 0x39
#define USB_REQ_CDC_GET_PROFILE 0x3A
#define USB_REQ_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
#define USB_REQ_CDC_SET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x41
#define USB_REQ_CDC_GET_ETHERNET_POWER_MANAGEMENT_PATTERNFILTER 0x42
#define USB_REQ_CDC_SET_ETHERNET_PACKET_FILTER 0x43
#define USB_REQ_CDC_GET_ETHERNET_STATISTIC 0x44
#define USB_REQ_CDC_SET_ATM_DATA_FORMAT 0x50
#define USB_REQ_CDC_GET_ATM_DEVICE_STATISTICS 0x51
#define USB_REQ_CDC_SET_ATM_DEFAULT_VC 0x52
#define USB_REQ_CDC_GET_ATM_VC_STATISTICS 0x53
// Added bNotification codes according cdc spec 1.1 chapter 6.3
#define USB_REQ_CDC_NOTIFY_RING_DETECT 0x09
#define USB_REQ_CDC_NOTIFY_SERIAL_STATE 0x20
#define USB_REQ_CDC_NOTIFY_CALL_STATE_CHANGE 0x28
#define USB_REQ_CDC_NOTIFY_LINE_STATE_CHANGE 0x29
//@}
/*
* Need to pack structures tightly, or the compiler might insert padding
* and violate the spec-mandated layout.
*/
COMPILER_PACK_SET(1)
//! \name USB CDC Descriptors
//@{
//! CDC Header Functional Descriptor
typedef struct {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
le16_t bcdCDC;
} usb_cdc_hdr_desc_t;
//! CDC Call Management Functional Descriptor
typedef struct {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bmCapabilities;
uint8_t bDataInterface;
} usb_cdc_call_mgmt_desc_t;
//! CDC ACM Functional Descriptor
typedef struct {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bmCapabilities;
} usb_cdc_acm_desc_t;
//! CDC Union Functional Descriptor
typedef struct {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bMasterInterface;
uint8_t bSlaveInterface0;
} usb_cdc_union_desc_t;
//! \name USB CDC Call Management Capabilities
//@{
//! Device handles call management itself
#define CDC_CALL_MGMT_SUPPORTED (1 << 0)
//! Device can send/receive call management info over a Data Class interface
#define CDC_CALL_MGMT_OVER_DCI (1 << 1)
//@}
//! \name USB CDC ACM Capabilities
//@{
//! Device supports the request combination of
//! Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature.
#define CDC_ACM_SUPPORT_FEATURE_REQUESTS (1 << 0)
//! Device supports the request combination of
//! Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding,
//! and the notification Serial_State.
#define CDC_ACM_SUPPORT_LINE_REQUESTS (1 << 1)
//! Device supports the request Send_Break
#define CDC_ACM_SUPPORT_SENDBREAK_REQUESTS (1 << 2)
//! Device supports the notification Network_Connection.
#define CDC_ACM_SUPPORT_NOTIFY_REQUESTS (1 << 3)
//@}
//@}
//! \name USB CDC line control
//@{
//! \name USB CDC line coding
//@{
//! Line Coding structure
typedef struct {
le32_t dwDTERate;
uint8_t bCharFormat;
uint8_t bParityType;
uint8_t bDataBits;
} usb_cdc_line_coding_t;
//! Possible values of bCharFormat
enum cdc_char_format {
CDC_STOP_BITS_1 = 0, //!< 1 stop bit
CDC_STOP_BITS_1_5 = 1, //!< 1.5 stop bits
CDC_STOP_BITS_2 = 2, //!< 2 stop bits
};
//! Possible values of bParityType
enum cdc_parity {
CDC_PAR_NONE = 0, //!< No parity
CDC_PAR_ODD = 1, //!< Odd parity
CDC_PAR_EVEN = 2, //!< Even parity
CDC_PAR_MARK = 3, //!< Parity forced to 0 (space)
CDC_PAR_SPACE = 4, //!< Parity forced to 1 (mark)
};
//@}
//! \name USB CDC control signals
//! spec 1.1 chapter 6.2.14
//@{
//! Control signal structure
typedef struct {
uint16_t value;
} usb_cdc_control_signal_t;
//! \name Possible values in usb_cdc_control_signal_t
//@{
//! Carrier control for half duplex modems.
//! This signal corresponds to V.24 signal 105 and RS-232 signal RTS.
//! The device ignores the value of this bit
//! when operating in full duplex mode.
#define CDC_CTRL_SIGNAL_ACTIVATE_CARRIER (1 << 1)
//! Indicates to DCE if DTE is present or not.
//! This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR.
#define CDC_CTRL_SIGNAL_DTE_PRESENT (1 << 0)
//@}
//@}
//! \name USB CDC notification message
//@{
typedef struct {
uint8_t bmRequestType;
uint8_t bNotification;
le16_t wValue;
le16_t wIndex;
le16_t wLength;
} usb_cdc_notify_msg_t;
//! \name USB CDC serial state
//@{*
//! Hardware handshake support (cdc spec 1.1 chapter 6.3.5)
typedef struct {
usb_cdc_notify_msg_t header;
le16_t value;
} usb_cdc_notify_serial_state_t;
//! \name Possible values in usb_cdc_notify_serial_state_t
//@{
#define CDC_SERIAL_STATE_DCD CPU_TO_LE16((1<<0))
#define CDC_SERIAL_STATE_DSR CPU_TO_LE16((1<<1))
#define CDC_SERIAL_STATE_BREAK CPU_TO_LE16((1<<2))
#define CDC_SERIAL_STATE_RING CPU_TO_LE16((1<<3))
#define CDC_SERIAL_STATE_FRAMING CPU_TO_LE16((1<<4))
#define CDC_SERIAL_STATE_PARITY CPU_TO_LE16((1<<5))
#define CDC_SERIAL_STATE_OVERRUN CPU_TO_LE16((1<<6))
//@}
//! @}
//! @}
COMPILER_PACK_RESET()
//! @}
#endif // _USB_PROTOCOL_CDC_H_
dstat-firmware-master/src/asf/common/services/usb/udc/ 0000775 0000000 0000000 00000000000 13317465730 0023330 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/services/usb/udc/udc.c 0000664 0000000 0000000 00000067110 13317465730 0024254 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief USB Device Controller (UDC)
*
* Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "conf_usb.h"
#include "usb_protocol.h"
#include "udd.h"
#include "udc_desc.h"
#include "udi.h"
#include "udc.h"
/**
* \ingroup udc_group
* \defgroup udc_group_interne Implementation of UDC
*
* Internal implementation
* @{
*/
//! \name Internal variables to manage the USB device
//! @{
//! Device status state (see enum usb_device_status in usb_protocol.h)
static le16_t udc_device_status;
//! Device Configuration number selected by the USB host
static uint8_t udc_num_configuration = 0;
//! Pointer on the selected speed device configuration
static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf;
//! Pointer on interface descriptor used by SETUP request.
static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface;
//! @}
//! \name Internal structure to store the USB device main strings
//! @{
/**
* \brief Language ID of USB device (US ID by default)
*/
COMPILER_WORD_ALIGNED
static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = {
.desc.bLength = sizeof(usb_str_lgid_desc_t),
.desc.bDescriptorType = USB_DT_STRING,
.string = {LE16(USB_LANGID_EN_US)}
};
/**
* \brief USB device manufacture name storage
* String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared
* by usb application configuration
*/
#ifdef USB_DEVICE_MANUFACTURE_NAME
static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME;
# define USB_DEVICE_MANUFACTURE_NAME_SIZE \
(sizeof(udc_string_manufacturer_name)-1)
#else
# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0
#endif
/**
* \brief USB device product name storage
* String is allocated only if USB_DEVICE_PRODUCT_NAME is declared
* by usb application configuration
*/
#ifdef USB_DEVICE_PRODUCT_NAME
static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME;
# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1)
#else
# define USB_DEVICE_PRODUCT_NAME_SIZE 0
#endif
/**
* \brief Get USB device serial number
*
* Use the define USB_DEVICE_SERIAL_NAME to set static serial number.
*
* For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER
* to a suitable pointer. This will also require the serial number length
* define USB_DEVICE_GET_SERIAL_NAME_LENGTH.
*/
#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER
static const uint8_t *udc_get_string_serial_name(void)
{
return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER;
}
# define USB_DEVICE_SERIAL_NAME_SIZE \
USB_DEVICE_GET_SERIAL_NAME_LENGTH
#elif defined USB_DEVICE_SERIAL_NAME
static const uint8_t *udc_get_string_serial_name(void)
{
return (const uint8_t *)USB_DEVICE_SERIAL_NAME;
}
# define USB_DEVICE_SERIAL_NAME_SIZE \
(sizeof(USB_DEVICE_SERIAL_NAME)-1)
#else
# define USB_DEVICE_SERIAL_NAME_SIZE 0
#endif
/**
* \brief USB device string descriptor
* Structure used to transfer ASCII strings to USB String descriptor structure.
*/
struct udc_string_desc_t {
usb_str_desc_t header;
le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \
USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)];
};
COMPILER_WORD_ALIGNED
static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = {
.header.bDescriptorType = USB_DT_STRING
};
//! @}
usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void)
{
return udc_ptr_iface;
}
/**
* \brief Returns a value to check the end of USB Configuration descriptor
*
* \return address after the last byte of USB Configuration descriptor
*/
static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void)
{
return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *)
udc_ptr_conf->desc +
le16_to_cpu(udc_ptr_conf->desc->wTotalLength));
}
#if (0!=USB_DEVICE_MAX_EP)
/**
* \brief Search specific descriptor in global interface descriptor
*
* \param desc Address of interface descriptor
* or previous specific descriptor found
* \param desc_id Descriptor ID to search
*
* \return address of specific descriptor found
* \return NULL if it is the end of global interface descriptor
*/
static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t
UDC_DESC_STORAGE * desc, uint8_t desc_id)
{
usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc;
ptr_eof_desc = udc_get_eof_conf();
// Go to next descriptor
desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc +
desc->bLength);
// Check the end of configuration descriptor
while (ptr_eof_desc > desc) {
// If new interface descriptor is found,
// then it is the end of the current global interface descriptor
if (USB_DT_INTERFACE == desc->bDescriptorType) {
break; // End of global interface descriptor
}
if (desc_id == desc->bDescriptorType) {
return desc; // Specific descriptor found
}
// Go to next descriptor
desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc +
desc->bLength);
}
return NULL; // No specific descriptor found
}
#endif
/**
* \brief Search an interface descriptor
* This routine updates the internal pointer udc_ptr_iface.
*
* \param iface_num Interface number to find in Configuration Descriptor
* \param setting_num Setting number of interface to find
*
* \return 1 if found or 0 if not found
*/
static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num)
{
usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc;
if (0 == udc_num_configuration) {
return false;
}
if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) {
return false;
}
// Start at the beginning of configuration descriptor
udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *)
udc_ptr_conf->desc;
// Check the end of configuration descriptor
ptr_end_desc = udc_get_eof_conf();
while (ptr_end_desc >
(UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) {
if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) {
// A interface descriptor is found
// Check interface and alternate setting number
if ((iface_num == udc_ptr_iface->bInterfaceNumber) &&
(setting_num ==
udc_ptr_iface->bAlternateSetting)) {
return true; // Interface found
}
}
// Go to next descriptor
udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) (
(uint8_t *) udc_ptr_iface +
udc_ptr_iface->bLength);
}
return false; // Interface not found
}
/**
* \brief Disables an usb device interface (UDI)
* This routine call the UDI corresponding to interface number
*
* \param iface_num Interface number to disable
*
* \return 1 if it is done or 0 if interface is not found
*/
static bool udc_iface_disable(uint8_t iface_num)
{
udi_api_t UDC_DESC_STORAGE *udi_api;
// Select first alternate setting of the interface
// to update udc_ptr_iface before call iface->getsetting()
if (!udc_update_iface_desc(iface_num, 0)) {
return false;
}
// Select the interface with the current alternate setting
udi_api = udc_ptr_conf->udi_apis[iface_num];
#if (0!=USB_DEVICE_MAX_EP)
if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) {
return false;
}
// Start at the beginning of interface descriptor
{
usb_ep_desc_t UDC_DESC_STORAGE *ep_desc;
ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface;
while (1) {
// Search Endpoint descriptor included in global interface descriptor
ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)
udc_next_desc_in_iface((UDC_DESC_STORAGE
usb_conf_desc_t *)
ep_desc, USB_DT_ENDPOINT);
if (NULL == ep_desc) {
break;
}
// Free the endpoint used by the interface
udd_ep_free(ep_desc->bEndpointAddress);
}
}
#endif
// Disable interface
udi_api->disable();
return true;
}
/**
* \brief Enables an usb device interface (UDI)
* This routine calls the UDI corresponding
* to the interface and setting number.
*
* \param iface_num Interface number to enable
* \param setting_num Setting number to enable
*
* \return 1 if it is done or 0 if interface is not found
*/
static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num)
{
// Select the interface descriptor
if (!udc_update_iface_desc(iface_num, setting_num)) {
return false;
}
#if (0!=USB_DEVICE_MAX_EP)
usb_ep_desc_t UDC_DESC_STORAGE *ep_desc;
// Start at the beginning of the global interface descriptor
ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface;
while (1) {
// Search Endpoint descriptor included in the global interface descriptor
ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *)
udc_next_desc_in_iface((UDC_DESC_STORAGE
usb_conf_desc_t *) ep_desc,
USB_DT_ENDPOINT);
if (NULL == ep_desc)
break;
// Alloc the endpoint used by the interface
if (!udd_ep_alloc(ep_desc->bEndpointAddress,
ep_desc->bmAttributes,
le16_to_cpu
(ep_desc->wMaxPacketSize))) {
return false;
}
}
#endif
// Enable the interface
return udc_ptr_conf->udi_apis[iface_num]->enable();
}
/*! \brief Start the USB Device stack
*/
void udc_start(void)
{
udd_enable();
}
/*! \brief Stop the USB Device stack
*/
void udc_stop(void)
{
udd_disable();
}
/**
* \brief Reset the current configuration of the USB device,
* This routines can be called by UDD when a RESET on the USB line occurs.
*/
void udc_reset(void)
{
uint8_t iface_num;
if (udc_num_configuration) {
for (iface_num = 0;
iface_num < udc_ptr_conf->desc->bNumInterfaces;
iface_num++) {
udc_iface_disable(iface_num);
}
}
udc_num_configuration = 0;
#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
== (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) {
// Remote wakeup is enabled then disable it
UDC_REMOTEWAKEUP_DISABLE();
}
#endif
udc_device_status =
#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED)
CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED);
#else
CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED);
#endif
}
void udc_sof_notify(void)
{
uint8_t iface_num;
if (udc_num_configuration) {
for (iface_num = 0;
iface_num < udc_ptr_conf->desc->bNumInterfaces;
iface_num++) {
if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) {
udc_ptr_conf->udi_apis[iface_num]->sof_notify();
}
}
}
}
/**
* \brief Standard device request to get device status
*
* \return true if success
*/
static bool udc_req_std_dev_get_status(void)
{
if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) {
return false;
}
udd_set_setup_payload( (uint8_t *) & udc_device_status,
sizeof(udc_device_status));
return true;
}
#if (0!=USB_DEVICE_MAX_EP)
/**
* \brief Standard endpoint request to get endpoint status
*
* \return true if success
*/
static bool udc_req_std_ep_get_status(void)
{
static le16_t udc_ep_status;
if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) {
return false;
}
udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req.
wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0;
udd_set_setup_payload( (uint8_t *) & udc_ep_status,
sizeof(udc_ep_status));
return true;
}
#endif
/**
* \brief Standard device request to change device status
*
* \return true if success
*/
static bool udc_req_std_dev_clear_feature(void)
{
if (udd_g_ctrlreq.req.wLength) {
return false;
}
if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) {
udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP);
#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
== (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
UDC_REMOTEWAKEUP_DISABLE();
#endif
return true;
}
return false;
}
#if (0!=USB_DEVICE_MAX_EP)
/**
* \brief Standard endpoint request to clear endpoint feature
*
* \return true if success
*/
static bool udc_req_std_ep_clear_feature(void)
{
if (udd_g_ctrlreq.req.wLength) {
return false;
}
if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) {
return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF);
}
return false;
}
#endif
/**
* \brief Standard device request to set a feature
*
* \return true if success
*/
static bool udc_req_std_dev_set_feature(void)
{
if (udd_g_ctrlreq.req.wLength) {
return false;
}
switch (udd_g_ctrlreq.req.wValue) {
case USB_DEV_FEATURE_REMOTE_WAKEUP:
#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \
== (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP))
udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP);
UDC_REMOTEWAKEUP_ENABLE();
return true;
#else
return false;
#endif
#ifdef USB_DEVICE_HS_SUPPORT
case USB_DEV_FEATURE_TEST_MODE:
if (!udd_is_high_speed()) {
break;
}
if (udd_g_ctrlreq.req.wIndex & 0xff) {
break;
}
// Unconfigure the device, terminating all ongoing requests
udc_reset();
switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) {
case USB_DEV_TEST_MODE_J:
udd_g_ctrlreq.callback = udd_test_mode_j;
return true;
case USB_DEV_TEST_MODE_K:
udd_g_ctrlreq.callback = udd_test_mode_k;
return true;
case USB_DEV_TEST_MODE_SE0_NAK:
udd_g_ctrlreq.callback = udd_test_mode_se0_nak;
return true;
case USB_DEV_TEST_MODE_PACKET:
udd_g_ctrlreq.callback = udd_test_mode_packet;
return true;
case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports
default:
break;
}
break;
#endif
default:
break;
}
return false;
}
/**
* \brief Standard endpoint request to halt an endpoint
*
* \return true if success
*/
#if (0!=USB_DEVICE_MAX_EP)
static bool udc_req_std_ep_set_feature(void)
{
if (udd_g_ctrlreq.req.wLength) {
return false;
}
if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) {
udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF);
return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF);
}
return false;
}
#endif
/**
* \brief Change the address of device
* Callback called at the end of request set address
*/
static void udc_valid_address(void)
{
udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F);
}
/**
* \brief Standard device request to set device address
*
* \return true if success
*/
static bool udc_req_std_dev_set_address(void)
{
if (udd_g_ctrlreq.req.wLength) {
return false;
}
// The address must be changed at the end of setup request after the handshake
// then we use a callback to change address
udd_g_ctrlreq.callback = udc_valid_address;
return true;
}
/**
* \brief Standard device request to get device string descriptor
*
* \return true if success
*/
static bool udc_req_std_dev_get_str_desc(void)
{
uint8_t i;
const uint8_t *str;
uint8_t str_length = 0;
// Link payload pointer to the string corresponding at request
switch (udd_g_ctrlreq.req.wValue & 0xff) {
case 0:
udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid,
sizeof(udc_string_desc_languageid));
break;
#ifdef USB_DEVICE_MANUFACTURE_NAME
case 1:
str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE;
str = udc_string_manufacturer_name;
break;
#endif
#ifdef USB_DEVICE_PRODUCT_NAME
case 2:
str_length = USB_DEVICE_PRODUCT_NAME_SIZE;
str = udc_string_product_name;
break;
#endif
#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER
case 3:
str_length = USB_DEVICE_SERIAL_NAME_SIZE;
str = udc_get_string_serial_name();
break;
#endif
default:
#ifdef UDC_GET_EXTRA_STRING
if (UDC_GET_EXTRA_STRING()) {
break;
}
#endif
return false;
}
if (str_length) {
for(i = 0; i < str_length; i++) {
udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]);
}
udc_string_desc.header.bLength = 2 + (str_length) * 2;
udd_set_setup_payload(
(uint8_t *) &udc_string_desc,
udc_string_desc.header.bLength);
}
return true;
}
/**
* \brief Standard device request to get descriptors about USB device
*
* \return true if success
*/
static bool udc_req_std_dev_get_descriptor(void)
{
uint8_t conf_num;
conf_num = udd_g_ctrlreq.req.wValue & 0xff;
// Check descriptor ID
switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) {
case USB_DT_DEVICE:
// Device descriptor requested
#ifdef USB_DEVICE_HS_SUPPORT
if (!udd_is_high_speed()) {
udd_set_setup_payload(
(uint8_t *) udc_config.confdev_hs,
udc_config.confdev_hs->bLength);
} else
#endif
{
udd_set_setup_payload(
(uint8_t *) udc_config.confdev_lsfs,
udc_config.confdev_lsfs->bLength);
}
break;
case USB_DT_CONFIGURATION:
// Configuration descriptor requested
#ifdef USB_DEVICE_HS_SUPPORT
if (udd_is_high_speed()) {
// HS descriptor
if (conf_num >= udc_config.confdev_hs->
bNumConfigurations) {
return false;
}
udd_set_setup_payload(
(uint8_t *)udc_config.conf_hs[conf_num].desc,
le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength));
} else
#endif
{
// FS descriptor
if (conf_num >= udc_config.confdev_lsfs->
bNumConfigurations) {
return false;
}
udd_set_setup_payload(
(uint8_t *)udc_config.conf_lsfs[conf_num].desc,
le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength));
}
((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType =
USB_DT_CONFIGURATION;
break;
#ifdef USB_DEVICE_HS_SUPPORT
case USB_DT_DEVICE_QUALIFIER:
// Device qualifier descriptor requested
udd_set_setup_payload( (uint8_t *) udc_config.qualifier,
udc_config.qualifier->bLength);
break;
case USB_DT_OTHER_SPEED_CONFIGURATION:
// Other configuration descriptor requested
if (!udd_is_high_speed()) {
// HS descriptor
if (conf_num >= udc_config.confdev_hs->
bNumConfigurations) {
return false;
}
udd_set_setup_payload(
(uint8_t *)udc_config.conf_hs[conf_num].desc,
le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength));
} else {
// FS descriptor
if (conf_num >= udc_config.confdev_lsfs->
bNumConfigurations) {
return false;
}
udd_set_setup_payload(
(uint8_t *)udc_config.conf_lsfs[conf_num].desc,
le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength));
}
((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType =
USB_DT_OTHER_SPEED_CONFIGURATION;
break;
#endif
case USB_DT_STRING:
// String descriptor requested
if (!udc_req_std_dev_get_str_desc()) {
return false;
}
break;
default:
// Unknown descriptor requested
return false;
}
// if the descriptor is larger than length requested, then reduce it
if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) {
udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength;
}
return true;
}
/**
* \brief Standard device request to get configuration number
*
* \return true if success
*/
static bool udc_req_std_dev_get_configuration(void)
{
if (udd_g_ctrlreq.req.wLength != 1) {
return false;
}
udd_set_setup_payload(&udc_num_configuration,1);
return true;
}
/**
* \brief Standard device request to enable a configuration
*
* \return true if success
*/
static bool udc_req_std_dev_set_configuration(void)
{
uint8_t iface_num;
// Check request length
if (udd_g_ctrlreq.req.wLength) {
return false;
}
// Authorize configuration only if the address is valid
if (!udd_getaddress()) {
return false;
}
// Check the configuration number requested
#ifdef USB_DEVICE_HS_SUPPORT
if (udd_is_high_speed()) {
// HS descriptor
if ((udd_g_ctrlreq.req.wValue & 0xFF) >
udc_config.confdev_hs->bNumConfigurations) {
return false;
}
} else
#endif
{
// FS descriptor
if ((udd_g_ctrlreq.req.wValue & 0xFF) >
udc_config.confdev_lsfs->bNumConfigurations) {
return false;
}
}
// Reset current configuration
udc_reset();
// Enable new configuration
udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF;
if (udc_num_configuration == 0) {
return true; // Default empty configuration requested
}
// Update pointer of the configuration descriptor
#ifdef USB_DEVICE_HS_SUPPORT
if (udd_is_high_speed()) {
// HS descriptor
udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1];
} else
#endif
{
// FS descriptor
udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1];
}
// Enable all interfaces of the selected configuration
for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces;
iface_num++) {
if (!udc_iface_enable(iface_num, 0)) {
return false;
}
}
return true;
}
/**
* \brief Standard interface request
* to get the alternate setting number of an interface
*
* \return true if success
*/
static bool udc_req_std_iface_get_setting(void)
{
static uint8_t udc_iface_setting;
uint8_t iface_num;
udi_api_t UDC_DESC_STORAGE *udi_api;
if (udd_g_ctrlreq.req.wLength != 1) {
return false; // Error in request
}
if (!udc_num_configuration) {
return false; // The device is not is configured state yet
}
// Check the interface number included in the request
iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) {
return false;
}
// Select first alternate setting of the interface to update udc_ptr_iface
// before call iface->getsetting()
if (!udc_update_iface_desc(iface_num, 0)) {
return false;
}
// Get alternate setting from UDI
udi_api = udc_ptr_conf->udi_apis[iface_num];
udc_iface_setting = udi_api->getsetting();
// Link value to payload pointer of request
udd_set_setup_payload(&udc_iface_setting,1);
return true;
}
/**
* \brief Standard interface request
* to set an alternate setting of an interface
*
* \return true if success
*/
static bool udc_req_std_iface_set_setting(void)
{
uint8_t iface_num, setting_num;
if (udd_g_ctrlreq.req.wLength) {
return false; // Error in request
}
if (!udc_num_configuration) {
return false; // The device is not is configured state yet
}
iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
setting_num = udd_g_ctrlreq.req.wValue & 0xFF;
// Disable current setting
if (!udc_iface_disable(iface_num)) {
return false;
}
// Enable new setting
return udc_iface_enable(iface_num, setting_num);
}
/**
* \brief Main routine to manage the standard USB SETUP request
*
* \return true if the request is supported
*/
static bool udc_reqstd(void)
{
if (Udd_setup_is_in()) {
// GET Standard Requests
if (udd_g_ctrlreq.req.wLength == 0) {
return false; // Error for USB host
}
if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) {
// Standard Get Device request
switch (udd_g_ctrlreq.req.bRequest) {
case USB_REQ_GET_STATUS:
return udc_req_std_dev_get_status();
case USB_REQ_GET_DESCRIPTOR:
return udc_req_std_dev_get_descriptor();
case USB_REQ_GET_CONFIGURATION:
return udc_req_std_dev_get_configuration();
default:
break;
}
}
if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) {
// Standard Get Interface request
switch (udd_g_ctrlreq.req.bRequest) {
case USB_REQ_GET_INTERFACE:
return udc_req_std_iface_get_setting();
default:
break;
}
}
#if (0!=USB_DEVICE_MAX_EP)
if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) {
// Standard Get Endpoint request
switch (udd_g_ctrlreq.req.bRequest) {
case USB_REQ_GET_STATUS:
return udc_req_std_ep_get_status();
default:
break;
}
}
#endif
} else {
// SET Standard Requests
if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) {
// Standard Set Device request
switch (udd_g_ctrlreq.req.bRequest) {
case USB_REQ_SET_ADDRESS:
return udc_req_std_dev_set_address();
case USB_REQ_CLEAR_FEATURE:
return udc_req_std_dev_clear_feature();
case USB_REQ_SET_FEATURE:
return udc_req_std_dev_set_feature();
case USB_REQ_SET_CONFIGURATION:
return udc_req_std_dev_set_configuration();
case USB_REQ_SET_DESCRIPTOR:
/* Not supported (defined as optional by the USB 2.0 spec) */
break;
default:
break;
}
}
if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) {
// Standard Set Interface request
switch (udd_g_ctrlreq.req.bRequest) {
case USB_REQ_SET_INTERFACE:
return udc_req_std_iface_set_setting();
default:
break;
}
}
#if (0!=USB_DEVICE_MAX_EP)
if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) {
// Standard Set Endpoint request
switch (udd_g_ctrlreq.req.bRequest) {
case USB_REQ_CLEAR_FEATURE:
return udc_req_std_ep_clear_feature();
case USB_REQ_SET_FEATURE:
return udc_req_std_ep_set_feature();
default:
break;
}
}
#endif
}
return false;
}
/**
* \brief Send the SETUP interface request to UDI
*
* \return true if the request is supported
*/
static bool udc_req_iface(void)
{
uint8_t iface_num;
udi_api_t UDC_DESC_STORAGE *udi_api;
if (0 == udc_num_configuration) {
return false; // The device is not is configured state yet
}
// Check interface number
iface_num = udd_g_ctrlreq.req.wIndex & 0xFF;
if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) {
return false;
}
//* To update udc_ptr_iface with the selected interface in request
// Select first alternate setting of interface to update udc_ptr_iface
// before calling udi_api->getsetting()
if (!udc_update_iface_desc(iface_num, 0)) {
return false;
}
// Select the interface with the current alternate setting
udi_api = udc_ptr_conf->udi_apis[iface_num];
if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) {
return false;
}
// Send the SETUP request to the UDI corresponding to the interface number
return udi_api->setup();
}
/**
* \brief Main routine to manage the USB SETUP request.
*
* This function parses a USB SETUP request and submits an appropriate
* response back to the host or, in the case of SETUP OUT requests
* with data, sets up a buffer for receiving the data payload.
*
* The main standard requests defined by the USB 2.0 standard are handled
* internally. The interface requests are sent to UDI, and the specific request
* sent to a specific application callback.
*
* \return true if the request is supported, else the request is stalled by UDD
*/
bool udc_process_setup(void)
{
// By default no data (receive/send) and no callbacks registered
udd_g_ctrlreq.payload_size = 0;
udd_g_ctrlreq.callback = NULL;
udd_g_ctrlreq.over_under_run = NULL;
if (Udd_setup_is_in()) {
if (udd_g_ctrlreq.req.wLength == 0) {
return false; // Error from USB host
}
}
// If standard request then try to decode it in UDC
if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) {
if (udc_reqstd()) {
return true;
}
}
// If interface request then try to decode it in UDI
if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) {
if (udc_req_iface()) {
return true;
}
}
// Here SETUP request unknown by UDC and UDIs
#ifdef USB_DEVICE_SPECIFIC_REQUEST
// Try to decode it in specific callback
return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,...
#else
return false;
#endif
}
//! @}
dstat-firmware-master/src/asf/common/services/usb/udc/udc.h 0000664 0000000 0000000 00000060124 13317465730 0024257 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Interface of the USB Device Controller (UDC)
*
* Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _UDC_H_
#define _UDC_H_
#include "conf_usb.h"
#include "usb_protocol.h"
#include "udc_desc.h"
#include "udd.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \ingroup usb_device_group
* \defgroup udc_group USB Device Controller (UDC)
*
* The UDC provides a high-level abstraction of the usb device.
* You can use these functions to control the main device state
* (start/attach/wakeup).
*
* \section USB_DEVICE_CONF USB Device Custom configuration
* The following USB Device configuration must be included in the conf_usb.h
* file of the application.
*
* USB_DEVICE_VENDOR_ID (Word)
* Vendor ID provided by USB org (ATMEL 0x03EB).
*
* USB_DEVICE_PRODUCT_ID (Word)
* Product ID (Referenced in usb_atmel.h).
*
* USB_DEVICE_MAJOR_VERSION (Byte)
* Major version of the device
*
* USB_DEVICE_MINOR_VERSION (Byte)
* Minor version of the device
*
* USB_DEVICE_MANUFACTURE_NAME (string)
* ASCII name for the manufacture
*
* USB_DEVICE_PRODUCT_NAME (string)
* ASCII name for the product
*
* USB_DEVICE_SERIAL_NAME (string)
* ASCII name to enable and set a serial number
*
* USB_DEVICE_POWER (Numeric)
* (unit mA) Maximum device power
*
* USB_DEVICE_ATTR (Byte)
* USB attributes available:
* - USB_CONFIG_ATTR_SELF_POWERED
* - USB_CONFIG_ATTR_REMOTE_WAKEUP
* Note: if remote wake enabled then defines remotewakeup callbacks,
* see Table 5-2. External API from UDC - Callback
*
* USB_DEVICE_LOW_SPEED (Only defined)
* Force the USB Device to run in low speed
*
* USB_DEVICE_HS_SUPPORT (Only defined)
* Authorize the USB Device to run in high speed
*
* USB_DEVICE_MAX_EP (Byte)
* Define the maximum endpoint number used by the USB Device.
* This one is already defined in UDI default configuration.
* Ex:
* - When endpoint control 0x00, endpoint 0x01 and
* endpoint 0x82 is used then USB_DEVICE_MAX_EP=2
* - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0
* - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
* (configuration not possible on USBB interface)
* @{
*/
/**
* \brief Authorizes the VBUS event
*
* \return true, if the VBUS monitoring is possible.
*
* \section udc_vbus_monitoring VBus monitoring used cases
*
* The VBus monitoring is used only for USB SELF Power application.
*
* - No custom implementation \n
* // Authorize VBUS monitoring \n
* if (!udc_include_vbus_monitoring()) { \n
* // VBUS monitoring is not available on this product \n
* // thereby VBUS has to be considered as present \n
* // Attach USB Device \n
* udc_attach(); \n
* } \n
*
* - Add custom VBUS monitoring \n
* // Authorize VBUS monitoring \n
* if (!udc_include_vbus_monitoring()) { \n
* // Implement custom VBUS monitoring via GPIO or other \n
* } \n
* Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n
* { \n
* // Attach USB Device \n
* udc_attach(); \n
* } \n
*
* - Case of battery charging \n
* Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n
* { \n
* // Authorize battery charging, but wait key press to start USB. \n
* } \n
* Event Key press() \n
* { \n
* // Stop batteries charging \n
* // Start USB \n
* udc_attach(); \n
* } \n
*/
static inline bool udc_include_vbus_monitoring(void)
{
return udd_include_vbus_monitoring();
}
/*! \brief Start the USB Device stack
*/
void udc_start(void);
/*! \brief Stop the USB Device stack
*/
void udc_stop(void);
/**
* \brief Attach device to the bus when possible
*
* \warning If a VBus control is included in driver,
* then it will attach device when an acceptable Vbus
* level from the host is detected.
*/
static inline void udc_attach(void)
{
udd_attach();
}
/**
* \brief Detaches the device from the bus
*
* The driver must remove pull-up on USB line D- or D+.
*/
static inline void udc_detach(void)
{
udd_detach();
}
/*! \brief The USB driver sends a resume signal called \e "Upstream Resume"
* This is authorized only when the remote wakeup feature is enabled by host.
*/
static inline void udc_remotewakeup(void)
{
udd_send_remotewakeup();
}
/**
* \brief Returns a pointer on the current interface descriptor
*
* \return pointer on the current interface descriptor.
*/
usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void);
//@}
/**
* \ingroup usb_group
* \defgroup usb_device_group USB Stack Device
*
* This module includes USB Stack Device implementation.
* The stack is divided in three parts:
* - USB Device Controller (UDC) provides USB chapter 9 compliance
* - USB Device Interface (UDI) provides USB Class compliance
* - USB Device Driver (UDD) provides USB Driver for each Atmel MCU
* Many USB Device applications can be implemented on Atmel MCU.
* Atmel provides many application notes for different applications:
* - AVR4900, provides general information about Device Stack
* - AVR4901, explains how to create a new class
* - AVR4902, explains how to create a composite device
* - AVR49xx, all device classes provided in ASF have an application note
*
* A basic USB knowledge is required to understand the USB Device
* Class application notes (HID,MS,CDC,PHDC,...).
* Then, to create an USB device with
* only one class provided by ASF, refer directly to the application note
* corresponding to this USB class. The USB Device application note for
* New Class and Composite is dedicated to advanced USB users.
*
* @{
*/
//! @}
#ifdef __cplusplus
}
#endif
/**
* \ingroup udc_group
* \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites
* Common prerequisites for all USB devices.
*
* This module is based on USB device stack full interrupt driven, and supporting
* \ref sleepmgr_group sleepmgr and \ref clk_group clock services.
*
* The following procedure must be executed to setup the project correctly:
* - Specify the clock configuration:
* - XMEGA USB devices need 48MHz clock input.\n
* XMEGA USB devices need CPU frequency higher than 12MHz.\n
* You can use either an internal RC48MHz auto calibrated by Start of Frames
* or an external OSC.
* - UC3 and SAM devices without USB high speed support need 48MHz clock input.\n
* You must use a PLL and an external OSC.
* - UC3 and SAM devices with USB high speed support need 12MHz clock input.\n
* You must use an external OSC.
* - UC3 devices with USBC hardware need CPU frequency higher than 25MHz.
* - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines.
* (Not mandatory for all boards)
* - Enable interrupts
* - Initialize the clock service
*
* The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power
* consumption:
* - Initialize the sleep manager service
* - Activate sleep mode when the application is in IDLE state
*
* \subpage udc_conf_clock.
*
* Add to the initialization code:
* \code
* sysclk_init();
* irq_initialize_vectors();
* cpu_irq_enable();
* board_init();
* sleepmgr_init(); // Optional
* \endcode
* Add to the main IDLE loop:
* \code
* sleepmgr_enter_sleep(); // Optional
* \endcode
*
*/
/**
* \ingroup udc_group
* \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code
* Common example code for all USB devices.
*
* Content of conf_usb.h:
* \code
* #define USB_DEVICE_VENDOR_ID 0x03EB
* #define USB_DEVICE_PRODUCT_ID 0xXXXX
* #define USB_DEVICE_MAJOR_VERSION 1
* #define USB_DEVICE_MINOR_VERSION 0
* #define USB_DEVICE_POWER 100
* #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED
*
* #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high)
* extern void my_vbus_action(bool b_high);
* \endcode
*
* Add to application C-file:
* \code
* void usb_init(void)
* {
* udc_start();
* }
*
* void my_vbus_action(bool b_high)
* {
* if (b_high) {
* // Attach USB Device
* udc_attach();
* } else {
* // Vbus not present
* udc_detach();
* }
* }
* \endcode
*/
/**
* \ingroup udc_group
* \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow
* Common workflow for all USB devices.
*
* -# Ensure that conf_usb.h is available and contains the following configuration
* which is the main USB device configuration:
* - \code // Vendor ID provided by USB org (ATMEL 0x03EB)
* #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word
* // Product ID (Atmel PID referenced in usb_atmel.h)
* #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word
* // Major version of the device
* #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte
* // Minor version of the device
* #define USB_DEVICE_MINOR_VERSION 0 // Type Byte
* // Maximum device power (mA)
* #define USB_DEVICE_POWER 100 // Type 9-bits
* // USB attributes to enable features
* #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode
* - \code #define UDC_VBUS_EVENT(b_vbus_high) my_vbus_action(b_vbus_high)
* extern void my_vbus_action(bool b_high); \endcode
* \note This callback is called when USB Device cable is plugged or unplugged.
* -# Call the USB device stack start function to enable stack:
* - \code udc_start(); \endcode
* \note In case of USB dual roles (Device and Host) managed through USB OTG connector
* (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start().
* SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles.
* -# Connect or disconnect USB device according to Vbus state:
* - \code void my_vbus_action(bool b_high)
* {
* if (b_high) {
* // Attach USB Device
* udc_attach();
* } else {
* // Vbus not present
* udc_detach();
* }
* } \endcode
*/
/**
* \page udc_conf_clock conf_clock.h examples with USB support
*
* Content of XMEGA conf_clock.h:
* \code
* // Configuration based on internal RC:
* // USB clock need of 48Mhz
* #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC
* #define CONFIG_OSC_RC32_CAL 48000000UL
* #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF
* // CPU clock need of clock > 12MHz to run with USB (Here 24MHz)
* #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ
* #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2
* #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1
* \endcode
*
* Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB):
* \code
* // Configuration based on 12MHz external OSC:
* #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0
* #define CONFIG_PLL1_MUL 8
* #define CONFIG_PLL1_DIV 2
* #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1
* #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div)
* \endcode
*
* Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support):
* \code
* // Configuration based on 12MHz external OSC:
* #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0
* #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div)
* \endcode
*
* Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC):
* \code
* // Configuration based on 12MHz external OSC:
* #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0
* #define CONFIG_PLL1_MUL 8
* #define CONFIG_PLL1_DIV 2
* #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1
* #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div)
* // CPU clock need of clock > 25MHz to run with USBC
* #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1
* \endcode
*
* Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device):
* \code
* // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div)
* #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL
* #define CONFIG_PLL1_MUL 16
* #define CONFIG_PLL1_DIV 2
* // USB Clock Source Options (Fusb = FpllX / USB_div)
* #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1
* #define CONFIG_USBCLK_DIV 2
* \endcode
*
* Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed):
* \code
* // USB Clock Source fixed at UPLL.
* \endcode
*
* Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed):
* \code
* // USB Clock Source fixed at UPLL.
* #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL
* #define CONFIG_USBCLK_DIV 1
* \endcode
*/
/**
* \page udc_use_case_1 Change USB speed
*
* In this use case, the USB device is used with different USB speeds.
*
* \section udc_use_case_1_setup Setup steps
*
* Prior to implement this use case, be sure to have already
* apply the UDI module "basic use case".
*
* \section udc_use_case_1_usage Usage steps
*
* \subsection udc_use_case_1_usage_code Example code
* Content of conf_usb.h:
* \code
* #if // Low speed
* #define USB_DEVICE_LOW_SPEED
* // #define USB_DEVICE_HS_SUPPORT
*
* #elif // Full speed
* // #define USB_DEVICE_LOW_SPEED
* // #define USB_DEVICE_HS_SUPPORT
*
* #elif // High speed
* // #define USB_DEVICE_LOW_SPEED
* #define USB_DEVICE_HS_SUPPORT
*
* #endif
* \endcode
*
* \subsection udc_use_case_1_usage_flow Workflow
* -# Ensure that conf_usb.h is available and contains the following parameters
* required for a USB device low speed (1.5Mbit/s):
* - \code #define USB_DEVICE_LOW_SPEED
* //#define USB_DEVICE_HS_SUPPORT \endcode
* -# Ensure that conf_usb.h contains the following parameters
* required for a USB device full speed (12Mbit/s):
* - \code //#define USB_DEVICE_LOW_SPEED
* //#define USB_DEVICE_HS_SUPPORT \endcode
* -# Ensure that conf_usb.h contains the following parameters
* required for a USB device high speed (480Mbit/s):
* - \code //#define USB_DEVICE_LOW_SPEED
* #define USB_DEVICE_HS_SUPPORT \endcode
*/
/**
* \page udc_use_case_2 Use USB strings
*
* In this use case, the usual USB strings is added in the USB device.
*
* \section udc_use_case_2_setup Setup steps
* Prior to implement this use case, be sure to have already
* apply the UDI module "basic use case".
*
* \section udc_use_case_2_usage Usage steps
*
* \subsection udc_use_case_2_usage_code Example code
* Content of conf_usb.h:
* \code
* #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name"
* #define USB_DEVICE_PRODUCT_NAME "Product name"
* #define USB_DEVICE_SERIAL_NAME "12...EF"
* \endcode
*
* \subsection udc_use_case_2_usage_flow Workflow
* -# Ensure that conf_usb.h is available and contains the following parameters
* required to enable different USB strings:
* - \code // Static ASCII name for the manufacture
* #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode
* - \code // Static ASCII name for the product
* #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode
* - \code // Static ASCII name to enable and set a serial number
* #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode
*/
/**
* \page udc_use_case_3 Use USB remote wakeup feature
*
* In this use case, the USB remote wakeup feature is enabled.
*
* \section udc_use_case_3_setup Setup steps
* Prior to implement this use case, be sure to have already
* apply the UDI module "basic use case".
*
* \section udc_use_case_3_usage Usage steps
*
* \subsection udc_use_case_3_usage_code Example code
* Content of conf_usb.h:
* \code
* #define USB_DEVICE_ATTR \
* (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED)
* #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable()
* extern void my_callback_remotewakeup_enable(void);
* #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable()
* extern void my_callback_remotewakeup_disable(void);
* \endcode
*
* Add to application C-file:
* \code
* void my_callback_remotewakeup_enable(void)
* {
* // Enable application wakeup events (e.g. enable GPIO interrupt)
* }
* void my_callback_remotewakeup_disable(void)
* {
* // Disable application wakeup events (e.g. disable GPIO interrupt)
* }
*
* void my_interrupt_event(void)
* {
* udc_remotewakeup();
* }
* \endcode
*
* \subsection udc_use_case_3_usage_flow Workflow
* -# Ensure that conf_usb.h is available and contains the following parameters
* required to enable remote wakeup feature:
* - \code // Authorizes the remote wakeup feature
* #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode
* - \code // Define callback called when the host enables the remotewakeup feature
* #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable()
* extern void my_callback_remotewakeup_enable(void); \endcode
* - \code // Define callback called when the host disables the remotewakeup feature
* #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable()
* extern void my_callback_remotewakeup_disable(void); \endcode
* -# Send a remote wakeup (USB upstream):
* - \code udc_remotewakeup(); \endcode
*/
/**
* \page udc_use_case_4 Self power application recommendations
*
* In this use case, the USB device self power feature is enabled.
* To be USB compliance, the SELF power application requires to manage Vbus event,
* because the USB device D+/- pull-up must be disabled if the USB cable is unplugged
* (unplug = Vbus not present, pull-up disable = \ref udd_detach()).
* This use case requires that Atmel products includes a Vbus monitoring, else
* see \ref udc_include_vbus_monitoring function documentation for more example.
*
* \section udc_use_case_4_setup Setup steps
* Prior to implement this use case, be sure to have already
* apply the UDI module "basic use case".
*
* \section udc_use_case_4_usage Usage steps
*
* \subsection udc_use_case_4_usage_code Example code
* Content of conf_usb.h:
* \code
* #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED)
* #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high)
* extern void user_callback_vbus_action(bool b_vbus_high);
* \endcode
*
* Add to application C-file:
* \code
* void user_callback_vbus_action(bool b_vbus_high)
* {
* if (b_high) {
* // Attach USB Device
* udc_attach();
* } else {
* // Vbus not present
* udc_detach();
* }
* }
* \endcode
*
* \subsection udc_use_case_4_usage_flow Workflow
* -# Ensure that conf_usb.h is available and contains the following parameters
* required for USB device SELF power device:
* - \code // Authorizes the SELF power feature
* #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_SELF_POWERED) \endcode
* - \code // Define callback called when the Vbus level change
* #define UDC_VBUS_EVENT(b_vbus_high) user_callback_vbus_action(b_vbus_high)
* extern void user_callback_vbus_action(bool b_vbus_high); \endcode
* -# Signal the USB device presence on USB line
* - \code udc_attach(); \endcode
* -# Remove signal of the USB device presence on USB line
* - \code udc_detach(); \endcode
*/
/**
* \page udc_use_case_5 Bus power application recommendations
*
* In this use case, the USB device BUS power feature is enabled.
* This feature requires a correct power consumption management.
*
* \section udc_use_case_5_setup Setup steps
* Prior to implement this use case, be sure to have already
* apply the UDI module "basic use case".
*
* \section udc_use_case_5_usage Usage steps
*
* \subsection udc_use_case_5_usage_code Example code
* Content of conf_usb.h:
* \code
* #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED)
* #define UDC_SUSPEND_EVENT() user_callback_suspend_action()
* extern void user_callback_suspend_action(void)
* #define UDC_RESUME_EVENT() user_callback_resume_action()
* extern void user_callback_resume_action(void)
* \endcode
*
* Add to application C-file:
* \code
* void user_callback_suspend_action(void)
* {
* // Disable hardware component to reduce power consumption
* }
* void user_callback_resume_action(void)
* {
* // Re-enable hardware component
* }
* \endcode
*
* \subsection udc_use_case_5_usage_flow Workflow
* -# Ensure that conf_usb.h is available and contains the following parameters:
* - \code // Authorizes the BUS power feature
* #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode
* - \code // Define callback called when the host suspend the USB line
* #define UDC_SUSPEND_EVENT() user_callback_suspend_action()
* extern void user_callback_suspend_action(void); \endcode
* - \code // Define callback called when the host or device resume the USB line
* #define UDC_RESUME_EVENT() user_callback_resume_action()
* extern void user_callback_resume_action(void); \endcode
* -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus):
* - \code void user_callback_suspend_action(void)
* {
* turn_off_components();
* } \endcode
*/
/**
* \page udc_use_case_6 USB dynamic serial number
*
* In this use case, the USB serial strings is dynamic.
* For a static serial string refer to \ref udc_use_case_2.
*
* \section udc_use_case_6_setup Setup steps
* Prior to implement this use case, be sure to have already
* apply the UDI module "basic use case".
*
* \section udc_use_case_6_usage Usage steps
*
* \subsection udc_use_case_6_usage_code Example code
* Content of conf_usb.h:
* \code
* #define USB_DEVICE_SERIAL_NAME
* #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number
* #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12
* extern uint8_t serial_number[];
* \endcode
*
* Add to application C-file:
* \code
* uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH];
*
* void init_build_usb_serial_number(void)
* {
* serial_number[0] = 'A';
* serial_number[1] = 'B';
* ...
* serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C';
* } \endcode
*
* \subsection udc_use_case_6_usage_flow Workflow
* -# Ensure that conf_usb.h is available and contains the following parameters
* required to enable a USB serial number strings dynamically:
* - \code #define USB_DEVICE_SERIAL_NAME // Define this empty
* #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer
* #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array
* extern uint8_t serial_number[]; // Declare external serial array \endcode
* -# Before start USB stack, initialize the serial array
* - \code
* uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH];
*
* void init_build_usb_serial_number(void)
* {
* serial_number[0] = 'A';
* serial_number[1] = 'B';
* ...
* serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C';
* } \endcode
*/
#endif // _UDC_H_
dstat-firmware-master/src/asf/common/services/usb/udc/udc_desc.h 0000664 0000000 0000000 00000010163 13317465730 0025253 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Common API for USB Device Interface
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _UDC_DESC_H_
#define _UDC_DESC_H_
#include "conf_usb.h"
#include "usb_protocol.h"
#include "udi.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \ingroup udc_group
* \defgroup udc_desc_group USB Device Descriptor
*
* @{
*/
/**
* \brief Defines the memory's location of USB descriptors
*
* By default the Descriptor is stored in RAM
* (UDC_DESC_STORAGE is defined empty).
*
* If you have need to free RAM space,
* it is possible to put descriptor in flash in following case:
* - USB driver authorize flash transfer (USBB on UC3 and USB on Mega)
* - USB Device is not high speed (UDC no need to change USB descriptors)
*
* For UC3 application used "const".
*
* For Mega application used "code".
*/
#define UDC_DESC_STORAGE
// Descriptor storage in internal RAM
#if (defined UDC_DATA_USE_HRAM_SUPPORT)
# if defined(__GNUC__)
# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0")))
# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0")))
# elif defined(__ICCAVR32__)
# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32
# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32
# endif
#else
# define UDC_DATA(x) COMPILER_ALIGNED(x)
# define UDC_BSS(x) COMPILER_ALIGNED(x)
#endif
/**
* \brief Configuration descriptor and UDI link for one USB speed
*/
typedef struct {
//! USB configuration descriptor
usb_conf_desc_t UDC_DESC_STORAGE *desc;
//! Array of UDI API pointer
udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis;
} udc_config_speed_t;
/**
* \brief All information about the USB Device
*/
typedef struct {
//! USB device descriptor for low or full speed
usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs;
//! USB configuration descriptor and UDI API pointers for low or full speed
udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs;
#ifdef USB_DEVICE_HS_SUPPORT
//! USB device descriptor for high speed
usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs;
//! USB device qualifier, only use in high speed mode
usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier;
//! USB configuration descriptor and UDI API pointers for high speed
udc_config_speed_t UDC_DESC_STORAGE *conf_hs;
#endif
} udc_config_t;
//! Global variables of USB Device Descriptor and UDI links
extern UDC_DESC_STORAGE udc_config_t udc_config;
//@}
#ifdef __cplusplus
}
#endif
#endif // _UDC_DESC_H_
dstat-firmware-master/src/asf/common/services/usb/udc/udd.h 0000664 0000000 0000000 00000026501 13317465730 0024261 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Common API for USB Device Drivers (UDD)
*
* Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _UDD_H_
#define _UDD_H_
#include "usb_protocol.h"
#include "udc_desc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \ingroup usb_device_group
* \defgroup udd_group USB Device Driver (UDD)
*
* The UDD driver provides a low-level abstraction of the device
* controller hardware. Most events coming from the hardware such as
* interrupts, which may cause the UDD to call into the UDC and UDI.
*
* @{
*/
//! \brief Endpoint identifier
typedef uint8_t udd_ep_id_t;
//! \brief Endpoint transfer status
//! Returned in parameters of callback register via udd_ep_run routine.
typedef enum {
UDD_EP_TRANSFER_OK = 0,
UDD_EP_TRANSFER_ABORT = 1,
} udd_ep_status_t;
/**
* \brief Global variable to give and record information of the setup request management
*
* This global variable allows to decode and response a setup request.
* It can be updated by udc_process_setup() from UDC or *setup() from UDIs.
*/
typedef struct {
//! Data received in USB SETUP packet
//! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD.
usb_setup_req_t req;
//! Point to buffer to send or fill with data following SETUP packet
uint8_t *payload;
//! Size of buffer to send or fill, and content the number of byte transfered
uint16_t payload_size;
//! Callback called after reception of ZLP from setup request
void (*callback) (void);
//! Callback called when the buffer given (.payload) is full or empty.
//! This one return false to abort data transfer, or true with a new buffer in .payload.
bool(*over_under_run) (void);
} udd_ctrl_request_t;
extern udd_ctrl_request_t udd_g_ctrlreq;
//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer
#define Udd_setup_is_in() \
(USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK))
//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer
#define Udd_setup_is_out() \
(USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK))
//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype.
#define Udd_setup_type() \
(udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK)
//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient
#define Udd_setup_recipient() \
(udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK)
/**
* \brief End of halt callback function type.
* Registered by routine udd_ep_wait_stall_clear()
* Callback called when endpoint stall is cleared.
*/
typedef void (*udd_callback_halt_cleared_t) (void);
/**
* \brief End of transfer callback function type.
* Registered by routine udd_ep_run()
* Callback called by USB interrupt after data transfer or abort (reset,...).
*
* \param status UDD_EP_TRANSFER_OK, if transfer is complete
* \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted
* \param n number of data transfered
*/
typedef void (*udd_callback_trans_t) (udd_ep_status_t status,
iram_size_t nb_transfered, udd_ep_id_t ep);
/**
* \brief Authorizes the VBUS event
*
* \return true, if the VBUS monitoring is possible.
*/
bool udd_include_vbus_monitoring(void);
/**
* \brief Enables the USB Device mode
*/
void udd_enable(void);
/**
* \brief Disables the USB Device mode
*/
void udd_disable(void);
/**
* \brief Attach device to the bus when possible
*
* \warning If a VBus control is included in driver,
* then it will attach device when an acceptable Vbus
* level from the host is detected.
*/
void udd_attach(void);
/**
* \brief Detaches the device from the bus
*
* The driver must remove pull-up on USB line D- or D+.
*/
void udd_detach(void);
/**
* \brief Test whether the USB Device Controller is running at high
* speed or not.
*
* \return \c true if the Device is running at high speed mode, otherwise \c false.
*/
bool udd_is_high_speed(void);
/**
* \brief Changes the USB address of device
*
* \param address New USB address
*/
void udd_set_address(uint8_t address);
/**
* \brief Returns the USB address of device
*
* \return USB address
*/
uint8_t udd_getaddress(void);
/**
* \brief Returns the current start of frame number
*
* \return current start of frame number.
*/
uint16_t udd_get_frame_number(void);
/**
* \brief Returns the current micro start of frame number
*
* \return current micro start of frame number required in high speed mode.
*/
uint16_t udd_get_micro_frame_number(void);
/*! \brief The USB driver sends a resume signal called Upstream Resume
*/
void udd_send_remotewakeup(void);
/**
* \brief Load setup payload
*
* \param payload Pointer on payload
* \param payload_size Size of payload
*/
void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size );
/**
* \name Endpoint Management
*
* The following functions allow drivers to create and remove
* endpoints, as well as set, clear and query their "halted" and
* "wedged" states.
*/
//@{
#if (USB_DEVICE_MAX_EP != 0)
/**
* \brief Configures and enables an endpoint
*
* \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT).
* \param bmAttributes Attributes of endpoint declared in the descriptor.
* \param MaxEndpointSize Endpoint maximum size
*
* \return \c 1 if the endpoint is enabled, otherwise \c 0.
*/
bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes,
uint16_t MaxEndpointSize);
/**
* \brief Disables an endpoint
*
* \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT).
*/
void udd_ep_free(udd_ep_id_t ep);
/**
* \brief Check if the endpoint \a ep is halted.
*
* \param ep The ID of the endpoint to check.
*
* \return \c 1 if \a ep is halted, otherwise \c 0.
*/
bool udd_ep_is_halted(udd_ep_id_t ep);
/**
* \brief Set the halted state of the endpoint \a ep
*
* After calling this function, any transaction on \a ep will result
* in a STALL handshake being sent. Any pending transactions will be
* performed first, however.
*
* \param ep The ID of the endpoint to be halted
*
* \return \c 1 if \a ep is halted, otherwise \c 0.
*/
bool udd_ep_set_halt(udd_ep_id_t ep);
/**
* \brief Clear the halted state of the endpoint \a ep
*
* After calling this function, any transaction on \a ep will
* be handled normally, i.e. a STALL handshake will not be sent, and
* the data toggle sequence will start at DATA0.
*
* \param ep The ID of the endpoint to be un-halted
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
bool udd_ep_clear_halt(udd_ep_id_t ep);
/**
* \brief Registers a callback to call when endpoint halt is cleared
*
* \param ep The ID of the endpoint to use
* \param callback NULL or function to call when endpoint halt is cleared
*
* \warning if the endpoint is not halted then the \a callback is called immediately.
*
* \return \c 1 if the register is accepted, otherwise \c 0.
*/
bool udd_ep_wait_stall_clear(udd_ep_id_t ep,
udd_callback_halt_cleared_t callback);
/**
* \brief Allows to receive or send data on an endpoint
*
* The driver uses a specific DMA USB to transfer data
* from internal RAM to endpoint, if this one is available.
* When the transfer is finished or aborted (stall, reset, ...), the \a callback is called.
* The \a callback returns the transfer status and eventually the number of byte transfered.
* Note: The control endpoint is not authorized.
*
* \param ep The ID of the endpoint to use
* \param b_shortpacket Enabled automatic short packet
* \param buf Buffer on Internal RAM to send or fill.
* It must be align, then use COMPILER_WORD_ALIGNED.
* \param buf_size Buffer size to send or fill
* \param callback NULL or function to call at the end of transfer
*
* \warning About \a b_shortpacket, for IN endpoint it means that a short packet
* (or a Zero Length Packet) will be sent to the USB line to properly close the usb
* transfer at the end of the data transfer.
* For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer
* at the end of the data transfer (received short packet).
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket,
uint8_t * buf, iram_size_t buf_size,
udd_callback_trans_t callback);
/**
* \brief Aborts transfer on going on endpoint
*
* If a transfer is on going, then it is stopped and
* the callback registered is called to signal the end of transfer.
* Note: The control endpoint is not authorized.
*
* \param ep Endpoint to abort
*/
void udd_ep_abort(udd_ep_id_t ep);
#endif
//@}
/**
* \name High speed test mode management
*
* The following functions allow the device to jump to a specific test mode required in high speed mode.
*/
//@{
void udd_test_mode_j(void);
void udd_test_mode_k(void);
void udd_test_mode_se0_nak(void);
void udd_test_mode_packet(void);
//@}
/**
* \name UDC callbacks to provide for UDD
*
* The following callbacks are used by UDD.
*/
//@{
/**
* \brief Decodes and manages a setup request
*
* The driver call it when a SETUP packet is received.
* The \c udd_g_ctrlreq contains the data of SETUP packet.
* If this callback accepts the setup request then it must
* return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data.
*
* \return \c 1 if the request is accepted, otherwise \c 0.
*/
extern bool udc_process_setup(void);
/**
* \brief Reset the UDC
*
* The UDC must reset all configuration.
*/
extern void udc_reset(void);
/**
* \brief To signal that a SOF is occurred
*
* The UDC must send the signal to all UDIs enabled
*/
extern void udc_sof_notify(void);
//@}
//@}
#ifdef __cplusplus
}
#endif
#endif // _UDD_H_
dstat-firmware-master/src/asf/common/services/usb/udc/udi.h 0000664 0000000 0000000 00000007466 13317465730 0024277 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Common API for USB Device Interface
*
* Copyright (c) 2009 - 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _UDI_H_
#define _UDI_H_
#include "conf_usb.h"
#include "usb_protocol.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \ingroup usb_device_group
* \defgroup udi_group USB Device Interface (UDI)
* The UDI provides a common API for all classes,
* and this is used by UDC for the main control of USB Device interface.
* @{
*/
/**
* \brief UDI API.
*
* The callbacks within this structure are called only by
* USB Device Controller (UDC)
*
* The udc_get_interface_desc() can be use by UDI to know the interface descriptor
* selected by UDC.
*/
typedef struct {
/**
* \brief Enable the interface.
*
* This function is called when the host selects a configuration
* to which this interface belongs through a Set Configuration
* request, and when the host selects an alternate setting of
* this interface through a Set Interface request.
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
bool(*enable) (void);
/**
* \brief Disable the interface.
*
* This function is called when this interface is currently
* active, and
* - the host selects any configuration through a Set
* Configuration request, or
* - the host issues a USB reset, or
* - the device is detached from the host (i.e. Vbus is no
* longer present)
*/
void (*disable) (void);
/**
* \brief Handle a control request directed at an interface.
*
* This function is called when this interface is currently
* active and the host sends a SETUP request
* with this interface as the recipient.
*
* Use udd_g_ctrlreq to decode and response to SETUP request.
*
* \return \c 1 if this interface supports the SETUP request, otherwise \c 0.
*/
bool(*setup) (void);
/**
* \brief Returns the current setting of the selected interface.
*
* This function is called when UDC when know alternate setting of selected interface.
*
* \return alternate setting of selected interface
*/
uint8_t(*getsetting) (void);
/**
* \brief To signal that a SOF is occurred
*/
void(*sof_notify) (void);
} udi_api_t;
//@}
#ifdef __cplusplus
}
#endif
#endif // _UDI_H_
dstat-firmware-master/src/asf/common/services/usb/usb_atmel.h 0000664 0000000 0000000 00000017262 13317465730 0024711 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief All USB VIDs and PIDs from Atmel USB applications
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _USB_ATMEL_H_
#define _USB_ATMEL_H_
/**
* \defgroup usb_group USB Stack
*
* This stack includes the USB Device Stack, USB Host Stack and common
* definitions.
* @{
*/
//! @}
/**
* \ingroup usb_group
* \defgroup usb_atmel_ids_group Atmel USB Identifiers
*
* This module defines Atmel PID and VIDs constants.
*
* @{
*/
//! \name Vendor Identifier assigned by USB org to ATMEL
#define USB_VID_ATMEL 0x03EB
//! \name Product Identifier assigned by ATMEL to AVR applications
//! @{
//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others.
//! @{
#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013
#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017
#define USB_PID_ATMEL_MEGA_CDC 0x2018
#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019
#define USB_PID_ATMEL_MEGA_MS 0x201A
#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B
#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C
#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D
#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E
#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022
#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023
#define USB_PID_ATMEL_MEGA_MS_2 0x2029
#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A
#define USB_PID_ATMEL_MEGA_MS_3 0x2032
#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050
//! @}
//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools.
//! @{
#define USB_PID_ATMEL_XPLAINED 0x2122
//! @}
//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=>
//! @{
#define USB_PID_ATMEL_UC3_ENUM 0x2300
#define USB_PID_ATMEL_UC3_MS 0x2301
#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302
#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303
#define USB_PID_ATMEL_UC3_HID 0x2304
#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305
#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306
#define USB_PID_ATMEL_UC3_CDC 0x2307
#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308
#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx
#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311
#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312
//! @}
//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications
//! @{
#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400
#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401
#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402
#define USB_PID_ATMEL_ASF_MSC 0x2403
#define USB_PID_ATMEL_ASF_CDC 0x2404
#define USB_PID_ATMEL_ASF_PHDC 0x2405
#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420
#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421
#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422
#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423
#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424
#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425
#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426
#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430
#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431
#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432
#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433
#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434
//! @}
//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders
//! Note, !!!! don't use this range for demos or examples !!!!
//! @{
#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6
#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7
#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8
#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9
#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA
#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB
#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC
#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD
#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE
#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF
#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0
#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1
#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2
#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3
#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4
#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5
#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6
#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7
#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8
#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9
#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA
#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB
#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC
#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED
#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE
#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF
#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0
#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1
#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2
#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3
#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4
#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5
#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6
#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7
#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8
#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9
#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA
#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB
// 2FFCh to 2FFFh used by C51 family products
//! @}
//! @}
//! @}
#endif // _USB_ATMEL_H_
dstat-firmware-master/src/asf/common/services/usb/usb_protocol.h 0000664 0000000 0000000 00000024706 13317465730 0025451 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief USB protocol definitions.
*
* This file contains the USB definitions and data structures provided by the
* USB 2.0 specification.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _USB_PROTOCOL_H_
#define _USB_PROTOCOL_H_
#include "usb_atmel.h"
/**
* \ingroup usb_group
* \defgroup usb_protocol_group USB Protocol Definitions
*
* This module defines constants and data structures provided by the USB
* 2.0 specification.
*
* @{
*/
//! Value for field bcdUSB
#define USB_V2_0 0x0200 //!< USB Specification version 2.00
/*! \name Generic definitions (Class, subclass and protocol)
*/
//! @{
#define NO_CLASS 0x00
#define CLASS_VENDOR_SPECIFIC 0xFF
#define NO_SUBCLASS 0x00
#define NO_PROTOCOL 0x00
//! @}
//! \name IAD (Interface Association Descriptor) constants
//! @{
#define CLASS_IAD 0xEF
#define SUB_CLASS_IAD 0x02
#define PROTOCOL_IAD 0x01
//! @}
/**
* \brief USB request data transfer direction (bmRequestType)
*/
#define USB_REQ_DIR_OUT (0<<7) //!< Host to device
#define USB_REQ_DIR_IN (1<<7) //!< Device to host
#define USB_REQ_DIR_MASK (1<<7) //!< Mask
/**
* \brief USB request types (bmRequestType)
*/
#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request
#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request
#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request
#define USB_REQ_TYPE_MASK (3<<5) //!< Mask
/**
* \brief USB recipient codes (bmRequestType)
*/
#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device
#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface
#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint
#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other
#define USB_REQ_RECIP_MASK (0x1F) //!< Mask
/**
* \brief Standard USB requests (bRequest)
*/
enum usb_reqid {
USB_REQ_GET_STATUS = 0,
USB_REQ_CLEAR_FEATURE = 1,
USB_REQ_SET_FEATURE = 3,
USB_REQ_SET_ADDRESS = 5,
USB_REQ_GET_DESCRIPTOR = 6,
USB_REQ_SET_DESCRIPTOR = 7,
USB_REQ_GET_CONFIGURATION = 8,
USB_REQ_SET_CONFIGURATION = 9,
USB_REQ_GET_INTERFACE = 10,
USB_REQ_SET_INTERFACE = 11,
USB_REQ_SYNCH_FRAME = 12,
};
/**
* \brief Standard USB device status flags
*
*/
enum usb_device_status {
USB_DEV_STATUS_BUS_POWERED = 0,
USB_DEV_STATUS_SELF_POWERED = 1,
USB_DEV_STATUS_REMOTEWAKEUP = 2
};
/**
* \brief Standard USB Interface status flags
*
*/
enum usb_interface_status {
USB_IFACE_STATUS_RESERVED = 0
};
/**
* \brief Standard USB endpoint status flags
*
*/
enum usb_endpoint_status {
USB_EP_STATUS_HALTED = 1,
};
/**
* \brief Standard USB device feature flags
*
* \note valid for SetFeature request.
*/
enum usb_device_feature {
USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled
USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode
USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3,
USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4,
USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5
};
/**
* \brief Test Mode possible on HS USB device
*
* \note valid for USB_DEV_FEATURE_TEST_MODE request.
*/
enum usb_device_hs_test_mode {
USB_DEV_TEST_MODE_J = 1,
USB_DEV_TEST_MODE_K = 2,
USB_DEV_TEST_MODE_SE0_NAK = 3,
USB_DEV_TEST_MODE_PACKET = 4,
USB_DEV_TEST_MODE_FORCE_ENABLE = 5,
};
/**
* \brief Standard USB endpoint feature/status flags
*/
enum usb_endpoint_feature {
USB_EP_FEATURE_HALT = 0,
};
/**
* \brief Standard USB Test Mode Selectors
*/
enum usb_test_mode_selector {
USB_TEST_J = 0x01,
USB_TEST_K = 0x02,
USB_TEST_SE0_NAK = 0x03,
USB_TEST_PACKET = 0x04,
USB_TEST_FORCE_ENABLE = 0x05,
};
/**
* \brief Standard USB descriptor types
*/
enum usb_descriptor_type {
USB_DT_DEVICE = 1,
USB_DT_CONFIGURATION = 2,
USB_DT_STRING = 3,
USB_DT_INTERFACE = 4,
USB_DT_ENDPOINT = 5,
USB_DT_DEVICE_QUALIFIER = 6,
USB_DT_OTHER_SPEED_CONFIGURATION = 7,
USB_DT_INTERFACE_POWER = 8,
USB_DT_OTG = 9,
USB_DT_IAD = 0x0B,
};
/**
* \brief Standard USB endpoint transfer types
*/
enum usb_ep_type {
USB_EP_TYPE_CONTROL = 0x00,
USB_EP_TYPE_ISOCHRONOUS = 0x01,
USB_EP_TYPE_BULK = 0x02,
USB_EP_TYPE_INTERRUPT = 0x03,
USB_EP_TYPE_MASK = 0x03,
};
/**
* \brief Standard USB language IDs for string descriptors
*/
enum usb_langid {
USB_LANGID_EN_US = 0x0409, //!< English (United States)
};
/**
* \brief Mask selecting the index part of an endpoint address
*/
#define USB_EP_ADDR_MASK 0x0f
//! \brief USB address identifier
typedef uint8_t usb_add_t;
/**
* \brief Endpoint transfer direction is IN
*/
#define USB_EP_DIR_IN 0x80
/**
* \brief Endpoint transfer direction is OUT
*/
#define USB_EP_DIR_OUT 0x00
//! \brief Endpoint identifier
typedef uint8_t usb_ep_t;
/**
* \brief Maximum length in bytes of a USB descriptor
*
* The maximum length of a USB descriptor is limited by the 8-bit
* bLength field.
*/
#define USB_MAX_DESC_LEN 255
/*
* 2-byte alignment requested for all USB structures.
*/
COMPILER_PACK_SET(1)
/**
* \brief A USB Device SETUP request
*
* The data payload of SETUP packets always follows this structure.
*/
typedef struct {
uint8_t bmRequestType;
uint8_t bRequest;
le16_t wValue;
le16_t wIndex;
le16_t wLength;
} usb_setup_req_t;
/**
* \brief Standard USB device descriptor structure
*/
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
le16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
le16_t idVendor;
le16_t idProduct;
le16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} usb_dev_desc_t;
/**
* \brief Standard USB device qualifier descriptor structure
*
* This descriptor contains information about the device when running at
* the "other" speed (i.e. if the device is currently operating at high
* speed, this descriptor can be used to determine what would change if
* the device was operating at full speed.)
*/
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
le16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint8_t bNumConfigurations;
uint8_t bReserved;
} usb_dev_qual_desc_t;
/**
* \brief Standard USB Interface Association Descriptor structure
*/
typedef struct {
uint8_t bLength; //!< size of this descriptor in bytes
uint8_t bDescriptorType; //!< INTERFACE descriptor type
uint8_t bFirstInterface; //!< Number of interface
uint8_t bInterfaceCount; //!< value to select alternate setting
uint8_t bFunctionClass; //!< Class code assigned by the USB
uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB
uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB
uint8_t iFunction; //!< Index of string descriptor
} usb_association_desc_t;
/**
* \brief Standard USB configuration descriptor structure
*/
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
le16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} usb_conf_desc_t;
#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set
#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered
#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered
#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported
#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA
/**
* \brief Standard USB association descriptor structure
*/
typedef struct {
uint8_t bLength; //!< Size of this descriptor in bytes
uint8_t bDescriptorType; //!< Interface descriptor type
uint8_t bFirstInterface; //!< Number of interface
uint8_t bInterfaceCount; //!< value to select alternate setting
uint8_t bFunctionClass; //!< Class code assigned by the USB
uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB
uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB
uint8_t iFunction; //!< Index of string descriptor
} usb_iad_desc_t;
/**
* \brief Standard USB interface descriptor structure
*/
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} usb_iface_desc_t;
/**
* \brief Standard USB endpoint descriptor structure
*/
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
le16_t wMaxPacketSize;
uint8_t bInterval;
} usb_ep_desc_t;
/**
* \brief A standard USB string descriptor structure
*/
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
} usb_str_desc_t;
typedef struct {
usb_str_desc_t desc;
le16_t string[1];
} usb_str_lgid_desc_t;
COMPILER_PACK_RESET()
//! @}
#endif /* _USB_PROTOCOL_H_ */
dstat-firmware-master/src/asf/common/utils/ 0000775 0000000 0000000 00000000000 13317465730 0021301 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/utils/interrupt.h 0000664 0000000 0000000 00000007443 13317465730 0023516 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Global interrupt management for 8- and 32-bit AVR
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef UTILS_INTERRUPT_H
#define UTILS_INTERRUPT_H
#include
#if XMEGA || MEGA || TINY
# include "interrupt/interrupt_avr8.h"
#elif UC3
# include "interrupt/interrupt_avr32.h"
#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E
# include "interrupt/interrupt_sam_nvic.h"
#else
# error Unsupported device.
#endif
/**
* \defgroup interrupt_group Global interrupt management
*
* This is a driver for global enabling and disabling of interrupts.
*
* @{
*/
#if defined(__DOXYGEN__)
/**
* \def CONFIG_INTERRUPT_FORCE_INTC
* \brief Force usage of the ASF INTC driver
*
* Predefine this symbol when preprocessing to force the use of the ASF INTC driver.
* This is useful to ensure compatibilty accross compilers and shall be used only when required
* by the application needs.
*/
# define CONFIG_INTERRUPT_FORCE_INTC
#endif
//! \name Global interrupt flags
//@{
/**
* \typedef irqflags_t
* \brief Type used for holding state of interrupt flag
*/
/**
* \def cpu_irq_enable
* \brief Enable interrupts globally
*/
/**
* \def cpu_irq_disable
* \brief Disable interrupts globally
*/
/**
* \fn irqflags_t cpu_irq_save(void)
* \brief Get and clear the global interrupt flags
*
* Use in conjunction with \ref cpu_irq_restore.
*
* \return Current state of interrupt flags.
*
* \note This function leaves interrupts disabled.
*/
/**
* \fn void cpu_irq_restore(irqflags_t flags)
* \brief Restore global interrupt flags
*
* Use in conjunction with \ref cpu_irq_save.
*
* \param flags State to set interrupt flag to.
*/
/**
* \fn bool cpu_irq_is_enabled_flags(irqflags_t flags)
* \brief Check if interrupts are globally enabled in supplied flags
*
* \param flags Currents state of interrupt flags.
*
* \return True if interrupts are enabled.
*/
/**
* \def cpu_irq_is_enabled
* \brief Check if interrupts are globally enabled
*
* \return True if interrupts are enabled.
*/
//@}
//! @}
/**
* \ingroup interrupt_group
* \defgroup interrupt_deprecated_group Deprecated interrupt definitions
*/
#endif /* UTILS_INTERRUPT_H */
dstat-firmware-master/src/asf/common/utils/interrupt/ 0000775 0000000 0000000 00000000000 13317465730 0023335 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/utils/interrupt/interrupt_avr8.h 0000664 0000000 0000000 00000007333 13317465730 0026510 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Global interrupt management for 8-bit AVR
*
* Copyright (C) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef UTILS_INTERRUPT_INTERRUPT_H
#define UTILS_INTERRUPT_INTERRUPT_H
#include
#include
/**
* \weakgroup interrupt_group
*
* @{
*/
#ifdef ISR_CUSTOM_H
# include ISR_CUSTOM_H
#else
/**
* \def ISR
* \brief Define service routine for specified interrupt vector
*
* Usage:
* \code
* ISR(FOO_vect)
* {
* ...
* }
* \endcode
*
* \param vect Interrupt vector name as found in the device header files.
*/
#if defined(__DOXYGEN__)
# define ISR(vect)
#elif defined(__GNUC__)
# include
#elif defined(__ICCAVR__)
# define __ISR(x) _Pragma(#x)
# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void)
#endif
#endif // ISR_CUSTOM_H
#if XMEGA
/**
* \brief Initialize interrupt vectors
* Enables all interrupt levels, with vectors located in the application section
* and fixed priority scheduling.
*/
#define irq_initialize_vectors() \
PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
#endif
#ifdef __GNUC__
# define cpu_irq_enable() sei()
# define cpu_irq_disable() cli()
#else
# define cpu_irq_enable() __enable_interrupt()
# define cpu_irq_disable() __disable_interrupt()
#endif
typedef uint8_t irqflags_t;
static inline irqflags_t cpu_irq_save(void)
{
irqflags_t flags = SREG;
cpu_irq_disable();
return flags;
}
static inline void cpu_irq_restore(irqflags_t flags)
{
barrier();
SREG = flags;
}
static inline bool cpu_irq_is_enabled_flags(irqflags_t flags)
{
#if XMEGA
# ifdef __GNUC__
return flags & CPU_I_bm;
# else
return flags & I_bm;
# endif
#elif MEGA || TINY
return flags & (1 << SREG_I);
#endif
}
#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG)
//! @}
/**
* \weakgroup interrupt_deprecated_group
* @{
*/
// Deprecated definitions.
#define Enable_global_interrupt() cpu_irq_enable()
#define Disable_global_interrupt() cpu_irq_disable()
#define Is_global_interrupt_enabled() cpu_irq_is_enabled()
//! @}
#endif /* UTILS_INTERRUPT_INTERRUPT_H */
dstat-firmware-master/src/asf/common/utils/make/ 0000775 0000000 0000000 00000000000 13317465730 0022216 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/utils/make/Makefile.avr.in 0000664 0000000 0000000 00000034067 13317465730 0025064 0 ustar 00root root 0000000 0000000 # List of available make goals:
#
# all Default target, builds the project
# clean Clean up the project
# rebuild Rebuild the project
#
# doc Build the documentation
# cleandoc Clean up the documentation
# rebuilddoc Rebuild the documentation
#
#
# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
#
# \asf_license_start
#
# \page License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. The name of Atmel may not be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# 4. This software may only be redistributed and used in connection with an
# Atmel microcontroller product.
#
# THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
# EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# \asf_license_stop
#
# Include the config.mk file from the current working path, e.g., where the
# user called make.
include config.mk
# Tool to use to generate documentation from the source code
DOCGEN ?= doxygen
# Look for source files relative to the top-level source directory
VPATH := $(PRJ_PATH)
# Output target file
target := $(TARGET)
# Output project name (target name minus suffix)
project := $(basename $(target))
# Output target file (typically ELF or static library)
ifeq ($(suffix $(target)),.a)
target_type := lib
else
ifeq ($(suffix $(target)),.elf)
target_type := elf
else
$(error "Target type $(target_type) is not supported")
endif
endif
# Allow override of operating system detection. The user can add OS=Linux or
# OS=Windows on the command line to explicit set the host OS.
#
# This allows to work around broken uname utility on certain systems.
ifdef OS
ifeq ($(strip $(OS)), Linux)
os_type := Linux
endif
ifeq ($(strip $(OS)), Windows)
os_type := windows32_64
endif
endif
os_type ?= $(strip $(shell uname))
ifeq ($(os_type),windows32)
os := Windows
else
ifeq ($(os_type),windows64)
os := Windows
else
ifeq ($(os_type),windows32_64)
os ?= Windows
else
ifeq ($(os_type),)
os := Windows
else
# Default to Linux style operating system. Both Cygwin and mingw are fully
# compatible (for this Makefile) with Linux.
os := Linux
endif
endif
endif
endif
# Output documentation directory and configuration file.
docdir := ../doxygen/html
doccfg := ../doxygen/doxyfile.doxygen
CROSS ?= avr-
AR := $(CROSS)ar
AS := $(CROSS)as
CC := $(CROSS)gcc
CPP := $(CROSS)gcc -E
CXX := $(CROSS)g++
LD := $(CROSS)g++
NM := $(CROSS)nm
OBJCOPY := $(CROSS)objcopy
OBJDUMP := $(CROSS)objdump
SIZE := $(CROSS)size
RM := rm
ifeq ($(os),Windows)
RMDIR := rmdir /S /Q
else
RMDIR := rmdir -p --ignore-fail-on-non-empty
endif
# Strings for beautifying output
MSG_CLEAN_FILES = "RM *.o *.d"
MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))"
MSG_CLEAN_DOC = "RMDIR $(docdir)"
MSG_MKDIR = "MKDIR $(dir $@)"
MSG_INFO = "INFO "
MSG_ARCHIVING = "AR $@"
MSG_ASSEMBLING = "AS $@"
MSG_BINARY_IMAGE = "OBJCOPY $@"
MSG_COMPILING = "CC $@"
MSG_COMPILING_CXX = "CXX $@"
MSG_EEPROM_IMAGE = "OBJCOPY $@"
MSG_EXTENDED_LISTING = "OBJDUMP $@"
MSG_IHEX_IMAGE = "OBJCOPY $@"
MSG_LINKING = "LN $@"
MSG_PREPROCESSING = "CPP $@"
MSG_SIZE = "SIZE $@"
MSG_SYMBOL_TABLE = "NM $@"
MSG_GENERATING_DOC = "DOXYGEN $(docdir)"
# Don't use make's built-in rules and variables
MAKEFLAGS += -rR
# Don't print 'Entering directory ...'
MAKEFLAGS += --no-print-directory
# Function for reversing the order of a list
reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
# Hide command output by default, but allow the user to override this
# by adding V=1 on the command line.
#
# This is inspired by the Kbuild system used by the Linux kernel.
ifdef V
ifeq ("$(origin V)", "command line")
VERBOSE = $(V)
endif
endif
ifndef VERBOSE
VERBOSE = 0
endif
ifeq ($(VERBOSE), 1)
Q =
else
Q = @
endif
arflags-gnu-y := $(ARFLAGS)
asflags-gnu-y := $(ASFLAGS)
cflags-gnu-y := $(CFLAGS)
cxxflags-gnu-y := $(CXXFLAGS)
cppflags-gnu-y := $(CPPFLAGS)
cpuflags-gnu-y :=
dbgflags-gnu-y := $(DBGFLAGS)
libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB))
ldflags-gnu-y := $(LDFLAGS)
flashflags-gnu-y := $(FLASHFLAGS)
eepromflags-gnu-y := $(EEPROMFLAGS)
clean-files :=
clean-dirs :=
clean-files += $(wildcard $(target) $(project).map)
clean-files += $(wildcard $(project).hex $(project).eep)
clean-files += $(wildcard $(project).lss $(project).sym)
clean-files += $(wildcard $(build))
# Use pipes instead of temporary files for communication between processes
cflags-gnu-y += -pipe
asflags-gnu-y += -pipe
ldflags-gnu-y += -pipe
# Archiver flags.
arflags-gnu-y += rcs
# Always enable warnings. And be very careful about implicit
# declarations.
cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes
cflags-gnu-y += -Werror-implicit-function-declaration
cxxflags-gnu-y += -Wall
# IAR doesn't allow arithmetic on void pointers, so warn about that.
cflags-gnu-y += -Wpointer-arith
cxxflags-gnu-y += -Wpointer-arith
# Preprocessor flags.
cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC))
asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)')
# CPU specific flags.
cpuflags-gnu-y += -mmcu=$(MCU)
# Dependency file flags.
depflags = -MD -MP -MQ $@
# Debug specific flags.
ifdef BUILD_DEBUG_LEVEL
dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL)
else
dbgflags-gnu-y += -gdwarf-2
endif
# Optimization specific flags.
ifdef BUILD_OPTIMIZATION
optflags-gnu-y = -O$(BUILD_OPTIMIZATION)
else
optflags-gnu-y = $(OPTIMIZATION)
endif
# Relax compilation and linking.
cflags-gnu-y += -mrelax
cxxflags-gnu-y += -mrelax
asflags-gnu-y += -mrelax
ldflags-gnu-y += -Wl,--relax
# Always preprocess assembler files.
asflags-gnu-y += -x assembler-with-cpp
# Compile C files using the GNU99 standard.
cflags-gnu-y += -std=gnu99
# Compile C++ files using the GNU++98 standard.
cxxflags-gnu-y += -std=gnu++98
# Use unsigned character type when compiling.
cflags-gnu-y += -funsigned-char
cxxflags-gnu-y += -funsigned-char
# Don't use strict aliasing (very common in embedded applications).
cflags-gnu-y += -fno-strict-aliasing
cxxflags-gnu-y += -fno-strict-aliasing
# Separate each function and data into its own separate section to allow
# garbage collection of unused sections.
cflags-gnu-y += -ffunction-sections -fdata-sections
cxxflags-gnu-y += -ffunction-sections -fdata-sections
# Garbage collect unreferred sections when linking.
ldflags-gnu-y += -Wl,--gc-sections
# Output a link map file and a cross reference table
ldflags-gnu-y += -Wl,-Map=$(project).map,--cref
# Add library search paths relative to the top level directory.
ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH))
a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__
c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y)
cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y)
l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y)
ar_flags = $(arflags-gnu-y)
# Intel Hex file production flags
flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table
# Eeprom file production flags
eepromflags-gnu-y += -j .eeprom
eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load"
eepromflags-gnu-y += --change-section-lma .eeprom=0
# Source files list and part informations must already be included before
# running this makefile
# If a custom build directory is specified, use it -- force trailing / in directory name.
ifdef BUILD_DIR
build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/)
else
build-dir =
endif
# Create object files list from source files list.
obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS))))
# Create dependency files list from source files list.
dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d))
clean-files += $(wildcard $(obj-y))
clean-files += $(dep-files)
clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y)))))
# Default target.
.PHONY: all
ifeq ($(target_type),lib)
all: $(target) $(project).lss $(project).sym
else
ifeq ($(target_type),elf)
all: $(target) $(project).hex $(project).lss $(project).sym
endif
endif
# Clean up the project.
.PHONY: clean
clean:
@$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES))
$(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),)
@$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS))
# Remove created directories, and make sure we only remove existing
# directories, since recursive rmdir might help us a bit on the way.
ifeq ($(os),Windows)
$(Q)$(if $(strip $(clean-dirs)), \
$(RMDIR) $(strip $(subst /,\,$(clean-dirs))))
else
$(Q)$(if $(strip $(clean-dirs)), \
for directory in $(strip $(clean-dirs)); do \
if [ -d "$$directory" ]; then \
$(RMDIR) $$directory; \
fi \
done \
)
endif
# Rebuild the project.
.PHONY: rebuild
rebuild: clean all
.PHONY: objfiles
objfiles: $(obj-y)
# Create object files from C source files.
$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
else
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
endif
@echo $(MSG_COMPILING)
$(Q)$(CC) $(c_flags) -c $< -o $@
# Create object files from C++ source files.
$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
else
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
endif
@echo $(MSG_COMPILING_CXX)
$(Q)$(CXX) $(cxx_flags) -c $< -o $@
# Preprocess and assemble: create object files from assembler source files.
$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
else
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
endif
@echo $(MSG_ASSEMBLING)
$(Q)$(CC) $(a_flags) -c $< -o $@
# Preprocess and assemble: create object files from assembler source files.
$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
else
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
endif
@echo $(MSG_ASSEMBLING)
$(Q)$(CC) $(a_flags) -c $< -o $@
# Include all dependency files to add depedency to all header files in use.
include $(dep-files)
ifeq ($(target_type),lib)
# Archive object files into an archive
$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
@echo $(MSG_ARCHIVING)
$(Q)$(AR) $(ar_flags) $@ $(obj-y)
@echo $(MSG_SIZE)
$(Q)$(SIZE) -Bxt $@
else
ifeq ($(target_type),elf)
# Link the object files into an ELF file. Also make sure the target is rebuilt
# if the common Makefile.avr.in or project config.mk is changed.
$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
@echo $(MSG_LINKING)
$(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@
@echo $(MSG_SIZE)
$(Q)$(SIZE) -Ax $@
$(Q)$(SIZE) -Bx $@
endif
endif
# Create extended function listing from target output file.
%.lss: $(target)
@echo $(MSG_EXTENDED_LISTING)
$(Q)$(OBJDUMP) -h -S $< > $@
# Create symbol table from target output file.
%.sym: $(target)
@echo $(MSG_SYMBOL_TABLE)
$(Q)$(NM) -n $< > $@
# Create Intel HEX image from ELF output file.
%.hex: $(target)
@echo $(MSG_IHEX_IMAGE)
$(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@
# Create EEPROM Intel HEX image from ELF output file.
%.eep: $(target)
@echo $(MSG_EEPROM_IMAGE)
$(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0
# Provide information about the detected host operating system.
.SECONDARY: info-os
info-os:
@echo $(MSG_INFO)$(os) build host detected
# Build Doxygen generated documentation.
.PHONY: doc
doc:
@echo $(MSG_GENERATING_DOC)
$(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg))
# Clean Doxygen generated documentation.
.PHONY: cleandoc
cleandoc:
@$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC))
$(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir))
# Rebuild the Doxygen generated documentation.
.PHONY: rebuilddoc
rebuilddoc: cleandoc doc
dstat-firmware-master/src/asf/common/utils/parts.h 0000664 0000000 0000000 00000052433 13317465730 0022612 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Atmel part identification macros
*
* Copyright (C) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef ATMEL_PARTS_H
#define ATMEL_PARTS_H
/**
* \defgroup part_macros_group Atmel part identification macros
*
* This collection of macros identify which series and families that the various
* Atmel parts belong to. These can be used to select part-dependent sections of
* code at compile time.
*
* @{
*/
/**
* \name Convenience macros for part checking
* @{
*/
/* ! Check GCC and IAR part definition for 8-bit AVR */
#define AVR8_PART_IS_DEFINED(part) \
(defined(__ ## part ## __) || defined(__AVR_ ## part ## __))
/* ! Check GCC and IAR part definition for 32-bit AVR */
#define AVR32_PART_IS_DEFINED(part) \
(defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __))
/* ! Check GCC and IAR part definition for SAM */
#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __))
/** @} */
/**
* \defgroup uc3_part_macros_group AVR UC3 parts
* @{
*/
/**
* \name AVR UC3 A series
* @{
*/
#define UC3A0 ( \
AVR32_PART_IS_DEFINED(UC3A0128) || \
AVR32_PART_IS_DEFINED(UC3A0256) || \
AVR32_PART_IS_DEFINED(UC3A0512) \
)
#define UC3A1 ( \
AVR32_PART_IS_DEFINED(UC3A1128) || \
AVR32_PART_IS_DEFINED(UC3A1256) || \
AVR32_PART_IS_DEFINED(UC3A1512) \
)
#define UC3A3 ( \
AVR32_PART_IS_DEFINED(UC3A364) || \
AVR32_PART_IS_DEFINED(UC3A364S) || \
AVR32_PART_IS_DEFINED(UC3A3128) || \
AVR32_PART_IS_DEFINED(UC3A3128S) || \
AVR32_PART_IS_DEFINED(UC3A3256) || \
AVR32_PART_IS_DEFINED(UC3A3256S) \
)
#define UC3A4 ( \
AVR32_PART_IS_DEFINED(UC3A464) || \
AVR32_PART_IS_DEFINED(UC3A464S) || \
AVR32_PART_IS_DEFINED(UC3A4128) || \
AVR32_PART_IS_DEFINED(UC3A4128S) || \
AVR32_PART_IS_DEFINED(UC3A4256) || \
AVR32_PART_IS_DEFINED(UC3A4256S) \
)
/** @} */
/**
* \name AVR UC3 B series
* @{
*/
#define UC3B0 ( \
AVR32_PART_IS_DEFINED(UC3B064) || \
AVR32_PART_IS_DEFINED(UC3B0128) || \
AVR32_PART_IS_DEFINED(UC3B0256) || \
AVR32_PART_IS_DEFINED(UC3B0512) \
)
#define UC3B1 ( \
AVR32_PART_IS_DEFINED(UC3B164) || \
AVR32_PART_IS_DEFINED(UC3B1128) || \
AVR32_PART_IS_DEFINED(UC3B1256) || \
AVR32_PART_IS_DEFINED(UC3B1512) \
)
/** @} */
/**
* \name AVR UC3 C series
* @{
*/
#define UC3C0 ( \
AVR32_PART_IS_DEFINED(UC3C064C) || \
AVR32_PART_IS_DEFINED(UC3C0128C) || \
AVR32_PART_IS_DEFINED(UC3C0256C) || \
AVR32_PART_IS_DEFINED(UC3C0512C) \
)
#define UC3C1 ( \
AVR32_PART_IS_DEFINED(UC3C164C) || \
AVR32_PART_IS_DEFINED(UC3C1128C) || \
AVR32_PART_IS_DEFINED(UC3C1256C) || \
AVR32_PART_IS_DEFINED(UC3C1512C) \
)
#define UC3C2 ( \
AVR32_PART_IS_DEFINED(UC3C264C) || \
AVR32_PART_IS_DEFINED(UC3C2128C) || \
AVR32_PART_IS_DEFINED(UC3C2256C) || \
AVR32_PART_IS_DEFINED(UC3C2512C) \
)
/** @} */
/**
* \name AVR UC3 D series
* @{
*/
#define UC3D3 ( \
AVR32_PART_IS_DEFINED(UC64D3) || \
AVR32_PART_IS_DEFINED(UC128D3) \
)
#define UC3D4 ( \
AVR32_PART_IS_DEFINED(UC64D4) || \
AVR32_PART_IS_DEFINED(UC128D4) \
)
/** @} */
/**
* \name AVR UC3 L series
* @{
*/
#define UC3L0 ( \
AVR32_PART_IS_DEFINED(UC3L016) || \
AVR32_PART_IS_DEFINED(UC3L032) || \
AVR32_PART_IS_DEFINED(UC3L064) \
)
#define UC3L0128 ( \
AVR32_PART_IS_DEFINED(UC3L0128) \
)
#define UC3L0256 ( \
AVR32_PART_IS_DEFINED(UC3L0256) \
)
#define UC3L3 ( \
AVR32_PART_IS_DEFINED(UC64L3U) || \
AVR32_PART_IS_DEFINED(UC128L3U) || \
AVR32_PART_IS_DEFINED(UC256L3U) \
)
#define UC3L4 ( \
AVR32_PART_IS_DEFINED(UC64L4U) || \
AVR32_PART_IS_DEFINED(UC128L4U) || \
AVR32_PART_IS_DEFINED(UC256L4U) \
)
#define UC3L3_L4 (UC3L3 || UC3L4)
/** @} */
/**
* \name AVR UC3 families
* @{
*/
/** AVR UC3 A family */
#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4)
/** AVR UC3 B family */
#define UC3B (UC3B0 || UC3B1)
/** AVR UC3 C family */
#define UC3C (UC3C0 || UC3C1 || UC3C2)
/** AVR UC3 D family */
#define UC3D (UC3D3 || UC3D4)
/** AVR UC3 L family */
#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4)
/** @} */
/** AVR UC3 product line */
#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L)
/** @} */
/**
* \defgroup xmega_part_macros_group AVR XMEGA parts
* @{
*/
/**
* \name AVR XMEGA A series
* @{
*/
#define XMEGA_A1 ( \
AVR8_PART_IS_DEFINED(ATxmega64A1) || \
AVR8_PART_IS_DEFINED(ATxmega128A1) \
)
#define XMEGA_A3 ( \
AVR8_PART_IS_DEFINED(ATxmega64A3) || \
AVR8_PART_IS_DEFINED(ATxmega128A3) || \
AVR8_PART_IS_DEFINED(ATxmega192A3) || \
AVR8_PART_IS_DEFINED(ATxmega256A3) \
)
#define XMEGA_A3B ( \
AVR8_PART_IS_DEFINED(ATxmega256A3B) \
)
#define XMEGA_A4 ( \
AVR8_PART_IS_DEFINED(ATxmega16A4) || \
AVR8_PART_IS_DEFINED(ATxmega32A4) \
)
/** @} */
/**
* \name AVR XMEGA AU series
* @{
*/
#define XMEGA_A1U ( \
AVR8_PART_IS_DEFINED(ATxmega64A1U) || \
AVR8_PART_IS_DEFINED(ATxmega128A1U) \
)
#define XMEGA_A3U ( \
AVR8_PART_IS_DEFINED(ATxmega64A3U) || \
AVR8_PART_IS_DEFINED(ATxmega128A3U) || \
AVR8_PART_IS_DEFINED(ATxmega192A3U) || \
AVR8_PART_IS_DEFINED(ATxmega256A3U) \
)
#define XMEGA_A3BU ( \
AVR8_PART_IS_DEFINED(ATxmega256A3BU) \
)
#define XMEGA_A4U ( \
AVR8_PART_IS_DEFINED(ATxmega16A4U) || \
AVR8_PART_IS_DEFINED(ATxmega32A4U) || \
AVR8_PART_IS_DEFINED(ATxmega64A4U) || \
AVR8_PART_IS_DEFINED(ATxmega128A4U) \
)
/** @} */
/**
* \name AVR XMEGA B series
* @{
*/
#define XMEGA_B1 ( \
AVR8_PART_IS_DEFINED(ATxmega64B1) || \
AVR8_PART_IS_DEFINED(ATxmega128B1) \
)
#define XMEGA_B3 ( \
AVR8_PART_IS_DEFINED(ATxmega64B3) || \
AVR8_PART_IS_DEFINED(ATxmega128B3) \
)
/** @} */
/**
* \name AVR XMEGA C series
* @{
*/
#define XMEGA_C3 ( \
AVR8_PART_IS_DEFINED(ATxmega384C3) || \
AVR8_PART_IS_DEFINED(ATxmega256C3) || \
AVR8_PART_IS_DEFINED(ATxmega128C3) || \
AVR8_PART_IS_DEFINED(ATxmega64C3) \
)
#define XMEGA_C4 ( \
AVR8_PART_IS_DEFINED(ATxmega32C4) || \
AVR8_PART_IS_DEFINED(ATxmega16C4) \
)
/** @} */
/**
* \name AVR XMEGA D series
* @{
*/
#define XMEGA_D3 ( \
AVR8_PART_IS_DEFINED(ATxmega64D3) || \
AVR8_PART_IS_DEFINED(ATxmega128D3) || \
AVR8_PART_IS_DEFINED(ATxmega192D3) || \
AVR8_PART_IS_DEFINED(ATxmega256D3) || \
AVR8_PART_IS_DEFINED(ATxmega384D3) \
)
#define XMEGA_D4 ( \
AVR8_PART_IS_DEFINED(ATxmega16D4) || \
AVR8_PART_IS_DEFINED(ATxmega32D4) || \
AVR8_PART_IS_DEFINED(ATxmega64D4) || \
AVR8_PART_IS_DEFINED(ATxmega128D4) \
)
/** @} */
/**
* \name AVR XMEGA E series
* @{
*/
#define XMEGA_E5 ( \
AVR8_PART_IS_DEFINED(ATxmega8E5) || \
AVR8_PART_IS_DEFINED(ATxmega16E5) || \
AVR8_PART_IS_DEFINED(ATxmega32E5) \
)
/** @} */
/**
* \name AVR XMEGA families
* @{
*/
/** AVR XMEGA A family */
#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4)
/** AVR XMEGA AU family */
#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U)
/** AVR XMEGA B family */
#define XMEGA_B (XMEGA_B1 || XMEGA_B3)
/** AVR XMEGA C family */
#define XMEGA_C (XMEGA_C3 || XMEGA_C4)
/** AVR XMEGA D family */
#define XMEGA_D (XMEGA_D3 || XMEGA_D4)
/** AVR XMEGA E family */
#define XMEGA_E (XMEGA_E5)
/** @} */
/** AVR XMEGA product line */
#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E)
/** @} */
/**
* \defgroup mega_part_macros_group megaAVR parts
*
* \note These megaAVR groupings are based on the groups in AVR Libc for the
* part header files. They are not names of official megaAVR device series or
* families.
*
* @{
*/
/**
* \name ATmegaxx0/xx1 subgroups
* @{
*/
#define MEGA_XX0 ( \
AVR8_PART_IS_DEFINED(ATmega640) || \
AVR8_PART_IS_DEFINED(ATmega1280) || \
AVR8_PART_IS_DEFINED(ATmega2560) \
)
#define MEGA_XX1 ( \
AVR8_PART_IS_DEFINED(ATmega1281) || \
AVR8_PART_IS_DEFINED(ATmega2561) \
)
/** @} */
/**
* \name megaAVR groups
* @{
*/
/** ATmegaxx0/xx1 group */
#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1)
/** ATmegaxx4 group */
#define MEGA_XX4 ( \
AVR8_PART_IS_DEFINED(ATmega164A) || \
AVR8_PART_IS_DEFINED(ATmega164PA) || \
AVR8_PART_IS_DEFINED(ATmega324A) || \
AVR8_PART_IS_DEFINED(ATmega324PA) || \
AVR8_PART_IS_DEFINED(ATmega644) || \
AVR8_PART_IS_DEFINED(ATmega644A) || \
AVR8_PART_IS_DEFINED(ATmega644PA) || \
AVR8_PART_IS_DEFINED(ATmega1284P) || \
AVR8_PART_IS_DEFINED(ATmega128RFA1) \
)
/** ATmegaxx4 group */
#define MEGA_XX4_A ( \
AVR8_PART_IS_DEFINED(ATmega164A) || \
AVR8_PART_IS_DEFINED(ATmega164PA) || \
AVR8_PART_IS_DEFINED(ATmega324A) || \
AVR8_PART_IS_DEFINED(ATmega324PA) || \
AVR8_PART_IS_DEFINED(ATmega644A) || \
AVR8_PART_IS_DEFINED(ATmega644PA) || \
AVR8_PART_IS_DEFINED(ATmega1284P) \
)
/** ATmegaxx8 group */
#define MEGA_XX8 ( \
AVR8_PART_IS_DEFINED(ATmega48) || \
AVR8_PART_IS_DEFINED(ATmega48A) || \
AVR8_PART_IS_DEFINED(ATmega48PA) || \
AVR8_PART_IS_DEFINED(ATmega88) || \
AVR8_PART_IS_DEFINED(ATmega88A) || \
AVR8_PART_IS_DEFINED(ATmega88PA) || \
AVR8_PART_IS_DEFINED(ATmega168) || \
AVR8_PART_IS_DEFINED(ATmega168A) || \
AVR8_PART_IS_DEFINED(ATmega168PA) || \
AVR8_PART_IS_DEFINED(ATmega328) || \
AVR8_PART_IS_DEFINED(ATmega328P) \
)
/** ATmegaxx8A/P/PA group */
#define MEGA_XX8_A ( \
AVR8_PART_IS_DEFINED(ATmega48A) || \
AVR8_PART_IS_DEFINED(ATmega48PA) || \
AVR8_PART_IS_DEFINED(ATmega88A) || \
AVR8_PART_IS_DEFINED(ATmega88PA) || \
AVR8_PART_IS_DEFINED(ATmega168A) || \
AVR8_PART_IS_DEFINED(ATmega168PA) || \
AVR8_PART_IS_DEFINED(ATmega328P) \
)
/** ATmegaxx group */
#define MEGA_XX ( \
AVR8_PART_IS_DEFINED(ATmega16) || \
AVR8_PART_IS_DEFINED(ATmega16A) || \
AVR8_PART_IS_DEFINED(ATmega32) || \
AVR8_PART_IS_DEFINED(ATmega32A) || \
AVR8_PART_IS_DEFINED(ATmega64) || \
AVR8_PART_IS_DEFINED(ATmega64A) || \
AVR8_PART_IS_DEFINED(ATmega128) || \
AVR8_PART_IS_DEFINED(ATmega128A) \
)
/** ATmegaxxA/P/PA group */
#define MEGA_XX_A ( \
AVR8_PART_IS_DEFINED(ATmega16A) || \
AVR8_PART_IS_DEFINED(ATmega32A) || \
AVR8_PART_IS_DEFINED(ATmega64A) || \
AVR8_PART_IS_DEFINED(ATmega128A) \
)
/** ATmegaxxRF group */
#define MEGA_RF ( \
AVR8_PART_IS_DEFINED(ATmega128RFA1) \
)
/**
* \name ATmegaxx_un0/un1/un2 subgroups
* @{
*/
#define MEGA_XX_UN0 ( \
AVR8_PART_IS_DEFINED(ATmega16) || \
AVR8_PART_IS_DEFINED(ATmega16A) || \
AVR8_PART_IS_DEFINED(ATmega32) || \
AVR8_PART_IS_DEFINED(ATmega32A) \
)
/** ATmegaxx group without power reduction and
* And interrupt sense register.
*/
#define MEGA_XX_UN1 ( \
AVR8_PART_IS_DEFINED(ATmega64) || \
AVR8_PART_IS_DEFINED(ATmega64A) || \
AVR8_PART_IS_DEFINED(ATmega128) || \
AVR8_PART_IS_DEFINED(ATmega128A) \
)
/** ATmegaxx group without power reduction and
* And interrupt sense register.
*/
#define MEGA_XX_UN2 ( \
AVR8_PART_IS_DEFINED(ATmega169P) || \
AVR8_PART_IS_DEFINED(ATmega169PA) || \
AVR8_PART_IS_DEFINED(ATmega329P) || \
AVR8_PART_IS_DEFINED(ATmega329PA) \
)
/** Devices added to complete megaAVR offering.
* Please do not use this group symbol as it is not intended
* to be permanent: the devices should be regrouped.
*/
#define MEGA_UNCATEGORIZED ( \
AVR8_PART_IS_DEFINED(AT90CAN128) || \
AVR8_PART_IS_DEFINED(AT90CAN32) || \
AVR8_PART_IS_DEFINED(AT90CAN64) || \
AVR8_PART_IS_DEFINED(AT90PWM1) || \
AVR8_PART_IS_DEFINED(AT90PWM216) || \
AVR8_PART_IS_DEFINED(AT90PWM2B) || \
AVR8_PART_IS_DEFINED(AT90PWM316) || \
AVR8_PART_IS_DEFINED(AT90PWM3B) || \
AVR8_PART_IS_DEFINED(AT90PWM81) || \
AVR8_PART_IS_DEFINED(AT90USB1286) || \
AVR8_PART_IS_DEFINED(AT90USB1287) || \
AVR8_PART_IS_DEFINED(AT90USB162) || \
AVR8_PART_IS_DEFINED(AT90USB646) || \
AVR8_PART_IS_DEFINED(AT90USB647) || \
AVR8_PART_IS_DEFINED(AT90USB82) || \
AVR8_PART_IS_DEFINED(ATmega1284) || \
AVR8_PART_IS_DEFINED(ATmega162) || \
AVR8_PART_IS_DEFINED(ATmega164P) || \
AVR8_PART_IS_DEFINED(ATmega165A) || \
AVR8_PART_IS_DEFINED(ATmega165P) || \
AVR8_PART_IS_DEFINED(ATmega165PA) || \
AVR8_PART_IS_DEFINED(ATmega168P) || \
AVR8_PART_IS_DEFINED(ATmega169A) || \
AVR8_PART_IS_DEFINED(ATmega16M1) || \
AVR8_PART_IS_DEFINED(ATmega16U2) || \
AVR8_PART_IS_DEFINED(ATmega16U4) || \
AVR8_PART_IS_DEFINED(ATmega2564RFR2) || \
AVR8_PART_IS_DEFINED(ATmega256RFA2) || \
AVR8_PART_IS_DEFINED(ATmega256RFR2) || \
AVR8_PART_IS_DEFINED(ATmega324P) || \
AVR8_PART_IS_DEFINED(ATmega325) || \
AVR8_PART_IS_DEFINED(ATmega3250) || \
AVR8_PART_IS_DEFINED(ATmega3250A) || \
AVR8_PART_IS_DEFINED(ATmega3250P) || \
AVR8_PART_IS_DEFINED(ATmega3250PA) || \
AVR8_PART_IS_DEFINED(ATmega325A) || \
AVR8_PART_IS_DEFINED(ATmega325P) || \
AVR8_PART_IS_DEFINED(ATmega325PA) || \
AVR8_PART_IS_DEFINED(ATmega329) || \
AVR8_PART_IS_DEFINED(ATmega3290) || \
AVR8_PART_IS_DEFINED(ATmega3290A) || \
AVR8_PART_IS_DEFINED(ATmega3290P) || \
AVR8_PART_IS_DEFINED(ATmega3290PA) || \
AVR8_PART_IS_DEFINED(ATmega329A) || \
AVR8_PART_IS_DEFINED(ATmega32M1) || \
AVR8_PART_IS_DEFINED(ATmega32U2) || \
AVR8_PART_IS_DEFINED(ATmega32U4) || \
AVR8_PART_IS_DEFINED(ATmega48P) || \
AVR8_PART_IS_DEFINED(ATmega644P) || \
AVR8_PART_IS_DEFINED(ATmega645) || \
AVR8_PART_IS_DEFINED(ATmega6450) || \
AVR8_PART_IS_DEFINED(ATmega6450A) || \
AVR8_PART_IS_DEFINED(ATmega6450P) || \
AVR8_PART_IS_DEFINED(ATmega645A) || \
AVR8_PART_IS_DEFINED(ATmega645P) || \
AVR8_PART_IS_DEFINED(ATmega649) || \
AVR8_PART_IS_DEFINED(ATmega6490) || \
AVR8_PART_IS_DEFINED(ATmega6490A) || \
AVR8_PART_IS_DEFINED(ATmega6490P) || \
AVR8_PART_IS_DEFINED(ATmega649A) || \
AVR8_PART_IS_DEFINED(ATmega649P) || \
AVR8_PART_IS_DEFINED(ATmega64M1) || \
AVR8_PART_IS_DEFINED(ATmega64RFA2) || \
AVR8_PART_IS_DEFINED(ATmega64RFR2) || \
AVR8_PART_IS_DEFINED(ATmega8) || \
AVR8_PART_IS_DEFINED(ATmega8515) || \
AVR8_PART_IS_DEFINED(ATmega8535) || \
AVR8_PART_IS_DEFINED(ATmega88P) || \
AVR8_PART_IS_DEFINED(ATmega8A) || \
AVR8_PART_IS_DEFINED(ATmega8U2) \
)
/** Unspecified group */
#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \
MEGA_UNCATEGORIZED)
/** @} */
/** megaAVR product line */
#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \
MEGA_UNSPECIFIED)
/** @} */
/** @} */
/**
* \defgroup tiny_part_macros_group tinyAVR parts
*
* @{
*/
/**
* \name tinyAVR groups
* @{
*/
/** Devices added to complete tinyAVR offering.
* Please do not use this group symbol as it is not intended
* to be permanent: the devices should be regrouped.
*/
#define TINY_UNCATEGORIZED ( \
AVR8_PART_IS_DEFINED(ATtiny10) || \
AVR8_PART_IS_DEFINED(ATtiny13) || \
AVR8_PART_IS_DEFINED(ATtiny13A) || \
AVR8_PART_IS_DEFINED(ATtiny1634) || \
AVR8_PART_IS_DEFINED(ATtiny167) || \
AVR8_PART_IS_DEFINED(ATtiny20) || \
AVR8_PART_IS_DEFINED(ATtiny2313) || \
AVR8_PART_IS_DEFINED(ATtiny2313A) || \
AVR8_PART_IS_DEFINED(ATtiny24) || \
AVR8_PART_IS_DEFINED(ATtiny24A) || \
AVR8_PART_IS_DEFINED(ATtiny25) || \
AVR8_PART_IS_DEFINED(ATtiny26) || \
AVR8_PART_IS_DEFINED(ATtiny261) || \
AVR8_PART_IS_DEFINED(ATtiny261A) || \
AVR8_PART_IS_DEFINED(ATtiny4) || \
AVR8_PART_IS_DEFINED(ATtiny40) || \
AVR8_PART_IS_DEFINED(ATtiny4313) || \
AVR8_PART_IS_DEFINED(ATtiny43U) || \
AVR8_PART_IS_DEFINED(ATtiny44) || \
AVR8_PART_IS_DEFINED(ATtiny44A) || \
AVR8_PART_IS_DEFINED(ATtiny45) || \
AVR8_PART_IS_DEFINED(ATtiny461) || \
AVR8_PART_IS_DEFINED(ATtiny461A) || \
AVR8_PART_IS_DEFINED(ATtiny48) || \
AVR8_PART_IS_DEFINED(ATtiny5) || \
AVR8_PART_IS_DEFINED(ATtiny828) || \
AVR8_PART_IS_DEFINED(ATtiny84) || \
AVR8_PART_IS_DEFINED(ATtiny84A) || \
AVR8_PART_IS_DEFINED(ATtiny85) || \
AVR8_PART_IS_DEFINED(ATtiny861) || \
AVR8_PART_IS_DEFINED(ATtiny861A) || \
AVR8_PART_IS_DEFINED(ATtiny87) || \
AVR8_PART_IS_DEFINED(ATtiny88) || \
AVR8_PART_IS_DEFINED(ATtiny9) \
)
/** @} */
/** tinyAVR product line */
#define TINY (TINY_UNCATEGORIZED)
/** @} */
/**
* \defgroup sam_part_macros_group SAM parts
* @{
*/
/**
* \name SAM3S series
* @{
*/
#define SAM3S1 ( \
SAM_PART_IS_DEFINED(SAM3S1A) || \
SAM_PART_IS_DEFINED(SAM3S1B) || \
SAM_PART_IS_DEFINED(SAM3S1C) \
)
#define SAM3S2 ( \
SAM_PART_IS_DEFINED(SAM3S2A) || \
SAM_PART_IS_DEFINED(SAM3S2B) || \
SAM_PART_IS_DEFINED(SAM3S2C) \
)
#define SAM3S4 ( \
SAM_PART_IS_DEFINED(SAM3S4A) || \
SAM_PART_IS_DEFINED(SAM3S4B) || \
SAM_PART_IS_DEFINED(SAM3S4C) \
)
#define SAM3S8 ( \
SAM_PART_IS_DEFINED(SAM3S8B) || \
SAM_PART_IS_DEFINED(SAM3S8C) \
)
#define SAM3SD8 ( \
SAM_PART_IS_DEFINED(SAM3SD8B) || \
SAM_PART_IS_DEFINED(SAM3SD8C) \
)
/** @} */
/**
* \name SAM3U series
* @{
*/
#define SAM3U1 ( \
SAM_PART_IS_DEFINED(SAM3U1C) || \
SAM_PART_IS_DEFINED(SAM3U1E) \
)
#define SAM3U2 ( \
SAM_PART_IS_DEFINED(SAM3U2C) || \
SAM_PART_IS_DEFINED(SAM3U2E) \
)
#define SAM3U4 ( \
SAM_PART_IS_DEFINED(SAM3U4C) || \
SAM_PART_IS_DEFINED(SAM3U4E) \
)
/** @} */
/**
* \name SAM3N series
* @{
*/
#define SAM3N1 ( \
SAM_PART_IS_DEFINED(SAM3N1A) || \
SAM_PART_IS_DEFINED(SAM3N1B) || \
SAM_PART_IS_DEFINED(SAM3N1C) \
)
#define SAM3N2 ( \
SAM_PART_IS_DEFINED(SAM3N2A) || \
SAM_PART_IS_DEFINED(SAM3N2B) || \
SAM_PART_IS_DEFINED(SAM3N2C) \
)
#define SAM3N4 ( \
SAM_PART_IS_DEFINED(SAM3N4A) || \
SAM_PART_IS_DEFINED(SAM3N4B) || \
SAM_PART_IS_DEFINED(SAM3N4C) \
)
/** @} */
/**
* \name SAM3X series
* @{
*/
#define SAM3X4 ( \
SAM_PART_IS_DEFINED(SAM3X4C) || \
SAM_PART_IS_DEFINED(SAM3X4E) \
)
#define SAM3X8 ( \
SAM_PART_IS_DEFINED(SAM3X8C) || \
SAM_PART_IS_DEFINED(SAM3X8E) || \
SAM_PART_IS_DEFINED(SAM3X8H) \
)
/** @} */
/**
* \name SAM3A series
* @{
*/
#define SAM3A4 ( \
SAM_PART_IS_DEFINED(SAM3A4C) \
)
#define SAM3A8 ( \
SAM_PART_IS_DEFINED(SAM3A8C) \
)
/** @} */
/**
* \name SAM4S series
* @{
*/
#define SAM4S8 ( \
SAM_PART_IS_DEFINED(SAM4S8B) || \
SAM_PART_IS_DEFINED(SAM4S8C) \
)
#define SAM4S16 ( \
SAM_PART_IS_DEFINED(SAM4S16B) || \
SAM_PART_IS_DEFINED(SAM4S16C) \
)
#define SAM4SA16 ( \
SAM_PART_IS_DEFINED(SAM4SA16B) || \
SAM_PART_IS_DEFINED(SAM4SA16C) \
)
#define SAM4SD16 ( \
SAM_PART_IS_DEFINED(SAM4SD16B) || \
SAM_PART_IS_DEFINED(SAM4SD16C) \
)
#define SAM4SD32 ( \
SAM_PART_IS_DEFINED(SAM4SD32B) || \
SAM_PART_IS_DEFINED(SAM4SD32C) \
)
/** @} */
/**
* \name SAM4L series
* @{
*/
#define SAM4LS ( \
SAM_PART_IS_DEFINED(ATSAM4LS2A) || \
SAM_PART_IS_DEFINED(ATSAM4LS2B) || \
SAM_PART_IS_DEFINED(ATSAM4LS2C) || \
SAM_PART_IS_DEFINED(ATSAM4LS4A) || \
SAM_PART_IS_DEFINED(ATSAM4LS4B) || \
SAM_PART_IS_DEFINED(ATSAM4LS4C) \
)
#define SAM4LC ( \
SAM_PART_IS_DEFINED(ATSAM4LC2A) || \
SAM_PART_IS_DEFINED(ATSAM4LC2B) || \
SAM_PART_IS_DEFINED(ATSAM4LC2C) || \
SAM_PART_IS_DEFINED(ATSAM4LC4A) || \
SAM_PART_IS_DEFINED(ATSAM4LC4B) || \
SAM_PART_IS_DEFINED(ATSAM4LC4C) \
)
/** @} */
/**
* \name SAM4E series
* @{
*/
#define SAM4E8 ( \
SAM_PART_IS_DEFINED(SAM4E8E) \
)
#define SAM4E16 ( \
SAM_PART_IS_DEFINED(SAM4E16E) \
)
/** @} */
/**
* \name SAM families
* @{
*/
/** SAM3S Family */
#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8)
/** SAM3U Family */
#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4)
/** SAM3N Family */
#define SAM3N (SAM3N1 || SAM3N2 || SAM3N4)
/** SAM3XA Family */
#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8)
/** SAM4S Family */
#define SAM4S (SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32)
/** SAM4L Family */
#define SAM4L (SAM4LS || SAM4LC)
/** SAM4E Family */
#define SAM4E (SAM4E8 || SAM4E16)
/** @} */
/** SAM product line */
#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E)
/** @} */
/** @} */
#endif /* ATMEL_PARTS_H */
dstat-firmware-master/src/asf/common/utils/stdio/ 0000775 0000000 0000000 00000000000 13317465730 0022423 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/utils/stdio/read.c 0000664 0000000 0000000 00000010252 13317465730 0023502 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief System-specific implementation of the \ref _read function used by
* the standard library.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "compiler.h"
/**
* \defgroup group_common_utils_stdio Standard I/O (stdio)
*
* Common standard I/O driver that implements the stdio
* read and write functions on AVR and SAM devices.
*
* \{
*/
extern volatile void *volatile stdio_base;
void (*ptr_get)(void volatile*, char*);
// IAR common implementation
#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) )
#include
_STD_BEGIN
#pragma module_name = "?__read"
/*! \brief Reads a number of bytes, at most \a size, into the memory area
* pointed to by \a buffer.
*
* \param handle File handle to read from.
* \param buffer Pointer to buffer to write read bytes to.
* \param size Number of bytes to read.
*
* \return The number of bytes read, \c 0 at the end of the file, or
* \c _LLIO_ERROR on failure.
*/
size_t __read(int handle, unsigned char *buffer, size_t size)
{
int nChars = 0;
// This implementation only reads from stdin.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDIN) {
return _LLIO_ERROR;
}
for (; size > 0; --size) {
ptr_get(stdio_base, (char*)buffer);
buffer++;
nChars++;
}
return nChars;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
int __close(int handle)
{
UNUSED(handle);
return 0;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
int remove(const char* val)
{
UNUSED(val);
return 0;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
long __lseek(int handle, long val, int val2)
{
UNUSED(handle);
UNUSED(val2);
return val;
}
_STD_END
// GCC AVR32 and SAM implementation
#elif (defined(__GNUC__) && !XMEGA)
int __attribute__((weak))
_read (int file, char * ptr, int len); // Remove GCC compiler warning
int __attribute__((weak))
_read (int file, char * ptr, int len)
{
int nChars = 0;
if (file != 0) {
return -1;
}
for (; len > 0; --len) {
ptr_get(stdio_base, ptr);
ptr++;
nChars++;
}
return nChars;
}
// GCC AVR implementation
#elif (defined(__GNUC__) && XMEGA)
int _read (int *f); // Remove GCC compiler warning
int _read (int *f)
{
char c;
ptr_get(stdio_base,&c);
return c;
}
#endif
/**
* \}
*/
dstat-firmware-master/src/asf/common/utils/stdio/stdio_usb/ 0000775 0000000 0000000 00000000000 13317465730 0024416 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/common/utils/stdio/stdio_usb/stdio_usb.c 0000664 0000000 0000000 00000007261 13317465730 0026563 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief USB CDC Standard I/O Serial Management.
*
* This module defines support routines for a stdio serial interface to the
* Atmel Software Framework (ASF) common USB CDC service.
*
* Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "stdio_usb.h"
static bool stdio_usb_interface_enable = false;
int stdio_usb_putchar (volatile void * unused, char data)
{
/* A negative return value should be used to indicate that data
* was not written, but this doesn't seem to work with GCC libc.
*/
if (!stdio_usb_interface_enable) {
return 0; // -1
}
return udi_cdc_putc(data) ? 0 : -1;
}
void stdio_usb_getchar (void volatile * unused, char *data)
{
/* A negative return value should be used to indicate that data
* was not read, but this doesn't seem to work with GCC libc.
*/
if (!stdio_usb_interface_enable) {
*data = 0; // -1
return;
}
*data = (char)udi_cdc_getc();
}
void stdio_usb_vbus_event(bool b_high)
{
if (b_high) {
// Attach USB Device
udc_attach();
} else {
// VBUS not present
udc_detach();
}
}
bool stdio_usb_enable(void)
{
stdio_usb_interface_enable = true;
return true;
}
void stdio_usb_disable(void)
{
stdio_usb_interface_enable = false;
}
void stdio_usb_init(void)
{
stdio_base = NULL;
ptr_put = stdio_usb_putchar;
ptr_get = stdio_usb_getchar;
/*
* Start and attach USB CDC device interface for devices with
* integrated USB interfaces. Assume the VBUS is present if
* VBUS monitoring is not available.
*/
udc_start ();
if (!udc_include_vbus_monitoring()) {
stdio_usb_vbus_event(true);
}
#if defined(__GNUC__)
# if XMEGA
// For AVR GCC libc print redirection uses fdevopen.
fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read));
# endif
# if UC3 || SAM
// For AVR32 and SAM GCC
// Specify that stdout and stdin should not be buffered.
setbuf(stdout, NULL);
setbuf(stdin, NULL);
// Note: Already the case in IAR's Normal DLIB default configuration
// and AVR GCC library:
// - printf() emits one character at a time.
// - getchar() requests only 1 byte to exit.
# endif
#endif
}
dstat-firmware-master/src/asf/common/utils/stdio/stdio_usb/stdio_usb.h 0000664 0000000 0000000 00000007272 13317465730 0026572 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief USB Standard I/O Serial Management.
*
* This file defines a useful set of functions for the Stdio Serial
* interface on AVR devices.
*
* Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef _stdio_usb_h_
#define _stdio_usb_h_
/**
* \defgroup group_common_utils_stdio_stdio_usb USB/CDC Standard I/O (stdio)
* \ingroup group_common_utils_stdio
*
* Standard I/O (stdio) management component that implements a stdio
* USB CDC interface on AVR devices.
*
* \{
*/
#include
#include
#include
#include
extern int _write (char c, int *f);
extern int _read (int *f);
//! Pointer to the base of the USART module instance to use for stdio.
extern volatile void *volatile stdio_base;
//! Pointer to the external low level write function.
extern int (*ptr_put)(void volatile*, char);
//! Pointer to the external low level read function.
extern void (*ptr_get)(void volatile*, char*);
/*! \brief Sends a character with the USART.
*
* \param usart Base address of the USART instance.
* \param data Character to write.
*
* \return Status.
* \retval 0 The character was written.
* \retval -1 The function timed out before the transmitter became ready.
*/
int stdio_usb_putchar (volatile void * usart, char data);
/*! \brief Waits until a character is received, and returns it.
*
* \param usart Base address of the USART instance.
* \param data Data to read
*
* \return Nothing.
*/
void stdio_usb_getchar (void volatile * usart, char * data);
/*! \brief Callback for VBUS level change event.
*
* \param b_high 1 if VBus is present
*
* \return Nothing.
*/
void stdio_usb_vbus_event (bool b_high);
/*! \brief Enables the stdio in USB Serial Mode.
*
* \return \c 1 if function was successfully done, otherwise \c 0.
*/
bool stdio_usb_enable(void);
/*! \brief Disables the stdio in USB Serial Mode.
*
* \return Nothing.
*/
void stdio_usb_disable(void);
/*! \brief Initializes the stdio in USB Serial Mode.
*
* \return Nothing.
*/
void stdio_usb_init(void);
/**
* \}
*/
#endif // _stdio_usb_h_
dstat-firmware-master/src/asf/common/utils/stdio/write.c 0000664 0000000 0000000 00000007333 13317465730 0023727 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief System-specific implementation of the \ref _write function used by
* the standard library.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "compiler.h"
/**
* \addtogroup group_common_utils_stdio
*
* \{
*/
volatile void *volatile stdio_base;
int (*ptr_put)(void volatile*, char);
#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__))
#include
_STD_BEGIN
#pragma module_name = "?__write"
/*! \brief Writes a number of bytes, at most \a size, from the memory area
* pointed to by \a buffer.
*
* If \a buffer is zero then \ref __write performs flushing of internal buffers,
* if any. In this case, \a handle can be \c -1 to indicate that all handles
* should be flushed.
*
* \param handle File handle to write to.
* \param buffer Pointer to buffer to read bytes to write from.
* \param size Number of bytes to write.
*
* \return The number of bytes written, or \c _LLIO_ERROR on failure.
*/
size_t __write(int handle, const unsigned char *buffer, size_t size)
{
size_t nChars = 0;
if (buffer == 0) {
// This means that we should flush internal buffers.
return 0;
}
// This implementation only writes to stdout and stderr.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) {
return _LLIO_ERROR;
}
for (; size != 0; --size) {
if (ptr_put(stdio_base, *buffer++) < 0) {
return _LLIO_ERROR;
}
++nChars;
}
return nChars;
}
_STD_END
#elif (defined(__GNUC__) && !XMEGA)
int _write (int file, char * ptr, int len); // Remove GCC compiler warning
int __attribute__((weak))
_write (int file, char * ptr, int len);
int __attribute__((weak))
_write (int file, char * ptr, int len)
{
int nChars = 0;
if ((file != 1) && (file != 2) && (file!=3)) {
return -1;
}
for (; len != 0; --len) {
if (ptr_put(stdio_base, *ptr++) < 0) {
return -1;
}
++nChars;
}
return nChars;
}
#elif (defined(__GNUC__) && XMEGA)
int _write (char c, int *f);
int _write (char c, int *f)
{
if (ptr_put(stdio_base, c) < 0) {
return -1;
}
return 1;
}
#endif
/**
* \}
*/
dstat-firmware-master/src/asf/xmega/ 0000775 0000000 0000000 00000000000 13317465730 0017752 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/xmega/drivers/ 0000775 0000000 0000000 00000000000 13317465730 0021430 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/xmega/drivers/cpu/ 0000775 0000000 0000000 00000000000 13317465730 0022217 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/xmega/drivers/cpu/ccp.h 0000664 0000000 0000000 00000007207 13317465730 0023143 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Configuration Change Protection write functions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef CPU_CCP_H
#define CPU_CCP_H
#include
/**
* \defgroup ccp_group Configuration Change Protection
*
* See \ref xmega_ccp_quickstart.
*
* Function for writing to protected IO registers.
* @{
*/
#if defined(__DOXYGEN__)
//! \name IAR Memory Model defines.
//@{
/**
* \def CONFIG_MEMORY_MODEL_TINY
* \brief Configuration symbol to enable 8 bit pointers.
*
*/
# define CONFIG_MEMORY_MODEL_TINY
/**
* \def CONFIG_MEMORY_MODEL_SMALL
* \brief Configuration symbol to enable 16 bit pointers.
* \note If no memory model is defined, SMALL is default.
*
*/
# define CONFIG_MEMORY_MODEL_SMALL
/**
* \def CONFIG_MEMORY_MODEL_LARGE
* \brief Configuration symbol to enable 24 bit pointers.
*
*/
# define CONFIG_MEMORY_MODEL_LARGE
//@}
#endif
/**
* \brief Write to a CCP-protected 8-bit I/O register
*
* \param addr Address of the I/O register
* \param value Value to be written
*
* \note Using IAR Embedded workbench, the choice of memory model has an impact
* on calling convention. The memory model is not visible to the
* preprocessor, so it must be defined in the Assembler preprocessor directives.
*/
extern void ccp_write_io(void *addr, uint8_t value);
/** @} */
/**
* \page xmega_ccp_quickstart Quick start guide for CCP driver
*
* This is the quick start guide for the \ref ccp_group
* "Configuration Change Protection (CCP) driver", with step-by-step
* instructions on how to use the driver.
*
* The use case contains a code fragment, and this can be copied into, e.g.,
* the main application function.
*
* \section ccp_basic_use_case Basic use case
* In this use case, the CCP is used to write to the protected XMEGA Clock
* Control register.
*
* \subsection ccp_basic_use_case_setup_flow Workflow
* -# call CCP write io to change system clock selection:
* - \code ccp_write_io((uint8_t *)&CLK.CTRL, CLK_SCLKSEL_RC32M_gc); \endcode
*/
#endif /* CPU_CCP_H */
dstat-firmware-master/src/asf/xmega/drivers/cpu/ccp.s 0000664 0000000 0000000 00000007241 13317465730 0023154 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Configuration Change Protection
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include
//! Value to write to CCP for access to protected IO registers.
#define CCP_IOREG 0xd8
/*
* GNU and IAR use different calling conventions. Since this is
* a very small and simple function to begin with, it's easier
* to implement it twice than to deal with the differences
* within a single implementation.
*
* Interrupts are disabled by hardware during the timed
* sequence, so there's no need to save/restore interrupt state.
*/
PUBLIC_FUNCTION(ccp_write_io)
#if defined(__GNUC__)
out RAMPZ, r1 // Reset bits 23:16 of Z
movw r30, r24 // Load addr into Z
ldi r18, CCP_IOREG // Load magic CCP value
out CCP, r18 // Start CCP handshake
st Z, r22 // Write value to I/O register
ret // Return to caller
#elif defined(__IAR_SYSTEMS_ASM__)
# if !defined(CONFIG_MEMORY_MODEL_TINY) && !defined(CONFIG_MEMORY_MODEL_SMALL) \
&& !defined(CONFIG_MEMORY_MODEL_LARGE)
# define CONFIG_MEMORY_MODEL_SMALL
# endif
ldi r20, 0
out RAMPZ, r20 // Reset bits 23:16 of Z
# if defined(CONFIG_MEMORY_MODEL_TINY)
mov r31, r20 // Reset bits 8:15 of Z
mov r30, r16 // Load addr into Z
# else
movw r30, r16 // Load addr into Z
# endif
ldi r21, CCP_IOREG // Load magic CCP value
out CCP, r21 // Start CCP handshake
# if defined(CONFIG_MEMORY_MODEL_TINY)
st Z, r17 // Write value to I/O register
# elif defined(CONFIG_MEMORY_MODEL_SMALL)
st Z, r18 // Write value to I/O register
# elif defined(CONFIG_MEMORY_MODEL_LARGE)
st Z, r19 // Write value to I/O register
# else
# error Unknown memory model in use, no idea how registers should be accessed
# endif
ret
#else
# error Unknown assembler
#endif
END_FUNC(ccp_write_io)
END_FILE()
dstat-firmware-master/src/asf/xmega/drivers/cpu/xmega_reset_cause.h 0000664 0000000 0000000 00000006573 13317465730 0026066 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Chip-specific reset cause functions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef XMEGA_DRIVERS_CPU_RESET_CAUSE_H
#define XMEGA_DRIVERS_CPU_RESET_CAUSE_H
#include "compiler.h"
#include "ccp.h"
/**
* \ingroup reset_cause_group
* \defgroup xmega_reset_cause_group XMEGA reset cause
*
* See \ref reset_cause_quickstart
*
* @{
*/
/**
* \brief Chip-specific reset cause type capable of holding all chip reset
* causes. Typically reflects the size of the reset cause register.
*/
typedef uint8_t reset_cause_t;
//! \internal \name Chip-specific reset causes
//@{
//! \internal External reset cause
#define CHIP_RESET_CAUSE_EXTRST RST_EXTRF_bm
//! \internal brown-out detected reset cause, same as for CPU
#define CHIP_RESET_CAUSE_BOD_IO RST_BORF_bm
//! \internal Brown-out detected reset cause, same as for I/O
#define CHIP_RESET_CAUSE_BOD_CPU RST_BORF_bm
//! \internal On-chip debug system reset cause
#define CHIP_RESET_CAUSE_OCD RST_PDIRF_bm
//! \internal Power-on-reset reset cause
#define CHIP_RESET_CAUSE_POR RST_PORF_bm
//! \internal Software reset reset cause
#define CHIP_RESET_CAUSE_SOFT RST_SRF_bm
//! \internal Spike detected reset cause
#define CHIP_RESET_CAUSE_SPIKE RST_SDRF_bm
//! \internal Watchdog timeout reset cause
#define CHIP_RESET_CAUSE_WDT RST_WDRF_bm
//@}
static inline reset_cause_t reset_cause_get_causes(void)
{
return (reset_cause_t)RST.STATUS;
}
static inline void reset_cause_clear_causes(reset_cause_t causes)
{
RST.STATUS = causes;
}
static inline void reset_do_soft_reset(void)
{
ccp_write_io((void *)&RST.CTRL, RST_SWRST_bm);
while (1) {
/* Intentionally empty. */
}
}
//! @}
#endif /* XMEGA_DRIVERS_CPU_RESET_CAUSE_H */
dstat-firmware-master/src/asf/xmega/drivers/dma/ 0000775 0000000 0000000 00000000000 13317465730 0022171 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/xmega/drivers/dma/dma.c 0000664 0000000 0000000 00000016207 13317465730 0023104 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief AVR XMEGA Direct Memory Access Controller driver
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include
#include
#include
#include
#include
/**
* \private
* \brief DMA private data struct
*/
struct dma_data_struct {
/** Callback on complete */
dma_callback_t callback;
};
/**
* \internal
* \brief DMA private data for each channel
*/
struct dma_data_struct dma_data[DMA_NUMBER_OF_CHANNELS];
/**
* \brief Enable DMA controller
*
* \note This function will do a soft reset of the DMA controller, clearing all
* previous configuration.
*/
void dma_enable(void)
{
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA);
sleepmgr_lock_mode(SLEEPMGR_IDLE);
/* Reset DMA controller just to make sure everything is from scratch */
DMA.CTRL = DMA_RESET_bm;
DMA.CTRL = DMA_ENABLE_bm;
}
/**
* \brief Disable DMA controller
*/
void dma_disable(void)
{
DMA.CTRL = 0;
sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA);
sleepmgr_unlock_mode(SLEEPMGR_IDLE);
}
/**
* \brief Set callback for given DMA channel
*
* \param num \ref dma_channel_num_t
* \param callback \ref dma_callback_t
*/
void dma_set_callback(dma_channel_num_t num, dma_callback_t callback)
{
dma_data[num].callback = callback;
}
/**
* \internal
* \brief Common DMA channel interrupt handler
*
* Calls the channel callback with the channel status code. The following
* status codes are possible:
* - DMA_CH_TRANSFER_COMPLETED: Transfer completed successfully
* - DMA_CH_TRANSFER_ERROR: Fault in transfer
*
* The optional callback used by the interrupt handler is set by the
* dma_set_callback() function.
*
* \param num DMA channel number to handle interrupt for
*/
static void dma_interrupt(const dma_channel_num_t num)
{
enum dma_channel_status status;
DMA_CH_t *channel;
channel = dma_get_channel_address_from_num(num);
status = dma_get_channel_status(num);
/* Clear all interrupt flags to be sure */
channel->CTRLB |= DMA_CH_TRNIF_bm | DMA_CH_ERRIF_bm;
if (dma_data[num].callback) {
dma_data[num].callback(status);
}
}
/**
* \internal
* \brief DMA channel 0 interrupt handler
*/
ISR(DMA_CH0_vect)
{
dma_interrupt(0);
}
#if DMA_NUMBER_OF_CHANNELS > 1
/**
* \internal
* \brief DMA channel 1 interrupt handler
*/
ISR(DMA_CH1_vect)
{
dma_interrupt(1);
}
#endif
#if DMA_NUMBER_OF_CHANNELS > 2
/**
* \internal
* \brief DMA channel 2 interrupt handler
*/
ISR(DMA_CH2_vect)
{
dma_interrupt(2);
}
#endif
#if DMA_NUMBER_OF_CHANNELS > 3
/**
* \internal
* \brief DMA channel 3 interrupt handler
*/
ISR(DMA_CH3_vect)
{
dma_interrupt(3);
}
#endif
/**
* \brief Write DMA channel configuration to hardware
*
* This function will write the DMA channel configuration, provided by a
* \ref dma_channel_config.
*
* \param num DMA channel number to write configuration to
* \param config Pointer to a DMA channel config, given by a
* \ref dma_channel_config
*/
void dma_channel_write_config(dma_channel_num_t num,
struct dma_channel_config *config)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
#ifdef CONFIG_HAVE_HUGEMEM
channel->DESTADDR0 = (uint32_t)config->destaddr;
channel->DESTADDR1 = (uint32_t)config->destaddr >> 8;
channel->DESTADDR2 = (uint32_t)config->destaddr >> 16;
#else
channel->DESTADDR0 = (uint32_t)config->destaddr16;
channel->DESTADDR1 = (uint32_t)config->destaddr16 >> 8;
# if XMEGA_A || XMEGA_AU
channel->DESTADDR2 = 0;
# endif
#endif
#ifdef CONFIG_HAVE_HUGEMEM
channel->SRCADDR0 = (uint32_t)config->srcaddr;
channel->SRCADDR1 = (uint32_t)config->srcaddr >> 8;
channel->SRCADDR2 = (uint32_t)config->srcaddr >> 16;
#else
channel->SRCADDR0 = (uint32_t)config->srcaddr16;
channel->SRCADDR1 = (uint32_t)config->srcaddr16 >> 8;
# if XMEGA_A || XMEGA_AU
channel->SRCADDR2 = 0;
# endif
#endif
channel->ADDRCTRL = config->addrctrl;
channel->TRIGSRC = config->trigsrc;
channel->TRFCNT = config->trfcnt;
channel->REPCNT = config->repcnt;
channel->CTRLB = config->ctrlb;
/* Make sure the DMA channel is not enabled before dma_channel_enable()
* is called.
*/
#if XMEGA_A || XMEGA_AU
channel->CTRLA = config->ctrla & ~DMA_CH_ENABLE_bm;
#else
channel->CTRLA = config->ctrla & ~DMA_CH_CHEN_bm;
#endif
cpu_irq_restore(iflags);
}
/**
* \brief Read DMA channel configuration from hardware
*
* This function will read the DMA channel configuration into a
* \ref dma_channel_config.
*
* \param num DMA channel number to read configuration from
* \param config Pointer to a DMA channel config, given by a
* \ref dma_channel_config
*/
void dma_channel_read_config(dma_channel_num_t num,
struct dma_channel_config *config)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
#ifdef CONFIG_HAVE_HUGEMEM
uint32_t address;
#else
uint16_t address;
#endif
address = channel->DESTADDR0;
address |= channel->DESTADDR1 << 8;
#ifdef CONFIG_HAVE_HUGEMEM
address |= (uint32_t)channel->DESTADDR2 << 16;
config->destaddr = (hugemem_ptr_t)address;
#else
config->destaddr16 = address;
#endif
address = channel->SRCADDR0;
address |= channel->SRCADDR1 << 8;
#ifdef CONFIG_HAVE_HUGEMEM
address |= (uint32_t)channel->SRCADDR2 << 16;
config->srcaddr = (hugemem_ptr_t)address;
#else
config->srcaddr16 = address;
#endif
config->addrctrl = channel->ADDRCTRL;
config->trigsrc = channel->TRIGSRC;
config->trfcnt = channel->TRFCNT;
config->repcnt = channel->REPCNT;
config->ctrlb = channel->CTRLB;
config->ctrla = channel->CTRLA;
cpu_irq_restore(iflags);
}
dstat-firmware-master/src/asf/xmega/drivers/dma/dma.h 0000664 0000000 0000000 00000131506 13317465730 0023111 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief AVR XMEGA Direct Memory Access Controller driver definitions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef DRIVERS_DMA_DMA_H
#define DRIVERS_DMA_DMA_H
#include
#include
#include
#include
/**
* \defgroup dma_group Direct Memory Access controller (DMA)
*
* See \ref xmega_dma_quickstart.
*
* This is a driver for configuration, enabling, disabling and use of the
* on-chip XMEGA Direct Memory Access (DMA) controller.
*
* \section dependencies Dependencies
*
* The direct memory access controller depends on the following modules:
* - \ref pmic_group for setting interrupt level.
* - \ref sysclk_group for peripheral clock control.
* - \ref sleepmgr_group for setting available sleep mode.
*
* @{
*/
#if XMEGA_A || XMEGA_AU
# define DMA_NUMBER_OF_CHANNELS 4
#else
/** Number of available DMA channels, device dependent. */
# define DMA_NUMBER_OF_CHANNELS 2
#endif
/**
* \private
* \brief Helper macro to get the channel offset given the channel number
*
* \param num DMA channel number
*
* \return DMA_CH_t pointer to the \a num DMA channel register struct
*/
#define dma_get_channel_address_from_num(num) \
((DMA_CH_t *)((uintptr_t)(&DMA.CH0) + (sizeof(DMA_CH_t) * num)))
/** \brief DMA channel number type */
typedef uint8_t dma_channel_num_t;
/** \brief DMA channel status */
enum dma_channel_status {
/** DMA channel is idling */
DMA_CH_FREE = 0,
/** DMA channel has a block transfer pending */
DMA_CH_PENDING,
/** DMA channel is busy doing a block transfer */
DMA_CH_BUSY,
/** DMA channel has completed a block transfer */
DMA_CH_TRANSFER_COMPLETED,
/** DMA channel failed to complete a block transfer */
DMA_CH_TRANSFER_ERROR,
};
/**
* \brief DMA channel configuration struct
*/
struct dma_channel_config {
/** DMA channel control register A */
uint8_t ctrla;
/** DMA channel control register B */
uint8_t ctrlb;
/** DMA channel address control register */
uint8_t addrctrl;
/** DMA channel trigger control register */
uint8_t trigsrc;
/** DMA channel block transfer count register */
uint16_t trfcnt;
/** DMA channel repeat counter register */
uint8_t repcnt;
union {
#ifdef CONFIG_HAVE_HUGEMEM
/** DMA channel source hugemem address */
hugemem_ptr_t srcaddr;
#endif
/** DMA channel source 16-bit address */
uint16_t srcaddr16;
};
union {
#ifdef CONFIG_HAVE_HUGEMEM
/** DMA channel destination hugemem address */
hugemem_ptr_t destaddr;
#endif
/** DMA channel destaddr 16-bit address */
uint16_t destaddr16;
};
};
/** DMA interrupt levels */
enum dma_int_level_t {
DMA_INT_LVL_OFF = 0x00,
DMA_INT_LVL_LO = 0x01,
DMA_INT_LVL_MED = 0x02,
DMA_INT_LVL_HI = 0x03,
};
void dma_enable(void);
void dma_disable(void);
/** \name DMA Controller Management */
/* @{ */
/**
* \brief Set DMA channel priority mode
*
* This functions sets the channel priority mode. Users can select between
* fixed priority, round-robin or a mix of both.
*
* The modes are defined in the toolchain header files in the form of \a
* DMA_PRIMODE_*_gc for devices with more than 2 channels, or DMA_PRIMODE_*_bm
* for dual channel devices.
*
* \param primode DMA channel priority mode given by a DMA_PRIMODE_t type
*/
static inline void dma_set_priority_mode(DMA_PRIMODE_t primode)
{
irqflags_t iflags;
#if XMEGA_A || XMEGA_AU
Assert(!(primode & ~DMA_PRIMODE_gm));
#else
Assert(!(primode & ~DMA_PRIMODE_bm));
#endif
iflags = cpu_irq_save();
#if XMEGA_A || XMEGA_AU
DMA.CTRL = (DMA.CTRL & ~DMA_PRIMODE_gm) | primode;
#else
DMA.CTRL = (DMA.CTRL & ~DMA_PRIMODE_bm) | primode;
#endif
cpu_irq_restore(iflags);
}
/**
* \brief Set DMA channel double buffering mode
*
* This function modifies which channels should be in double buffer mode. The
* modes are defined in the toolchain header files in the form of \a
* DMA_DBUFMODE_*_gc for devices with more than 2 channels, or DMA_DBUFMODE_*_bm
* for dual channel devices.
*
* \param dbufmode Double buffer channel configuration given by a
* DMA_DBUFMODE_t type
*/
static inline void dma_set_double_buffer_mode(DMA_DBUFMODE_t dbufmode)
{
irqflags_t iflags;
#if XMEGA_A || XMEGA_AU
Assert(!(dbufmode & ~DMA_DBUFMODE_gm));
#else
Assert(!(dbufmode & ~DMA_DBUFMODE_bm));
#endif
iflags = cpu_irq_save();
#if XMEGA_A || XMEGA_AU
DMA.CTRL = (DMA.CTRL & ~DMA_DBUFMODE_gm) | dbufmode;
#else
DMA.CTRL = (DMA.CTRL & ~DMA_DBUFMODE_bm) | dbufmode;
#endif
cpu_irq_restore(iflags);
}
/** @} */
/** \name DMA Channel Management */
/** @{ */
void dma_channel_write_config(dma_channel_num_t num,
struct dma_channel_config *config);
void dma_channel_read_config(dma_channel_num_t num,
struct dma_channel_config *config);
/**
* \brief Enable a DMA channel
*
* This function enables a DMA channel, depending on the configuration the DMA
* channel will start the block transfer upon a
* \ref dma_channel_trigger_block_transfer() or when other hardware modules trigger
* the DMA hardware.
*
* \pre The DMA channel configuration must be written to the channel before
* enabling the channel.
*
* \param num DMA channel to enable
*/
static inline void dma_channel_enable(dma_channel_num_t num)
{
irqflags_t iflags = cpu_irq_save();
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
#if XMEGA_A || XMEGA_AU
channel->CTRLA |= DMA_CH_ENABLE_bm;
#else
channel->CTRLA |= DMA_CH_CHEN_bm;
#endif
cpu_irq_restore(iflags);
}
/**
* \brief Disable a DMA channel
*
* This function disables a DMA channel. If the DMA channel was already enabled
* the DMA channel is not disabled before the internal transfer buffer is empty
* and the DMA transfer is aborted.
*
* \param num DMA channel to disable
*/
static inline void dma_channel_disable(dma_channel_num_t num)
{
irqflags_t iflags = cpu_irq_save();
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
#if XMEGA_A || XMEGA_AU
channel->CTRLA &= ~DMA_CH_ENABLE_bm;
#else
channel->CTRLA &= ~DMA_CH_CHEN_bm;
#endif
cpu_irq_restore(iflags);
}
/**
* \brief Check if DMA channel is enabled
*
* This function checks if a DMA channel is enabled.
*
* \param num DMA channel number to query
*
* \retval true DMA channel is enabled
* \retval false DMA channel is disabled
*/
static inline bool dma_channel_is_enabled(dma_channel_num_t num)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
bool channel_enabled;
#if XMEGA_A || XMEGA_AU
channel_enabled = (channel->CTRLA & DMA_CH_ENABLE_bm);
#else
channel_enabled = (channel->CTRLA & DMA_CH_CHEN_bm);
#endif
return channel_enabled;
}
/**
* \brief Check if DMA channel is busy
*
* This function checks if a DMA channel is busy doing or going to do (pending)
* a block transfer.
*
* \param num DMA channel number to query
*
* \retval true DMA channel is busy or have a block transfer pending
* \retval false DMA channel is not busy or have a block transfer pending
*/
static inline bool dma_channel_is_busy(dma_channel_num_t num)
{
uint8_t busy_pending = DMA.STATUS;
busy_pending &= (1 << num) | (1 << (num + 4));
if (busy_pending) {
return true;
}
return false;
}
/**
* \brief Get channel status
*
* This function returns the current channel status.
*
* \param num DMA channel number
*
* \return Channel status given by a \ref dma_channel_status
*/
static inline enum dma_channel_status dma_get_channel_status(
dma_channel_num_t num)
{
uint8_t busy_pending = DMA.STATUS;
uint8_t error_completed = DMA.INTFLAGS;
/*
* Check lower and upper nibble of INTFLAGS register to find possible
* error or transfer completed status.
*/
error_completed &= (1 << num) | (1 << (num + 4));
if (error_completed & (1 << (num + 4))) {
return DMA_CH_TRANSFER_ERROR;
} else if (error_completed & (1 << num)) {
return DMA_CH_TRANSFER_COMPLETED;
}
/*
* Check lower and upper nibble of STATUS register to find possible
* busy or pending completed status.
*/
busy_pending &= (1 << num) | (1 << (num + 4));
if (busy_pending & (1 << (num + 4))) {
return DMA_CH_BUSY;
} else if (busy_pending & (1 << num)) {
return DMA_CH_PENDING;
}
return DMA_CH_FREE;
}
/**
* \brief DMA channel trigger block transfer
*
* This function triggers a start of a block transfer on a given DMA channel.
*
* \pre The DMA channel must be configured and enabled for this to have any
* affect.
*
* \param num DMA channel number to trigger block transfer for
*/
static inline void dma_channel_trigger_block_transfer(dma_channel_num_t num)
{
irqflags_t iflags = cpu_irq_save();
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
channel->CTRLA |= DMA_CH_TRFREQ_bm;
cpu_irq_restore(iflags);
}
/**
* \brief Reset a DMA channel
*
* This function resets a given DMA channel.
*
* \param num DMA channel number to trigger block transfer for
*/
static inline void dma_channel_reset(dma_channel_num_t num)
{
irqflags_t iflags = cpu_irq_save();
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
#if XMEGA_A || XMEGA_AU
channel->CTRLA |= DMA_CH_RESET_bm;
#else
channel->CTRLA |= DMA_CH_CHRST_bm;
#endif
cpu_irq_restore(iflags);
}
/**
* \brief Callback definition for DMA channel interrupts
*
* \param status Status of DMA channel block transfer
*/
typedef void (*dma_callback_t)(enum dma_channel_status status);
void dma_set_callback(dma_channel_num_t num, dma_callback_t callback);
/** @} */
/**
* \name DMA Channel Direct Configuration Functions
*
* These functions allows direct configuration on the DMA channels, not going
* through a \ref dma_channel_config struct. This allows update of the most
* commonly changed DMA channel properties.
*
* @{
*/
/**
* \brief Write DMA channel burst length to hardware
*
* This function writes the DMA channel burst length directly to hardware. The
* burst lengths are defined in the toolchain header files in the form of \a
* DMA_CH_BURSTLEN_*_gc, where * represents the various available burst
* lengths.
*
* \param num DMA channel number to write burst length for
* \param burst_length DMA channel burst length given by a DMA_CH_BURSTLEN_t
* type
*/
static inline void dma_channel_write_burst_length(dma_channel_num_t num,
DMA_CH_BURSTLEN_t burst_length)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
channel->CTRLA &= ~DMA_CH_BURSTLEN_gm;
channel->CTRLA |= burst_length;
cpu_irq_restore(iflags);
}
/**
* \brief Write DMA channel transfer count to hardware
*
* This function writes the DMA channel number of bytes in each block transfer
* to hardware.
*
* \param num DMA channel number to write transfer count for
* \param count Number of bytes in each block transfer
*/
static inline void dma_channel_write_transfer_count(dma_channel_num_t num,
uint16_t count)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
channel->TRFCNT = count;
cpu_irq_restore(iflags);
}
/**
* \brief Write DMA channel number of transfer repeats to hardware
*
* This function writes the DMA channel number of block transfer repeats to
* hardware. It will also enable the repeat feature.
*
* \param num DMA channel number to write transfer repeats for
* \param repeats Number of block transfer repeats
*/
static inline void dma_channel_write_repeats(dma_channel_num_t num,
uint8_t repeats)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
channel->REPCNT = repeats;
channel->CTRLA |= DMA_CH_REPEAT_bm;
cpu_irq_restore(iflags);
}
/**
* \brief Write DMA channel 16-bit destination address to hardware
*
* This function writes a DMA channel destination 16-bit LSB address to
*hardware.
*
* \param num DMA channel number to write 16-bit destination address for
* \param destination 16-bit LSB destination address
*/
static inline void dma_channel_write_destination(dma_channel_num_t num,
uint16_t destination)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
channel->DESTADDR0 = destination;
channel->DESTADDR1 = destination >> 8;
#if XMEGA_A || XMEGA_AU
/*
* Make sure the third byte of the destination address is zero to avoid
* a runaway DMA transfer.
*/
channel->DESTADDR2 = 0;
#endif
cpu_irq_restore(iflags);
}
#ifdef CONFIG_HAVE_HUGEMEM
/**
* \brief Write DMA channel hugemem destination address to hardware
*
* This function writes a DMA channel destination hugemem address to hardware.
*
* \param num DMA channel number to write hugemem destination address for
* \param destination hugemem destination address
*/
static inline void dma_channel_write_destination_hugemem(dma_channel_num_t num,
hugemem_ptr_t destination)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
channel->DESTADDR0 = (uint32_t)destination;
channel->DESTADDR1 = (uint32_t)destination >> 8;
channel->DESTADDR2 = (uint32_t)destination >> 16;
cpu_irq_restore(iflags);
}
#endif
/**
* \brief Write DMA channel 16-bit source address to hardware
*
* This function writes a DMA channel source 16-bit LSB address to hardware.
*
* \param num DMA channel number to write 16-bit source address for
* \param source 16-bit LSB source address
*/
static inline void dma_channel_write_source(dma_channel_num_t num,
uint16_t source)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
channel->SRCADDR0 = source;
channel->SRCADDR1 = source >> 8;
#if XMEGA_A || XMEGA_AU
/*
* Make sure the third byte of the source address is zero to avoid a
* runaway DMA transfer.
*/
channel->SRCADDR2 = 0;
#endif
cpu_irq_restore(iflags);
}
#ifdef CONFIG_HAVE_HUGEMEM
/**
* \brief Write DMA channel hugemem source address to hardware
*
* This function writes a DMA channel source hugemem address to hardware.
*
* \param num DMA channel number to write hugemem source address for
* \param source hugemem source address
*/
static inline void dma_channel_write_source_hugemem(dma_channel_num_t num,
hugemem_ptr_t source)
{
DMA_CH_t *channel = dma_get_channel_address_from_num(num);
irqflags_t iflags = cpu_irq_save();
channel->SRCADDR0 = (uint32_t)source;
channel->SRCADDR1 = (uint32_t)source >> 8;
channel->SRCADDR2 = (uint32_t)source >> 16;
cpu_irq_restore(iflags);
}
#endif
/** @} */
/** \name DMA Channel Configuration Helper Functions */
/** @{ */
/**
* \brief Set DMA channel burst length
*
* This function helps the caller setting the DMA channel burst length. The
* burst lengths are defined in the toolchain header files in the form of \a
* DMA_CH_BURSTLEN_*_gc, where * represents the various available burst
* lengths.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param burst_length DMA channel burst length given by a DMA_CH_BURSTLEN_t
* type
*/
static inline void dma_channel_set_burst_length(
struct dma_channel_config *config,
DMA_CH_BURSTLEN_t burst_length)
{
config->ctrla &= ~DMA_CH_BURSTLEN_gm;
config->ctrla |= burst_length;
}
/**
* \brief Set DMA channel in single shot transfer mode
*
* This function helps the caller setting the DMA channel in single shot
* transfer mode.
*
* \param config Pointer to a \ref dma_channel_config variable
*/
static inline void dma_channel_set_single_shot(struct dma_channel_config *config)
{
config->ctrla |= DMA_CH_SINGLE_bm;
}
/**
* \brief Unset DMA channel from single shot transfer mode
*
* This function helps the caller clear the DMA channel single shot transfer
* mode feature.
*
* \param config Pointer to a \ref dma_channel_config variable
*/
static inline void dma_channel_unset_single_shot(
struct dma_channel_config *config)
{
config->ctrla &= ~DMA_CH_SINGLE_bm;
}
/**
* \brief Set DMA channel interrupt level
*
* This function helps the caller setting the DMA channel interrupt level for
* transaction complete and channel error.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param level Interrupt level given by a \ref dma_int_level_t type
*/
static inline void dma_channel_set_interrupt_level(struct dma_channel_config
*config, enum dma_int_level_t level)
{
config->ctrlb &= ~(DMA_CH_ERRINTLVL_gm | DMA_CH_TRNINTLVL_gm);
config->ctrlb |= (level << DMA_CH_ERRINTLVL_gp)
| (level << DMA_CH_TRNINTLVL_gp);
}
/**
* \brief Set DMA channel source address reload mode
*
* This function helps the caller setting the DMA channel source address reload
* mode. The reload modes are defined in the toolchain header files in the form
* of \a DMA_CH_SRCRELOAD_*_gc, where * is NONE, BLOCK, BURST, TRANSACTION.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param mode DMA channel source address reload mode given by an
* DMA_CH_SRCRELOAD_t type
*/
static inline void dma_channel_set_src_reload_mode(
struct dma_channel_config *config,
DMA_CH_SRCRELOAD_t mode)
{
config->addrctrl &= ~DMA_CH_SRCRELOAD_gm;
config->addrctrl |= mode;
}
/**
* \brief Set DMA channel destination address reload mode
*
* This function helps the caller setting the DMA channel destination address
* reload mode. The reload modes are defined in the toolchain header files in
* the form of \a DMA_CH_DESTRELOAD_*_gc, where * is NONE, BLOCK, BURST,
* TRANSACTION.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param mode DMA channel destination address reload mode given by an
* DMA_CH_DESTRELOAD_t type
*/
static inline void dma_channel_set_dest_reload_mode(
struct dma_channel_config *config,
DMA_CH_DESTRELOAD_t mode)
{
config->addrctrl &= ~DMA_CH_DESTRELOAD_gm;
config->addrctrl |= mode;
}
/**
* \brief Set DMA channel source addressing mode
*
* This function helps the caller setting the DMA channel source addressing
* mode. The addressing modes are defined in the toolchain header files in the
* form of \a DMA_CH_SRCDIR_*_gc, where * is FIXED, INC, DEC.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param mode DMA channel source addressing mode given by an
* DMA_CH_SRCDIR_t type
*/
static inline void dma_channel_set_src_dir_mode(
struct dma_channel_config *config,
DMA_CH_SRCDIR_t mode)
{
config->addrctrl &= ~DMA_CH_SRCDIR_gm;
config->addrctrl |= mode;
}
/**
* \brief Set DMA channel destination addressing mode
*
* This function helps the caller setting the DMA channel destination
* addressing mode. The reload modes are defined in the toolchain header files
* in the form of \a DMA_CH_DESTDIR_*_gc, where * is FIXED, INC, DEC.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param mode DMA channel destination addressing mode given by an
* DMA_CH_DESTDIR_t type
*/
static inline void dma_channel_set_dest_dir_mode(
struct dma_channel_config *config,
DMA_CH_DESTDIR_t mode)
{
config->addrctrl &= ~DMA_CH_DESTDIR_gm;
config->addrctrl |= mode;
}
/**
* \brief Set DMA channel trigger source
*
* This function helps the caller setting the DMA channel trigger source. The
* trigger sources are defined in the toolchain header files in the form of \a
* DMA_CH_TRIGSRC_*_gc, where * represents the various sources.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param source DMA channel trigger source given by a DMA_CH_TRIGSRC_t type
*/
static inline void dma_channel_set_trigger_source(
struct dma_channel_config *config,
DMA_CH_TRIGSRC_t source)
{
config->trigsrc = source;
}
/**
* \brief Set DMA channel transfer count
*
* This function helps the caller setting the DMA channel number of bytes in
* each block transfer.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param count Number of bytes in each block transfer
*/
static inline void dma_channel_set_transfer_count(
struct dma_channel_config *config,
uint16_t count)
{
config->trfcnt = count;
}
/**
* \brief Set DMA channel number of transfer repeats
*
* This function helps the caller setting the DMA channel number of block
* transfer repeats. It will also enable the repeat feature.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param repeats Number of block transfer repeats
*/
static inline void dma_channel_set_repeats(struct dma_channel_config *config,
uint8_t repeats)
{
config->ctrla |= DMA_CH_REPEAT_bm;
config->repcnt = repeats;
}
/**
* \brief Set DMA channel 16-bit destination address
*
* This function helps the caller setting the DMA channel destination 16-bit
* LSB address.
*
* \note This function assumes the \a config was initialized with zeros (static
* or intentionally zeroed). If not zero filled, there might be garbage left in
* the upper byte of the destination address.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param destination 16-bit LSB destination address
*/
static inline void dma_channel_set_destination_address(
struct dma_channel_config *config,
uint16_t destination)
{
config->destaddr16 = destination;
}
#ifdef CONFIG_HAVE_HUGEMEM
/**
* \brief Set DMA channel hugemem destination address
*
* This function helps the caller setting the DMA channel destination address.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param destination Destination address provided by a \ref hugemem_ptr_t type
*/
static inline void dma_channel_set_destination_hugemem(
struct dma_channel_config *config,
hugemem_ptr_t destination)
{
config->destaddr = destination;
}
#endif
/**
* \brief Set DMA channel 16-bit source address
*
* This function helps the caller setting the DMA channel source 16-bit LSB
* address.
*
* \note This function assumes the \a config was initialized with zeros (static
* or intentionally zeroed). If not zero filled, there might be garbage left in
* the upper byte of the source address.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param source 16-bit LSB source address
*/
static inline void dma_channel_set_source_address(
struct dma_channel_config *config,
uint16_t source)
{
config->srcaddr16 = source;
}
#ifdef CONFIG_HAVE_HUGEMEM
/**
* \brief Set DMA channel hugemem source address
*
* This function helps the caller setting the DMA channel source address.
*
* \param config Pointer to a \ref dma_channel_config variable
* \param source Source address provided by a \ref hugemem_ptr_t type
*/
static inline void dma_channel_set_source_hugemem(
struct dma_channel_config *config,
hugemem_ptr_t source)
{
config->srcaddr = source;
}
#endif
/** @} */
/** @} */
/**
* \page xmega_dma_quickstart Quick start guide for the XMEGA DMA driver
*
* This is the quick start guide for the \ref dma_group "DMA driver", with
* step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section dma_use_cases Advanced use cases
* For more advanced use of the DMA driver, see the following use cases:
* - \subpage dma_use_case_1
* - \subpage dma_use_case_2
*
* \section dma_basic_use_case Basic use case
* In this basic use case, the DMA is configured for:
* - Burst length: 1 byte
* - Transfer count: 1024
* - Source: Buffer located in RAM
* - Destination: Buffer located in RAM
* - Source and destination address reload mode: End of transaction
* - Source and destination address direction mode: Increment
*
* In this use case data is copied from the source buffer to the destination
* buffer in 1-byte bursts, until all data in the block is transferred. This
* example is analogus to a memcpy(destination, source, sizeof(source))
* operation performed in hardware asynchronously to the CPU.
*
* \section dma_basic_use_case_setup Setup steps
*
* \subsection dma_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref sysclk_group "System Clock Manager Service (sysclk)"
*
* \subsection dma_basic_use_case_setup_setup_code Example code
* Add to application C-file:
* \code
* #define DMA_CHANNEL 0
* #define DMA_BUFFER_SIZE 1024
*
* static uint8_t source[DMA_BUFFER_SIZE];
* static uint8_t destination[DMA_BUFFER_SIZE];
*
* static void dma_init(void)
* {
* struct dma_channel_config dmach_conf;
* memset(&dmach_conf, 0, sizeof(dmach_conf));
*
* dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_1BYTE_gc);
* dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
*
* dma_channel_set_src_reload_mode(&dmach_conf,
* DMA_CH_SRCRELOAD_TRANSACTION_gc);
* dma_channel_set_dest_reload_mode(&dmach_conf,
* DMA_CH_DESTRELOAD_TRANSACTION_gc);
*
* dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
* dma_channel_set_source_address(&dmach_conf,
* (uint16_t)(uintptr_t)source);
*
* dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_INC_gc);
* dma_channel_set_destination_address(&dmach_conf,
* (uint16_t)(uintptr_t)destination);
*
* dma_enable();
*
* dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
* dma_channel_enable(DMA_CHANNEL);
* }
* \endcode
*
* Add to \c main():
* \code
* sysclk_init();
* dma_init();
* \endcode
*
* \subsection dma_basic_use_case_setup_flow Workflow
* -# Define the DMA channel that will be used for the transfer for convenience:
* - \code #define DMA_CHANNEL 0 \endcode
* -# Define the array length that will be the used for the source and
* destination buffers located in RAM:
* - \code #define DMA_BUFFER_SIZE 1024 \endcode
* -# Create a pair of global arrays that will hold the source and destination
* data copied by the DMA controller channel when it is triggered:
* - \code
* static uint8_t source[DMA_BUFFER_SIZE];
* static uint8_t destination[DMA_BUFFER_SIZE];
* \endcode
* -# Create a function \c dma_init() to intialize the DMA:
* - \code
* static void dma_init(void)
* {
* // ...
* }
* \endcode
* -# Create config struct for DMA channel:
* - \code struct dma_channel_config dmach_conf; \endcode
* -# Make sure the configuration structure is zeroed out to ensure that all
* values are reset to their defaults before writing new values:
* - \code memset(&dmach_conf, 0, sizeof(dmach_conf)); \endcode
* -# Configure the DMA channel for single byte bursts, with a transfer length
* equal to the size of the source and destination buffers:
* - \code
* dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_1BYTE_gc);
* dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
* \endcode
* -# Configure the DMA channel to reset the source and destination addresses at
* the end of the complete transaction (i.e. after \c DMA_BUFFER_SIZE bytes
* copied):
* - \code
* dma_channel_set_src_reload_mode(&dmach_conf, DMA_CH_SRCRELOAD_TRANSACTION_gc);
* dma_channel_set_dest_reload_mode(&dmach_conf, DMA_CH_DESTRELOAD_TRANSACTION_gc);
* \endcode
* -# Configure the DMA channel to increment the source and destination
* addresses after each byte transferred:
* - \code
* dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
* dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_INC_gc);
* \endcode
* -# Configure the DMA channel source and destination addresses:
* - \code
* dma_channel_set_source_address(&dmach_conf, (uint16_t)(uintptr_t)source);
* dma_channel_set_destination_address(&dmach_conf, (uint16_t)(uintptr_t)destination);
* \endcode
* -# Enable the DMA module so that channels can be configured in it:
* - \code dma_enable(); \endcode
* \attention Calling dma_enable() will result in a soft-reset of the entire
* DMA module, clearing all channel configurations. If more than one
* DMA channel is to be configured, this function should be called
* only once in the application initialization procedure only.
* -# Write the DMA channel configuration to the DMA and enable it so that
* it can be triggered to start the transfer:
* - \code
* dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
* dma_channel_enable(DMA_CHANNEL);
* \endcode
* -# Initialize the clock system:
* - \code sysclk_init(); \endcode
* -# Call our DMA init function:
* - \code dma_init(); \endcode
*
* \section dma_basic_use_case_usage Usage steps
*
* \subsection dma_basic_use_case_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* dma_channel_trigger_block_transfer(DMA_CHANNEL);
* do {} while (dma_get_channel_status(DMA_CHANNEL) != DMA_CH_TRANSFER_COMPLETED);
* \endcode
*
* \subsection dma_basic_use_case_usage_flow Workflow
* -# Start the DMA transfer:
* - \code dma_channel_trigger_block_transfer(DMA_CHANNEL); \endcode
* -# Wait for the transfer to complete:
* - \code do {} while (dma_get_channel_status(DMA_CHANNEL) != DMA_CH_TRANSFER_COMPLETED);
* \endcode
*/
/**
* \page dma_use_case_1 Use case #1 - Interrupt for a completed DMA transfer.
*
* This use case shows how to set up an interrupt for when a DMA transfer is
* completed.
*
* In this use case, the DMA is configured for:
* - Interrupt level: Low
* - Burst length: 1 byte
* - Transfer count: 1024
* - Source: Buffer located in RAM
* - Destination: Buffer located in RAM
* - Source and destination address reload mode: End of transaction
* - Source and destination address direction mode: Increment
*
* In this use case data is copied from the source buffer to the destination
* buffer in 1-byte bursts, until all data in the block is transferred. This
* example is analogus to a memcpy(destination, source, sizeof(source))
* operation performed in hardware asynchronously to the CPU.
*
* Each time the DMA transfer completes, a user-specified callback function is
* run to notify the user application.
*
* \section dma_use_case_1_setup Setup steps
*
* \subsection dma_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref sysclk_group "System Clock Manager Service (sysclk)"
* -# \ref sleepmgr_group "Sleep Manager Service"
* -# \ref pmic_group "PMIC Driver"
*
* A \ref dma_callback_t "callback" function, called \c dma_transfer_done, must
* also be provided by the user application:
* \code
* static void dma_transfer_done(enum dma_channel_status status)
* {
* // ...
* }
* \endcode
*
* \subsection dma_use_case_1_setup_code Example code
* Add to application C-file:
* \code
* #define DMA_CHANNEL 0
* #define DMA_BUFFER_SIZE 1024
*
* static uint8_t source[DMA_BUFFER_SIZE];
* static uint8_t destination[DMA_BUFFER_SIZE];
*
* static void dma_init(void)
* {
* struct dma_channel_config dmach_conf;
* memset(&dmach_conf, 0, sizeof(dmach_conf));
*
* dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_1BYTE_gc);
* dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
*
* dma_channel_set_src_reload_mode(&dmach_conf,
* DMA_CH_SRCRELOAD_TRANSACTION_gc);
* dma_channel_set_dest_reload_mode(&dmach_conf,
* DMA_CH_DESTRELOAD_TRANSACTION_gc);
*
* dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
* dma_channel_set_source_address(&dmach_conf,
* (uint16_t)(uintptr_t)source);
*
* dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_INC_gc);
* dma_channel_set_destination_address(&dmach_conf,
* (uint16_t)(uintptr_t)destination);
*
* dma_enable();
*
* dma_set_callback(DMA_CHANNEL, dma_transfer_done);
* dma_channel_set_interrupt_level(&dmach_conf, DMA_INT_LVL_LO);
*
* dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
* dma_channel_enable(DMA_CHANNEL);
* }
* \endcode
*
* Add to \c main():
* \code
* sysclk_init();
* pmic_init();
* sleepmgr_init();
* dma_init();
* cpu_irq_enable();
* \endcode
*
* \subsection dma_use_case_1_setup_flow Workflow
* -# Define the DMA channel that will be used for the transfer for convenience:
* - \code #define DMA_CHANNEL 0 \endcode
* -# Define the array length that will be the used for the source and
* destination buffers located in RAM:
* - \code #define DMA_BUFFER_SIZE 1024 \endcode
* -# Create a pair of global arrays that will hold the source and destination
* data copied by the DMA controller channel when it is triggered:
* - \code
* static uint8_t source[DMA_BUFFER_SIZE];
* static uint8_t destination[DMA_BUFFER_SIZE];
* \endcode
* -# Create a function \c dma_init() to intialize the DMA:
* - \code
* static void dma_init(void)
* {
* // ...
* }
* \endcode
* -# Create config struct for DMA channel:
* - \code struct dma_channel_config dmach_conf; \endcode
* -# Make sure the configuration structure is zeroed out to ensure that all
* values are reset to their defaults before writing new values:
* - \code memset(&dmach_conf, 0, sizeof(dmach_conf)); \endcode
* -# Configure the DMA channel for single byte bursts, with a transfer length
* equal to the size of the source and destination buffers:
* - \code
* dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_1BYTE_gc);
* dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
* \endcode
* -# Configure the DMA channel to reset the source and destination addresses at
* the end of the complete transaction (i.e. after \c DMA_BUFFER_SIZE bytes
* copied):
* - \code
* dma_channel_set_src_reload_mode(&dmach_conf, DMA_CH_SRCRELOAD_TRANSACTION_gc);
* dma_channel_set_dest_reload_mode(&dmach_conf, DMA_CH_DESTRELOAD_TRANSACTION_gc);
* \endcode
* -# Configure the DMA channel to increment the source and destination
* addresses after each byte transferred:
* - \code
* dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
* dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_INC_gc);
* \endcode
* -# Configure the DMA channel source and destination addresses:
* - \code
* dma_channel_set_source_address(&dmach_conf, (uint16_t)(uintptr_t)source);
* dma_channel_set_destination_address(&dmach_conf,
* (uint16_t)(uintptr_t)destination);
* \endcode
* -# Enable the DMA module so that channels can be configured in it:
* - \code dma_enable(); \endcode
* \attention Calling dma_enable() will result in a soft-reset of the entire
* DMA module, clearing all channel configurations. If more than one
* DMA channel is to be configured, this function should be called
* only once in the application initialization procedure only.
* -# Set up the DMA channel interrupt to run at low interrupt priority, and
* link it to the user created \c dma_transfer_done() function:
* - \code
* dma_set_callback(DMA_CHANNEL, dma_transfer_done);
* dma_channel_set_interrupt_level(&dmach_conf, DMA_INT_LVL_LO);
* \endcode
* -# Write the DMA channel configuration to the DMA and enable it so that
* it can be triggered to start the transfer:
* - \code
* dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
* dma_channel_enable(DMA_CHANNEL);
* \endcode
* -# Initialize the clock system, PMIC driver and Sleep Manager service:
* - \code
* sysclk_init();
* pmic_init();
* sleepmgr_init();
* \endcode
* -# Call our DMA init function:
* - \code dma_init(); \endcode
* -# Enable global processing of interrupts:
* - \code cpu_irq_enable(); \endcode
*
* \section dma_use_case_1_usage Usage steps
*
* \subsection dma_use_case_1_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* dma_channel_trigger_block_transfer(DMA_CHANNEL);
* sleepmgr_enter_sleep();
* \endcode
*
* \subsection dma_use_case_1_usage_flow Workflow
* -# Start the DMA transfer:
* - \code dma_channel_trigger_block_transfer(DMA_CHANNEL); \endcode
* -# Sleep while waiting for the transfer to complete:
* - \code sleepmgr_enter_sleep(); \endcode
*/
/**
* \page dma_use_case_2 Use case #2 - Event driven DMA transfer from a peripheral.
*
* This use case shows how to set up a burst DMA transfer between a peripheral
* register set and the main system memory.
*
* In this use case, the DMA is configured for:
* - Burst length: 2 bytes (one 16-bit result from the ADC peripheral)
* - Transfer count: 1024 (512 16-bit samples)
* - Source: ADC channel 0 result register
* - Destination: Buffer located in RAM
* - Source address reload mode: End of burst
* - Destination address reload mode: End of transaction
* - Source and destination address direction mode: Increment
*
* In this use case data is copied from the 16-bit ADC channel 0 result register
* to a buffer in RAM, each time the ADC indicates that a new conversion has
* completed.
*
* \section dma_use_case_2_setup Setup steps
*
* \subsection dma_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref sysclk_group "System Clock Manager Service (sysclk)"
*
* The ADC must be configured according to the XMEGA ADC driver Quick Start
* \ref adc_basic_use_case "basic use case".
*
* \subsection dma_use_case_2_setup_code Example code
* Add to application C-file:
* \code
* #define DMA_CHANNEL 0
* #define DMA_BUFFER_SIZE 1024
*
* static uint16_t adc_samples[DMA_BUFFER_SIZE / 2];
*
* static void dma_init(void)
* {
* struct dma_channel_config dmach_conf;
* memset(&dmach_conf, 0, sizeof(dmach_conf));
*
* dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_2BYTE_gc);
* dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
*
* dma_channel_set_src_reload_mode(&dmach_conf,
* DMA_CH_SRCRELOAD_BURST_gc);
* dma_channel_set_dest_reload_mode(&dmach_conf,
* DMA_CH_DESTRELOAD_TRANSACTION_gc);
*
* dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
* dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_INC_gc);
*
* dma_channel_set_source_address(&dmach_conf,
* (uint16_t)(uintptr_t)&ADCA.CH0RES);
* dma_channel_set_destination_address(&dmach_conf,
* (uint16_t)(uintptr_t)adc_samples);
*
* dma_channel_set_trigger_source(&dmach_conf, DMA_CH_TRIGSRC_ADCA_CH0_gc);
* dma_channel_set_single_shot(&dmach_conf);
*
* dma_enable();
*
* dma_set_callback(DMA_CHANNEL, dma_transfer_done);
* dma_channel_set_interrupt_level(&dmach_conf, DMA_INT_LVL_LO);
*
* dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
* dma_channel_enable(DMA_CHANNEL);
* }
* \endcode
*
* Add to \c main():
* \code
* sysclk_init();
* dma_init();
* \endcode
*
* \subsection dma_use_case_2_setup_flow Workflow
* -# Define the DMA channel that will be used for the transfer for convenience:
* - \code #define DMA_CHANNEL 0 \endcode
* -# Define the array length that will be the used for the source and
* destination buffers located in RAM:
* - \code #define DMA_BUFFER_SIZE 1024 \endcode
* -# Create a global array that will hold the ADC sample result data copied by
* the DMA controller channel when it is triggered (the buffer size is
* halved as each sample is two bytes long):
* - \code static uint16_t adc_samples[DMA_BUFFER_SIZE / 2]; \endcode
* -# Create a function \c dma_init() to intialize the DMA:
* - \code
* static void dma_init(void)
* {
* // ...
* }
* \endcode
* -# Create config struct for DMA channel:
* - \code struct dma_channel_config dmach_conf; \endcode
* -# Make sure the configuration structure is zeroed out to ensure that all
* values are reset to their defaults before writing new values:
* - \code memset(&dmach_conf, 0, sizeof(dmach_conf)); \endcode
* -# Configure the DMA channel for two byte bursts (the size of a single ADC
* conversion) with a transfer length equal to the size of the destination
* buffer:
* - \code
* dma_channel_set_burst_length(&dmach_conf, DMA_CH_BURSTLEN_2BYTE_gc);
* dma_channel_set_transfer_count(&dmach_conf, DMA_BUFFER_SIZE);
* \endcode
* -# Configure the DMA channel to reset the source address at the end of each
* burst transfer, and the destination addresses at the end of the complete
* transaction (i.e. after \c DMA_BUFFER_SIZE bytes copied):
* - \code
* dma_channel_set_src_reload_mode(&dmach_conf, DMA_CH_SRCRELOAD_BURST_gc);
* dma_channel_set_dest_reload_mode(&dmach_conf, DMA_CH_DESTRELOAD_TRANSACTION_gc);
* \endcode
* -# Configure the DMA channel to increment the source and destination
* addresses after each byte transferred:
* - \code
* dma_channel_set_src_dir_mode(&dmach_conf, DMA_CH_SRCDIR_INC_gc);
* dma_channel_set_dest_dir_mode(&dmach_conf, DMA_CH_DESTDIR_INC_gc);
* \endcode
* -# Configure the DMA channel source and destination addresses to the ADC
* module channel 0 result registers and RAM buffer respectively:
* - \code
* dma_channel_set_source_address(&dmach_conf,
* (uint16_t)(uintptr_t)&ADCA.CH0RES);
* dma_channel_set_destination_address(&dmach_conf,
* (uint16_t)(uintptr_t)adc_samples);
* \endcode
* -# Set the DMA channel trigger source to the ADC module channel 0 complete
* event:
* - \code dma_channel_set_trigger_source(&dmach_conf, DMA_CH_TRIGSRC_ADCA_CH0_gc); \endcode
* -# Configure the DMA channel in single shot mode, so that each time it is
* triggered it will perform one bust transfer only:
* - \code dma_channel_set_single_shot(&dmach_conf); \endcode
* -# Enable the DMA module so that channels can be configured in it:
* - \code dma_enable(); \endcode
* \attention Calling dma_enable() will result in a soft-reset of the entire
* DMA module, clearing all channel configurations. If more than one
* DMA channel is to be configured, this function should be called
* only once in the application initialization procedure only.
* -# Set up the DMA channel interrupt to run at low interrupt priority, and
* link it to the user created \c dma_transfer_done() function:
* - \code
* dma_set_callback(DMA_CHANNEL, dma_transfer_done);
* dma_channel_set_interrupt_level(&dmach_conf, DMA_INT_LVL_LO);
* \endcode
* -# Write the DMA channel configuration to the DMA and enable it so that
* it can be triggered to start the transfer:
* - \code
* dma_channel_write_config(DMA_CHANNEL, &dmach_conf);
* dma_channel_enable(DMA_CHANNEL);
* \endcode
* -# Initialize the clock system:
* - \code sysclk_init(); \endcode
* -# Call our DMA init function:
* - \code dma_init(); \endcode
*
* \section dma_use_case_2_usage Usage steps
*
* \subsection dma_use_case_2_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* adc_start_conversion(&ADCA, ADC_CH0);
* adc_wait_for_interrupt_flag(&ADCA, ADC_CH0);
* \endcode
*
* \subsection dma_use_case_2_usage_flow Workflow
* -# Start an ADC conversion, result will be automatically copied to the
* global buffer when complete:
* - \code adc_start_conversion(&ADCA, ADC_CH0); \endcode
* -# Wait for the ADC to complete before triggering the next conversion by
* polling the ADC channel 0 complete interrupt flag:
* - \code adc_wait_for_interrupt_flag(&ADCA, ADC_CH0); \endcode
*/
#endif /* DRIVERS_DMA_DMA_H */
dstat-firmware-master/src/asf/xmega/drivers/nvm/ 0000775 0000000 0000000 00000000000 13317465730 0022230 5 ustar 00root root 0000000 0000000 dstat-firmware-master/src/asf/xmega/drivers/nvm/nvm.c 0000664 0000000 0000000 00000051132 13317465730 0023176 0 ustar 00root root 0000000 0000000 /**
* \file
*
* \brief Non Volatile Memory controller driver
*
* Copyright (C) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "compiler.h"
#include "ccp.h"
#include "nvm.h"
#include
/**
* \weakgroup nvm_signature_group
* @{
*/
/**
* \brief Read the device serial
*
* This function returns the device serial stored in the device.
*
* \note This function is modifying the NVM.CMD register.
* If the application are using program space access in interrupts
* (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts
* needs to be disabled when running EEPROM access functions. If not
* the program space reads will be corrupted.
*
* \retval storage Pointer to the structure where to store the device serial
*/
void nvm_read_device_serial(struct nvm_device_serial *storage)
{
storage->lotnum0 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(LOTNUM0));
storage->lotnum1 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(LOTNUM1));
storage->lotnum2 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(LOTNUM2));
storage->lotnum3 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(LOTNUM3));
storage->lotnum4 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(LOTNUM4));
storage->lotnum5 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(LOTNUM5));
storage->wafnum = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(WAFNUM));
storage->coordx0 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(COORDX0));
storage->coordx1 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(COORDX1));
storage->coordy0 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(COORDY0));
storage->coordy1 = nvm_read_production_signature_row(
nvm_get_production_signature_row_offset(COORDY1));
}
//! @}
/**
* \weakgroup nvm_eeprom_group
* @{
*/
/**
* \brief Read one byte from EEPROM using IO mapping.
*
* This function reads one byte from EEPROM using IO-mapped access.
* If memory mapped EEPROM is enabled, this function will not work.
*
* \param addr EEPROM address, between 0 and EEPROM_SIZE
*
* \return Byte value read from EEPROM.
*/
uint8_t nvm_eeprom_read_byte(eeprom_addr_t addr)
{
Assert(addr <= EEPROM_SIZE);
/* Wait until NVM is ready */
nvm_wait_until_ready();
/* Set address to read from */
NVM.ADDR2 = 0x00;
NVM.ADDR1 = (addr >> 8) & 0xFF;
NVM.ADDR0 = addr & 0xFF;
/* Issue EEPROM Read command */
nvm_issue_command(NVM_CMD_READ_EEPROM_gc);
return NVM.DATA0;
}
/**
* \brief Read buffer within the eeprom
*
* \param address the address to where to read
* \param buf pointer to the data
* \param len the number of bytes to read
*/
void nvm_eeprom_read_buffer(eeprom_addr_t address, void *buf, uint16_t len)
{
nvm_wait_until_ready();
eeprom_enable_mapping();
memcpy( buf,(void*)(address+MAPPED_EEPROM_START), len );
eeprom_disable_mapping();
}
/**
* \brief Write one byte to EEPROM using IO mapping.
*
* This function writes one byte to EEPROM using IO-mapped access.
* If memory mapped EEPROM is enabled, this function will not work.
* This function will cancel all ongoing EEPROM page buffer loading
* operations, if any.
*
* \param address EEPROM address (max EEPROM_SIZE)
* \param value Byte value to write to EEPROM.
*/
void nvm_eeprom_write_byte(eeprom_addr_t address, uint8_t value)
{
uint8_t old_cmd;
/* Flush buffer to make sure no unintentional data is written and load
* the "Page Load" command into the command register.
*/
old_cmd = NVM.CMD;
nvm_eeprom_flush_buffer();
// Wait until NVM is ready
nvm_wait_until_ready();
NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
Assert(address <= EEPROM_SIZE);
// Set address to write to
NVM.ADDR2 = 0x00;
NVM.ADDR1 = (address >> 8) & 0xFF;
NVM.ADDR0 = address & 0xFF;
// Load data to write, which triggers the loading of EEPROM page buffer
NVM.DATA0 = value;
/* Issue EEPROM Atomic Write (Erase&Write) command. Load command, write
* the protection signature and execute command.
*/
NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc;
nvm_exec();
NVM.CMD = old_cmd;
}
/**
* \brief Write buffer within the eeprom
*
* \param address the address to where to write
* \param buf pointer to the data
* \param len the number of bytes to write
*/
void nvm_eeprom_erase_and_write_buffer(eeprom_addr_t address, const void *buf, uint16_t len)
{
while (len) {
if (((address%EEPROM_PAGE_SIZE)==0) && (len>=EEPROM_PAGE_SIZE)) {
// A full page can be written
nvm_eeprom_load_page_to_buffer((uint8_t*)buf);
nvm_eeprom_atomic_write_page(address/EEPROM_PAGE_SIZE);
address += EEPROM_PAGE_SIZE;
buf = (uint8_t*)buf + EEPROM_PAGE_SIZE;
len -= EEPROM_PAGE_SIZE;
} else {
nvm_eeprom_write_byte(address++, *(uint8_t*)buf);
buf = (uint8_t*)buf + 1;
len--;
}
}
}
/**
* \brief Flush temporary EEPROM page buffer.
*
* This function flushes the EEPROM page buffers. This function will cancel
* any ongoing EEPROM page buffer loading operations, if any.
* This function also works for memory mapped EEPROM access.
*
* \note An EEPROM write operations will automatically flush the buffer for you.
* \note The function does not preserve the value of the NVM.CMD register
*/
void nvm_eeprom_flush_buffer(void)
{
// Wait until NVM is ready
nvm_wait_until_ready();
// Flush EEPROM page buffer if necessary
if ((NVM.STATUS & NVM_EELOAD_bm) != 0) {
NVM.CMD = NVM_CMD_ERASE_EEPROM_BUFFER_gc;
nvm_exec();
}
}
/**
* \brief Load single byte into temporary page buffer.
*
* This function loads one byte into the temporary EEPROM page buffers.
* If memory mapped EEPROM is enabled, this function will not work.
* Make sure that the buffer is flushed before starting to load bytes.
* Also, if multiple bytes are loaded into the same location, they will
* be ANDed together, thus 0x55 and 0xAA will result in 0x00 in the buffer.
*
* \note Only one page buffer exist, thus only one page can be loaded with
* data and programmed into one page. If data needs to be written to
* different pages, the loading and writing needs to be repeated.
*
* \param byte_addr EEPROM Byte address, between 0 and EEPROM_PAGE_SIZE.
* \param value Byte value to write to buffer.
*/
void nvm_eeprom_load_byte_to_buffer(uint8_t byte_addr, uint8_t value)
{
uint8_t old_cmd;
old_cmd = NVM.CMD;
// Wait until NVM is ready
nvm_wait_until_ready();
NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
// Set address
NVM.ADDR2 = 0x00;
NVM.ADDR1 = 0x00;
NVM.ADDR0 = byte_addr & 0xFF;
// Set data, which triggers loading of EEPROM page buffer
NVM.DATA0 = value;
NVM.CMD = old_cmd;
}
/**
* \brief Load entire page into temporary EEPROM page buffer.
*
* This function loads an entire EEPROM page from an SRAM buffer to
* the EEPROM page buffers. If memory mapped EEPROM is enabled, this
* function will not work. Make sure that the buffer is flushed before
* starting to load bytes.
*
* \note Only the lower part of the address is used to address the buffer.
* Therefore, no address parameter is needed. In the end, the data
* is written to the EEPROM page given by the address parameter to the
* EEPROM write page operation.
*
* \param values Pointer to SRAM buffer containing an entire page.
*/
void nvm_eeprom_load_page_to_buffer(const uint8_t *values)
{
uint8_t old_cmd;
old_cmd = NVM.CMD;
// Wait until NVM is ready
nvm_wait_until_ready();
NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
/* Set address to zero, as only the lower bits matters. ADDR0 is
* maintained inside the loop below.
*/
NVM.ADDR2 = 0x00;
NVM.ADDR1 = 0x00;
// Load multiple bytes into page buffer
uint8_t i;
for (i = 0; i < EEPROM_PAGE_SIZE; ++i) {
NVM.ADDR0 = i;
NVM.DATA0 = *values;
++values;
}
NVM.CMD = old_cmd;
}
/**
* \brief Erase and write bytes from page buffer into EEPROM.
*
* This function writes the contents of an already loaded EEPROM page
* buffer into EEPROM memory.
*
* As this is an atomic write, the page in EEPROM will be erased
* automatically before writing. Note that only the page buffer locations
* that have been loaded will be used when writing to EEPROM. Page buffer
* locations that have not been loaded will be left untouched in EEPROM.
*
* \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE
*/
void nvm_eeprom_atomic_write_page(uint8_t page_addr)
{
// Wait until NVM is ready
nvm_wait_until_ready();
// Calculate page address
uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE);
Assert(address <= EEPROM_SIZE);
// Set address
NVM.ADDR2 = 0x00;
NVM.ADDR1 = (address >> 8) & 0xFF;
NVM.ADDR0 = address & 0xFF;
// Issue EEPROM Atomic Write (Erase&Write) command
nvm_issue_command(NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc);
}
/**
* \brief Write (without erasing) EEPROM page.
*
* This function writes the contents of an already loaded EEPROM page
* buffer into EEPROM memory.
*
* As this is a split write, the page in EEPROM will _not_ be erased
* before writing.
*
* \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE
*/
void nvm_eeprom_split_write_page(uint8_t page_addr)
{
// Wait until NVM is ready
nvm_wait_until_ready();
// Calculate page address
uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE);
Assert(address <= EEPROM_SIZE);
// Set address
NVM.ADDR2 = 0x00;
NVM.ADDR1 = (address >> 8) & 0xFF;
NVM.ADDR0 = address & 0xFF;
// Issue EEPROM Split Write command
nvm_issue_command(NVM_CMD_WRITE_EEPROM_PAGE_gc);
}
/**
* \brief Fill temporary EEPROM page buffer with value.
*
* This fills the the EEPROM page buffers with a given value.
* If memory mapped EEPROM is enabled, this function will not work.
*
* \note Only the lower part of the address is used to address the buffer.
* Therefore, no address parameter is needed. In the end, the data
* is written to the EEPROM page given by the address parameter to the
* EEPROM write page operation.
*
* \param value Value to copy to the page buffer.
*/
void nvm_eeprom_fill_buffer_with_value(uint8_t value)
{
uint8_t old_cmd;
old_cmd = NVM.CMD;
nvm_eeprom_flush_buffer();
// Wait until NVM is ready
nvm_wait_until_ready();
NVM.CMD = NVM_CMD_LOAD_EEPROM_BUFFER_gc;
/* Set address to zero, as only the lower bits matters. ADDR0 is
* maintained inside the loop below.
*/
NVM.ADDR2 = 0x00;
NVM.ADDR1 = 0x00;
// Load multiple bytes into page buffer
uint8_t i;
for (i = 0; i < EEPROM_PAGE_SIZE; ++i) {
NVM.ADDR0 = i;
NVM.DATA0 = value;
}
NVM.CMD = old_cmd;
}
/**
* \brief Erase bytes from EEPROM page.
*
* This function erases bytes from one EEPROM page, so that every location
* written to in the page buffer reads 0xFF.
*
* \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE
*/
void nvm_eeprom_erase_bytes_in_page(uint8_t page_addr)
{
// Wait until NVM is ready
nvm_wait_until_ready();
// Calculate page address
uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE);
Assert(address <= EEPROM_SIZE);
// Set address
NVM.ADDR2 = 0x00;
NVM.ADDR1 = (address >> 8) & 0xFF;
NVM.ADDR0 = address & 0xFF;
// Issue EEPROM Erase command
nvm_issue_command(NVM_CMD_ERASE_EEPROM_PAGE_gc);
}
/**
* \brief Erase EEPROM page.
*
* This function erases one EEPROM page, so that every location reads 0xFF.
*
* \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE
*/
void nvm_eeprom_erase_page(uint8_t page_addr)
{
// Mark all addresses to be deleted
nvm_eeprom_fill_buffer_with_value(0xff);
// Erase bytes
nvm_eeprom_erase_bytes_in_page(page_addr);
}
/**
* \brief Erase bytes from all EEPROM pages.
*
* This function erases bytes from all EEPROM pages, so that every location
* written to in the page buffer reads 0xFF.
*/
void nvm_eeprom_erase_bytes_in_all_pages(void)
{
// Wait until NVM is ready
nvm_wait_until_ready();
// Issue EEPROM Erase All command
nvm_issue_command(NVM_CMD_ERASE_EEPROM_gc);
}
/**
* \brief Erase entire EEPROM memory.
*
* This function erases the entire EEPROM memory block to 0xFF.
*/
void nvm_eeprom_erase_all(void)
{
// Mark all addresses to be deleted
nvm_eeprom_fill_buffer_with_value(0xff);
// Erase all pages
nvm_eeprom_erase_bytes_in_all_pages();
}
//! @}
//! @}
/**
* \weakgroup nvm_flash_group
* @{
*/
/**
* \brief Issue flash range CRC command
*
* This function sets the FLASH range CRC command in the NVM.CMD register.
* It then loads the start and end byte address of the part of FLASH to
* generate a CRC-32 for into the ADDR and DATA registers and finally performs
* the execute command.
*
* \note Should only be called from the CRC module. The function saves and
* restores the NVM.CMD register, but if this
* function is called from an interrupt, interrupts must be disabled
* before this function is called.
*
* \param start_addr end byte address
* \param end_addr start byte address
*/
void nvm_issue_flash_range_crc(flash_addr_t start_addr, flash_addr_t end_addr)
{
uint8_t old_cmd;
// Save current nvm command
old_cmd = NVM.CMD;
// Load the NVM CMD register with the Flash Range CRC command
NVM.CMD = NVM_CMD_FLASH_RANGE_CRC_gc;
// Load the start byte address in the NVM Address Register
NVM.ADDR0 = start_addr & 0xFF;
NVM.ADDR1 = (start_addr >> 8) & 0xFF;
#if (FLASH_SIZE >= 0x10000UL)
NVM.ADDR2 = (start_addr >> 16) & 0xFF;
#endif
// Load the end byte address in NVM Data Register
NVM.DATA0 = end_addr & 0xFF;
NVM.DATA1 = (end_addr >> 8) & 0xFF;
#if (FLASH_SIZE >= 0x10000UL)
NVM.DATA2 = (end_addr >> 16) & 0xFF;
#endif
// Execute command
ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm);
// Restore command register
NVM.CMD = old_cmd;
}
/**
* \brief Read buffer within the application section
*
* \param address the address to where to read
* \param buf pointer to the data
* \param len the number of bytes to read
*/
void nvm_flash_read_buffer(flash_addr_t address, void *buf, uint16_t len)
{
#if (FLASH_SIZE>0x10000)
uint32_t opt_address = address;
#else
uint16_t opt_address = (uint16_t)address;
#endif
nvm_wait_until_ready();
while ( len ) {
*(uint8_t*)buf = nvm_flash_read_byte(opt_address);
buf=(uint8_t*)buf+1;
opt_address++;
len--;
}
}
/**
* \brief Read buffer within the user section
*
* \param address the address to where to read
* \param buf pointer to the data
* \param len the number of bytes to read
*/
void nvm_user_sig_read_buffer(flash_addr_t address, void *buf, uint16_t len)
{
uint16_t opt_address = (uint16_t)address&(FLASH_PAGE_SIZE-1);
while ( len ) {
*(uint8_t*)buf = nvm_read_user_signature_row(opt_address);
buf=(uint8_t*)buf+1;
opt_address++;
len--;
}
}
/**
* \brief Write specific parts of user flash section
*
* \param address the address to where to write
* \param buf pointer to the data
* \param len the number of bytes to write
* \param b_blank_check if True then the page flash is checked before write
* to run or not the erase page command.
*
* Set b_blank_check to false if all application flash is erased before.
*/
void nvm_user_sig_write_buffer(flash_addr_t address, const void *buf,
uint16_t len, bool b_blank_check)
{
uint16_t w_value;
uint16_t page_pos;
uint16_t opt_address = (uint16_t)address;
bool b_flag_erase = false;
while ( len ) {
for (page_pos=0; page_pos0x10000)
uint32_t page_address;
uint32_t opt_address = address;
#else
uint16_t page_address;
uint16_t opt_address = (uint16_t)address;
#endif
// Compute the start of the page to be modified
page_address = opt_address-(opt_address%FLASH_PAGE_SIZE);
// For each page
while ( len ) {
b_flag_erase = false;
nvm_wait_until_ready();
for (page_pos=0; page_pos